File "php_cli_finder.php"
Full path: /home/bud/public_html/swamp/wp-admin/wp-content/plugins/backup-backup/includes/cli/php_cli_finder.php
File size: 8.09 KB
MIME-type: text/x-php
Charset: utf-8
<?php
// Namespace
namespace BMI\Plugin\PHPCLI;
// Use
use BMI\Plugin\Backup_Migration_Plugin as BMP;
// Exit on direct access
if (!defined('ABSPATH')) exit;
/**
* Scans for PHP CLI executable and makes sure exec is working
*/
class Checker {
/**
* Points if the exec is disabled or not
*/
public $ini_disabled = true;
/**
* __construct - Unused construct function
*
* @return {self}
*/
function __construct() {}
/**
* findPHP - Scans the system to find executable PHP
*
* @return {bool/array} false on fail, array on success
* $final_executable = [
* 'version' => $php_cli_version,
* 'brand' => $php_brand,
* 'memory' => $php_cli_memory . '/' . $php_cli_memory_modified,
* 'max_exec' => $php_cli_max_exec . '/' . $php_cli_max_exec_modified,
* 'executable' => $executable_path_to_file
* ];
*/
public function findPHP() {
// Return false if exec is disabled
if ($this->isExecEnabled() === false) return false;
// Check if user defined own PHP CLI
$user_defined = false;
if (defined('BMI_CLI_EXECUTABLE')) {
if (file_exists(BMI_CLI_EXECUTABLE)) {
$user_defined = true;
}
}
if ($user_defined === false) {
// Makes variable for system paths list
$system_paths = null;
// Exec command which displays all paths per line
@exec('(sed "s/:/\n/g" <<< $PATH) 2>&1', $system_paths);
// Concat output
$system_paths = implode("\n", $system_paths);
// Check if the output is not empty, if empty abort
if (empty($system_paths) || !$system_paths) return false;
// Make variable for executables that contains php keyword
$executables = ['php'];
// Make variable for "for" loop
$system_paths = explode("\n", $system_paths);
// Loop all paths and check for PHP executables
for ($i = 0; $i < sizeof($system_paths); ++$i) {
// Variable for scan output
$executables_scan = null;
// Trim the path just in case
$path = trim($system_paths[$i]);
// If path is empty ignore and continue
if (empty($path)) continue;
// Exec command which will display PHP (in name) executables
@exec('(for i in $(ls ' . $path . ' | grep "php"); do [ -x ' . $path . '/$i ] && echo ' . $path . '/$i || echo ""; done;) 2>&1', $executables_scan);
// Implode the output
$executables_scan = implode("\n", $executables_scan);
// Merge the array with other results
$executables = array_merge($executables, explode("\n", $executables_scan));
}
}
// Make variable for real PHP executables
$php_executables = [];
// If used defined own PHP CLI use it
if ($user_defined === true) $executables = [BMI_CLI_EXECUTABLE];
// Filter the array to exclude empty values and remove duplicates
$executables = array_filter(array_unique($executables));
// Make variable for final executable
$final_executable = false;
// Loop and test the executables
foreach ($executables as $exe) {
// If path+name does not contain php ignore and continue
if (strpos($exe, 'php') === false) continue;
// Make variable for CLI version in shell
$shell_version = null;
// Make variable for regex check
$output = null;
// Exec the command to check shell displayed version
@exec($exe . ' --version 2>&1', $shell_version);
// Implode the output
$shell_version = implode("\n", $shell_version);
// Test the output with regex to find PHP version and brand
preg_match('/PHP\ (.*)\ (.*)\ \(built: (.*)\)/i', $shell_version, $output);
// Check if the output is not empty and contains at least 4 results
if ($output && !empty($output) && !empty($output[1]) && sizeof($output) >= 4) {
// Remove additional characters from the version leave only numbers with dots
$php = preg_replace("/[^0-9.]/", "", $output[1]);
// Save the brand in the $brand variable
$brand = $output[2];
// Make variable for file version test
$file_version = null;
// Make variable for shell inline PHP version test
$inline_version = null;
// Exec the shell inline test for version
@exec($exe . ' -r "echo phpversion();" 2>&1', $inline_version);
// Implode the version
$inline_version = implode("\n", $inline_version);
// Check if the version match required minimum
if (version_compare($inline_version, '5.6', '>=')) {
// Path to CLI check file
$path_to_cli = BMI_INCLUDES . '/cli/version_check.php';
// Exec the file check if it can run files
@exec($exe . ' -f ' . $path_to_cli . ' 2>&1', $file_version);
// Check if the output is correct
if ($file_version && is_array($file_version) && !empty($file_version) && sizeof($file_version) >= 5) {
// The results from file saved to named variables
$php_cli_version = $file_version[0];
$php_cli_memory = $file_version[1];
$php_cli_max_exec = $file_version[2];
$php_cli_memory_modified = $file_version[3];
$php_cli_max_exec_modified = $file_version[4];
// Check if the version match the inline one (it's the same php.ini)
if (trim($php_cli_version) == trim($inline_version)) {
// If it match use this PHP CLI module
$final_executable = [
'brand' => $brand,
'version' => $php_cli_version,
'memory' => $php_cli_memory . '/' . $php_cli_memory_modified,
'max_exec' => $php_cli_max_exec . '/' . $php_cli_max_exec_modified,
'executable' => $exe
];
break;
}
}
}
}
}
// Return the final result
return $final_executable;
}
/**
* isExecAvailable - Check if exec is not blocked by php.ini
*
* @return {bool} true on success / false on fail
*/
public function isExecAvailable() {
// Get disabled functions
$disabled_functions = @ini_get('disable_functions');
// Turn disabled functions to array
$disabled_functions = explode(',', $disabled_functions);
// Check if everything is allowed
if (empty($disabled_functions)) {
// Check if function is callable and not disabled (PHP 8 check)
if (function_exists('shell_exec') && is_callable('shell_exec')) return true;
else return false;
}
// Few checks
if (!is_array($disabled_functions)) return false;
elseif (in_array('shell_exec', $disabled_functions)) return false;
elseif (in_array('exec', $disabled_functions)) return false;
elseif (in_array('system', $disabled_functions)) return false;
else {
// Check if function is callable and not disabled (PHP 8 check)
if (function_exists('shell_exec') && is_callable('shell_exec')) return true;
else return false;
}
}
/**
* isExecEnabled - Checks if exec function is not disabled or blocked
*
* @return {bool} true on success / false on fail
*/
public function isExecEnabled() {
// Check if the function is not disabled in php.ini
if ($this->isExecAvailable()) {
// Mark as enabled in php_ini
$this->ini_disabled = false;
// Try to run simple shell
try {
// Output variable
$output = null;
// Execute the command
@exec('echo "It works!" 2>&1', $output);
// Implode the output just in case
$output = implode("\n", $output);
// Check if the output is as expected
if ($output === 'It works!') return true;
else return false;
// Catch errors in older PHP
} catch (\Error $e) {
return false;
// Catch exceptions if any
} catch (\Exception $e) {
return false;
// Catch throwable exception if any
} catch (\Throwable $e) {
return false;
}
// If the function is blocked do not even try and return false
} else {
// Mark as disabled in php_ini
$this->ini_disabled = true;
return false;
}
}
}