1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 01:39:24 +02:00
This commit is contained in:
Daniel Neto 2024-12-03 11:30:16 -03:00
parent 7f1d5e5a98
commit 5ce81cc9be
5 changed files with 146 additions and 85 deletions

View file

@ -487,9 +487,14 @@ function execFFMPEGAsyncOrRemote($command, $keyword = null)
$obj = AVideoPlugin::getDataObjectIfEnabled('API');
if(!empty($obj) && !empty($obj->standAloneFFMPEG)){
$url = "{$obj->standAloneFFMPEG}";
$codeToExec = array('ffmpegCommand'=>$command, 'keyword'=>$keyword, 'time'=>time());
$codeToExecEncrypted = encryptString(json_encode($codeToExec));
$url = addQueryStringParameter($url, 'APISecret', $obj->APISecret);
$url = addQueryStringParameter($url, 'ffmpegCommand', $command);
$url = addQueryStringParameter($url, 'keyword', $keyword);
$url = addQueryStringParameter($url, 'codeToExecEncrypted', $codeToExecEncrypted);
//var_dump($url);
_error_log("execFFMPEGAsyncOrRemote: URL $command");
_error_log("execFFMPEGAsyncOrRemote: URL $url");
return url_get_contents($url);

View file

@ -121,8 +121,11 @@ function getMySQLDate()
function _mysql_connect($persistent = false, $try = 0)
{
global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort, $mysql_connect_was_closed, $mysql_connect_is_persistent;
global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort, $mysql_connect_was_closed, $mysql_connect_is_persistent, $isStandAlone;
if(!empty($isStandAlone)){
_error_log('StandAlone Mode');
return false;
}
$checkValues = ['mysqlHost', 'mysqlUser', 'mysqlPass', 'mysqlDatabase'];
foreach ($checkValues as $value) {

View file

@ -2907,12 +2907,12 @@ class API extends PluginAbstract
}
/**
* @param array $parameters return true if the secret is valid and false if it is not
* return true if the secret is valid and false if it is not
* 'APISecret' mandatory for security reasons - required
* @example {webSiteRootURL}plugin/API/{getOrSet}.json.php?APIName={APIName}&APISecret={APISecret}
* @return \ApiObject Returns an ApiObject.
*/
public function get_api_isAPISecretValid($parameters)
public function get_api_isAPISecretValid()
{
global $global;
if (!self::isAPISecretValid()) {
@ -2921,6 +2921,17 @@ class API extends PluginAbstract
return new ApiObject("APISecret is valid", false);
}
}
/**
* decrypt a string
* 'string' mandatory
* @example {webSiteRootURL}plugin/API/{getOrSet}.json.php?APIName={APIName}&string=stringEncryptedToDecrypt
* @return \ApiObject Returns an ApiObject.
*/
public function get_api_decryptString()
{
return new ApiObject(decryptString($_REQUEST['string']), false);
}
}
class ApiObject

View file

@ -87,98 +87,140 @@
* Replace `https://yourSite.com/` with your actual website URL.
*/
$global_timeLimit = 300;
ini_set("memory_limit", -1);
ini_set('default_socket_timeout', $global_timeLimit);
set_time_limit($global_timeLimit);
ini_set('max_execution_time', $global_timeLimit);
ini_set("memory_limit", "-1");
header('Content-Type: application/json');
require_once __DIR__ . "/../../../objects/functionsStandAlone.php";
if (empty($streamerURL)) {
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']);
exit;
}
// Function to safely get inputs from either command line or request
function getInput($key, $default = '') {
global $argv;
// Check if running from command line or HTTP request
if (php_sapi_name() === 'cli') {
// Look for the parameter in $argv (command line)
foreach ($argv as $arg) {
if (strpos($arg, "{$key}=") === 0) {
return substr($arg, strlen("{$key}="));
}
}
} else {
// Fallback to HTTP request ($_REQUEST)
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}
return $default;
}
// Validate and sanitize the ffmpegCommand
function sanitizeFFmpegCommand($command) {
// Allowable ffmpeg prefixes
ini_set("memory_limit", -1);
ini_set('default_socket_timeout', $global_timeLimit);
set_time_limit($global_timeLimit);
ini_set('max_execution_time', $global_timeLimit);
ini_set("memory_limit", "-1");
header('Content-Type: application/json');
require_once __DIR__ . "/../../../objects/functionsStandAlone.php";
if (empty($streamerURL)) {
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']);
exit;
}
function _decryptString($string)
{
global $global;
$url = "{$global['webSiteRootURL']}plugin/API/get.json.php?APIName=decryptString&string={$string}";
$content = file_get_contents($url);
$json = json_decode($content);
if (!empty($json) && empty($json->error)) {
$json2 = json_decode($json->message);
if ($json2->time > strtotime('30 seconds ago')) {
return $json2;
}
}
//return $json2;
return false;
}
// Function to safely get inputs from either command line or request
function getInput($key, $default = '') {
global $argv;
// Check if running from command line or HTTP request
if (php_sapi_name() === 'cli') {
foreach ($argv as $arg) {
if (strpos($arg, "{$key}=") === 0) {
return substr($arg, strlen("{$key}="));
}
}
} else {
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}
return $default;
}
// Validate and sanitize the ffmpegCommand
function sanitizeFFmpegCommand($command) {
$allowedPrefixes = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg'];
// Remove dangerous characters
$command = str_replace('&&', '', $command);
$command = preg_replace('/[;|`<]/', '', $command);
// Remove existing log file redirection (e.g., '> /path/to/log 2>&1' or '> /path/to/log')
$command = preg_replace('/\s*>.*(?:2>&1)?/', '', $command);
$command = preg_replace('/[;|`<>]/', '', $command);
// Ensure it starts with ffmpeg
// Ensure it starts with an allowed prefix
foreach ($allowedPrefixes as $prefix) {
if (strpos(trim($command), $prefix) === 0) {
return $command;
}
}
// If it doesn't start with an allowed prefix, return an empty string
return '';
}
// Fetch and sanitize inputs
$ffmpegCommand = sanitizeFFmpegCommand(getInput('ffmpegCommand', ''));
$keyword = getInput('keyword', '');
// Fetch and sanitize inputs
$codeToExecEncrypted = getInput('codeToExecEncrypted', '');
$codeToExec = _decryptString($codeToExecEncrypted);
if (empty($codeToExec)) {
die('Invalid Request');
}
$ffmpegCommand = sanitizeFFmpegCommand($codeToExec->ffmpegCommand);
$keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword);
// Kill processes associated with the keyword
if (!empty($keyword)) {
killProcessFromKeyword($keyword);
}
// Validate that ffmpegCommand is not empty after sanitization
if (empty($ffmpegCommand)) {
echo json_encode([
'error' => true,
'msg' => 'Invalid or empty ffmpeg command',
]);
exit;
}
// Get the system's temporary directory
$tempDir = sys_get_temp_dir();
// Kill processes associated with the keyword
if (!empty($keyword)) {
killProcessFromKeyword($keyword);
}
// Ensure the temp directory ends with a directory separator
$tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
// Validate that ffmpegCommand is not empty after sanitization
if (empty($ffmpegCommand)) {
echo json_encode([
'error' => true,
'msg' => 'Invalid or empty ffmpeg command',
]);
exit;
}
// Create a unique log file path
$timestamp = date('YmdHis');
$logFile = "{$tempDir}ffmpeg_{$keyword}_{$timestamp}.log";
// Debug output (optional)
error_log("Constructed FFMPEG Command: $ffmpegCommand");
try {
$pid = execAsync($ffmpegCommand, $keyword);
echo json_encode([
'error' => false,
'msg' => 'Command executed',
'command' => $ffmpegCommand,
'pid' => $pid,
]);
} catch (Exception $e) {
echo json_encode([
'error' => true,
'msg' => 'Failed to execute command',
'errorMsg' => $e->getMessage(),
]);
}
exit;
// Redirect all output to the log file
$ffmpegCommand .= " > {$logFile} 2>&1";
// Debug output (optional)
error_log("Constructed FFMPEG Command: $ffmpegCommand");
try {
$pid = execAsync($ffmpegCommand, $keyword);
echo json_encode([
'error' => false,
'msg' => 'Command executed',
'command' => $ffmpegCommand,
'pid' => $pid,
'logFile' => $logFile,
]);
} catch (Exception $e) {
echo json_encode([
'error' => true,
'msg' => 'Failed to execute command',
'errorMsg' => $e->getMessage(),
'logFile' => $logFile,
]);
}
exit;

View file

@ -636,7 +636,7 @@ function startRestream($m3u8, $restreamsDestinations, $logFile, $robj, $tries =
file_put_contents($logFile, $command . PHP_EOL);
if (empty($isATest)) {
// use remote ffmpeg here
exec('nohup ' . $command . ' 2>> ' . $logFile . ' > /dev/null &');
execFFMPEGAsyncOrRemote($command . ' > ' . $logFile);
}
error_log("Restreamer.json.php startRestream finish");
}