From e40a5f241f399f4ba05c00d35d185e189b7ee678 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Wed, 20 Mar 2024 13:48:37 +0500 Subject: [PATCH 1/9] Fix. Cron. Cron file. Add a global sign to the variable by defaults. --- uniforce/data/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniforce/data/cron.php b/uniforce/data/cron.php index 1f8207c..36a0354 100644 --- a/uniforce/data/cron.php +++ b/uniforce/data/cron.php @@ -1,2 +1,2 @@ Date: Wed, 20 Mar 2024 16:11:49 +0500 Subject: [PATCH 2/9] New. Scanner. Automatic start in background implemented. --- uniforce/inc/admin.php | 1 + uniforce/inc/cron_functions.php | 6 +- uniforce/inc/scanner.php | 10 +++ .../lib/Cleantalk/USP/ScannerController.php | 19 +++-- uniforce/lib/Cleantalk/USP/Uniforce/Cron.php | 74 ++++++++++++++++++- 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/uniforce/inc/admin.php b/uniforce/inc/admin.php index 27351e3..980c61b 100644 --- a/uniforce/inc/admin.php +++ b/uniforce/inc/admin.php @@ -313,6 +313,7 @@ function usp_install_cron(){ Cron::addTask( 'clean_black_lists', 'uniforce_clean_black_lists', 86400 ); Cron::addTask( 'update_signatures', 'usp_scanner__get_signatures', 86400, time() + 10 ); Cron::addTask( 'check_for_updates', 'usp_get_latest_version', 86400, time() ); + Cron::addTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); } diff --git a/uniforce/inc/cron_functions.php b/uniforce/inc/cron_functions.php index 98133e6..6d86c91 100644 --- a/uniforce/inc/cron_functions.php +++ b/uniforce/inc/cron_functions.php @@ -138,13 +138,13 @@ function usp_scanner__launch(){ if ( $usp->scanner_status === false || ! $usp->settings->scanner_auto_start ) return true; - return Helper::http__request( - CT_USP_AJAX_URI, + return Helper::http__request( + CT_USP_URI, array( 'plugin_name' => 'security', 'spbc_remote_call_token' => md5($usp->settings->key), 'spbc_remote_call_action' => 'scanner__controller', - 'state' => 'get_hashes' + 'state' => 'create_db' ), 'get async' ); diff --git a/uniforce/inc/scanner.php b/uniforce/inc/scanner.php index 34ff51e..a612941 100644 --- a/uniforce/inc/scanner.php +++ b/uniforce/inc/scanner.php @@ -6,6 +6,7 @@ use Cleantalk\USP\Layout\ListTable; use Cleantalk\USP\Scanner\Scanner; use Cleantalk\USP\Uniforce\API; +use Cleantalk\USP\Uniforce\Cron; use Cleantalk\USP\Uniforce\Helper; use Cleantalk\USP\Variables\Post; @@ -412,6 +413,15 @@ function usp_scanner__display(){ return; } + $scanner_next_launch = Cron::getTaskNextCall('scanner_launch', 'Y-m-d H:i:s'); + if ($scanner_next_launch) { + echo '

'; + printf( + uniforce_translate('Next automatic scan is scheduled on: %s', 'security-malware-firewall'), + $scanner_next_launch + ); + echo '

'; + } // Info about last scanning echo '

'; diff --git a/uniforce/lib/Cleantalk/USP/ScannerController.php b/uniforce/lib/Cleantalk/USP/ScannerController.php index 9e08fe7..d06c251 100644 --- a/uniforce/lib/Cleantalk/USP/ScannerController.php +++ b/uniforce/lib/Cleantalk/USP/ScannerController.php @@ -2,6 +2,7 @@ namespace Cleantalk\USP; +use Cleantalk\USP\Uniforce\Cron; use Cleantalk\USP\Common\Err; use Cleantalk\USP\Common\State; use Cleantalk\USP\Common\Storage; @@ -73,8 +74,9 @@ function __construct( $root_dir, $db_params = null ){ 'signature_analysis', 'heuristic_analysis', 'auto_cure', - 'frontend_analysis', - 'outbound_links', + //'frontend_analysis', + //'outbound_links', + 'send_results' ); public function action__scanner__controller(){ @@ -131,7 +133,7 @@ public function action__scanner__controller(){ break; // Heuristic - case 'analysis_heuristic': + case 'heuristic_analysis': $result = $this->action__scanner__heuristic_analysis( $this->offset, @@ -141,6 +143,10 @@ public function action__scanner__controller(){ break; + case 'auto_cure': + $result['end'] = true; + break; + // Send result case 'send_results': @@ -162,7 +168,7 @@ public function action__scanner__controller(){ ); Helper::http__request( - CT_USP_AJAX_URI, + CT_USP_URI, $remote_call_params, 'get async' ); @@ -174,6 +180,8 @@ public function action__scanner__controller(){ ? $usp->error_delete( $this->state, 'and_save_data', 'cron_scan' ) : $usp->error_add( $this->state, $result, 'cron_scan' ); + Cron::updateTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); + return true; } @@ -701,8 +709,6 @@ public function action__scanner__heuristic_analysis( $offset = null, $amount = n $out['end'] = $out['processed'] < $amount; return $out; - - return $out; } private function scanner__db_update_ok_files($list_of_ok_hashes, $check_type) @@ -802,6 +808,7 @@ public function action__scanner__send_results( ) { $usp->data->save(); $result['end'] = 1; + return $result; } diff --git a/uniforce/lib/Cleantalk/USP/Uniforce/Cron.php b/uniforce/lib/Cleantalk/USP/Uniforce/Cron.php index 8d17969..65b74c8 100644 --- a/uniforce/lib/Cleantalk/USP/Uniforce/Cron.php +++ b/uniforce/lib/Cleantalk/USP/Uniforce/Cron.php @@ -12,6 +12,9 @@ class Cron extends \Cleantalk\USP\Common\Cron // Option name with cron data const CRON_FILE = CT_USP_CRON_FILE; + /** + * @return array|array[] + */ public static function getTasks(){ if( ! file_exists( self::CRON_FILE ) ){ file_put_contents( @@ -36,4 +39,73 @@ public static function saveTasks( $tasks ){ return ! Err::check(); } -} \ No newline at end of file + /** + * Get the task info array. + * @param string $task_name + * @return array|array[] + */ + public static function getTaskInfo($task_name) { + return isset(self::getTasks()[$task_name]) ? self::getTasks()[$task_name] : array(); + } + + /** + * Get the task next call. + * @param string $task_name + * @param string $format Date formatting. If set, will apply the format to the output date. If false, return string of timestamp. Default false. + * @return false|string If $format param is set return formatted string, timestamp string otherwise. False on errors. + */ + public static function getTaskNextCall($task_name, $format = false) { + $out = false; + $task_info = self::getTaskInfo($task_name); + if ( !empty($task_info) && !empty($task_info['next_call'])) { + if (is_string($format)) { + $out = date($format, $task_info['next_call']); + } else { + $out = (string)$task_info['next_call']; + } + } + return $out; + } + + // Updates cron task, create task if not exists + static public function updateTask($task, $handler, $period, $first_call = null, $params = array()){ + return static::removeTask($task) && + static::addTask($task, $handler, $period, $first_call, $params); + } + + static public function removeTask($task) + { + $tasks = self::getTasks(); + + if(!isset($tasks[$task])) + return true; + + unset($tasks[$task]); + + return static::saveTasks( $tasks ); + } + + static public function addTask($task, $handler, $period, $first_call = null, $params = array()) + { + // First call time() + preiod + $first_call = !$first_call ? time() + $period : $first_call; + + $tasks = static::getTasks(); + + if(isset($tasks[$task])) + return false; + + // Task entry + $tasks[$task] = array( + 'handler' => $handler, + 'next_call' => $first_call, + 'executed' => 0, + 'last_executed' => 0, + 'period' => $period, + 'params' => $params, + ); + + return static::saveTasks( $tasks ); + } + +} From 325226dabf83125b923122c4333130dc9f44f7f2 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Wed, 20 Mar 2024 16:13:39 +0500 Subject: [PATCH 3/9] Code. Tabs to spaces. --- uniforce/inc/cron_functions.php | 23 +- uniforce/lib/Cleantalk/USP/Common/Helper.php | 242 +++++++++--------- .../lib/Cleantalk/USP/Common/RemoteCalls.php | 16 +- 3 files changed, 141 insertions(+), 140 deletions(-) diff --git a/uniforce/inc/cron_functions.php b/uniforce/inc/cron_functions.php index 6d86c91..70e5f88 100644 --- a/uniforce/inc/cron_functions.php +++ b/uniforce/inc/cron_functions.php @@ -7,9 +7,9 @@ use Cleantalk\USP\Variables\Server; function uniforce_fw_update( $immediate = false ){ - + $usp = State::getInstance(); - + // SFW actions if( $usp->key && $usp->settings->fw ){ @@ -35,16 +35,16 @@ function uniforce_fw_update( $immediate = false ){ function uniforce_fw_send_logs(){ $usp = State::getInstance(); - + // SFW actions if( $usp->key && $usp->settings->fw ){ // Send SFW logs $result = \Cleantalk\USP\Uniforce\Firewall\FW::send_log( $usp->key ); - + if( ! empty( $result['error'] ) ) Err::add( $result['error'] ); - + if( ! Err::check() ) { $usp->fw_stats->logs_sent_time = time(); $usp->fw_stats->count = 0; @@ -52,7 +52,7 @@ function uniforce_fw_send_logs(){ } } - + return ! Err::check() ? true : false; } @@ -135,8 +135,9 @@ function usp_scanner__launch(){ $usp = State::getInstance(); - if ( $usp->scanner_status === false || ! $usp->settings->scanner_auto_start ) - return true; + if ( $usp->scanner_status === false || ! $usp->settings->scanner_auto_start ){ + return true; + } return Helper::http__request( CT_USP_URI, @@ -151,9 +152,9 @@ function usp_scanner__launch(){ } function usp_scanner__get_signatures() { - + $usp = State::getInstance(); - + $scanner_controller = new \Cleantalk\USP\ScannerController( CT_USP_SITE_ROOT ); $out = $scanner_controller->action__scanner__get_signatures(); @@ -164,4 +165,4 @@ function usp_get_latest_version(){ $updater = new \Cleantalk\USP\Updater\Updater( CT_USP_ROOT ); State::getInstance()->plugin_meta->latest_version = $updater->getLatestVersion(); State::getInstance()->plugin_meta->save(); -} \ No newline at end of file +} diff --git a/uniforce/lib/Cleantalk/USP/Common/Helper.php b/uniforce/lib/Cleantalk/USP/Common/Helper.php index ea6308b..3541dcb 100644 --- a/uniforce/lib/Cleantalk/USP/Common/Helper.php +++ b/uniforce/lib/Cleantalk/USP/Common/Helper.php @@ -17,7 +17,7 @@ * @see https://github.com/CleanTalk/php-antispam */ class Helper{ - + use \Cleantalk\USP\Templates\Singleton; static $instance; @@ -26,7 +26,7 @@ class Helper{ * Default user agent for HTTP requests */ const DEFAULT_USER_AGENT = 'Cleantalk-Helper/3.2'; - + /** * @var array Set of private networks IPv4 and IPv6 */ @@ -43,7 +43,7 @@ class Helper{ '0:0:0:0:0:0:a:1/128', // ::ffff:127.0.0.1 ), ); - + /** * @var array Set of CleanTalk servers */ @@ -65,7 +65,7 @@ class Helper{ 'netserv2.cleantalk.org' => '178.63.60.214', 'netserv3.cleantalk.org' => '188.40.14.173', ); - + /** * Getting arrays of IP (REMOTE_ADDR, X-Forwarded-For, X-Real-Ip, Cf_Connecting_Ip) * @@ -78,7 +78,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa { $ips = array_flip($ip_types); // Result array with IPs $headers = self::http__get_headers(); - + // REMOTE_ADDR if(isset($ips['remote_addr'])){ $ip_type = self::ip__validate(Server::get( 'REMOTE_ADDR' )); @@ -86,7 +86,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa $ips['remote_addr'] = $ip_type == 'v6' ? self::ip__v6_normalize(Server::get( 'REMOTE_ADDR' )) : Server::get( 'REMOTE_ADDR' ); } } - + // X-Forwarded-For if(isset($ips['x_forwarded_for'])){ if(isset($headers['X-Forwarded-For'])){ @@ -98,7 +98,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa } } } - + // X-Real-Ip if(isset($ips['x_real_ip'])){ if(isset($headers['X-Real-Ip'])){ @@ -110,7 +110,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa } } } - + // Cloud Flare if(isset($ips['cloud_flare'])){ if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){ @@ -122,15 +122,15 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa } } } - + // Getting real IP from REMOTE_ADDR or Cf_Connecting_Ip if set or from (X-Forwarded-For, X-Real-Ip) if REMOTE_ADDR is local. if(isset($ips['real'])){ - + // Detect IP type $ip_type = self::ip__validate(Server::get( 'REMOTE_ADDR' ) ); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(Server::get( 'REMOTE_ADDR' )) : Server::get( 'REMOTE_ADDR' ); - + // Cloud Flare if(isset($headers['CF-Connecting-IP'], $headers['CF-IPCountry'], $headers['CF-RAY']) || isset($headers['Cf-Connecting-Ip'], $headers['Cf-Ipcountry'], $headers['Cf-Ray'])){ $tmp = isset($headers['CF-Connecting-IP']) ? $headers['CF-Connecting-IP'] : $headers['Cf-Connecting-Ip']; @@ -138,29 +138,29 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa $ip_type = self::ip__validate(trim($tmp[0])); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize(trim($tmp[0])) : trim($tmp[0]); - + // Sucury }elseif(isset($headers['X-Sucuri-Clientip'], $headers['X-Sucuri-Country'])){ $ip_type = self::ip__validate($headers['X-Sucuri-Clientip']); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Sucuri-Clientip']) : $headers['X-Sucuri-Clientip']; - + // OVH }elseif(isset($headers['X-Cdn-Any-Ip'], $headers['Remote-Ip'])){ $ip_type = self::ip__validate($headers['X-Cdn-Any-Ip']); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['X-Cdn-Any-Ip']) : $headers['X-Cdn-Any-Ip']; - + // Incapsula proxy }elseif(isset($headers['Incap-Client-Ip'])){ $ip_type = self::ip__validate($headers['Incap-Client-Ip']); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($headers['Incap-Client-Ip']) : $headers['Incap-Client-Ip']; } - + // Is private network if($ip_type === false || ($ip_type && (self::ip__is_private_network($ips['real'], $ip_type) || self::ip__mask_match($ips['real'], $_SERVER['SERVER_ADDR'] . '/24', $ip_type)))){ - + // X-Forwarded-For if(isset($headers['X-Forwarded-For'])){ $tmp = explode(',', trim($headers['X-Forwarded-For'])); @@ -168,7 +168,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa $ip_type = self::ip__validate($tmp); if($ip_type) $ips['real'] = $ip_type == 'v6' ? self::ip__v6_normalize($tmp) : $tmp; - + // X-Real-Ip }elseif(isset($headers['X-Real-Ip'])){ $tmp = explode(',', trim($headers['X-Real-Ip'])); @@ -179,7 +179,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa } } } - + // Validating IPs $result = array(); foreach($ips as $key => $ip){ @@ -188,7 +188,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa $result[$key] = $ip; } } - + $result = array_unique($result); return count($result) > 1 ? $result @@ -196,7 +196,7 @@ static public function ip__get($ip_types = array('real', 'remote_addr', 'x_forwa ? reset($result) : null); } - + /** * Checks if the IP is in private range * @@ -209,7 +209,7 @@ static function ip__is_private_network($ip, $ip_type = 'v4') { return self::ip__mask_match($ip, self::$private_networks[$ip_type], $ip_type); } - + /** * Check if the IP belong to mask. Recursive. * Octet by octet for IPv4 @@ -295,7 +295,7 @@ static public function ip__mask_match($ip, $cidr, $ip_type = 'v4', $xtet_count = return $result; } - + /** * Converts long mask like 4294967295 to number like 32 * @@ -308,7 +308,7 @@ static function ip__mask__long_to_number($long_mask) $num_mask = strpos((string)decbin($long_mask), '0'); return $num_mask === false ? 32 : $num_mask; } - + /** * Validating IPv4, IPv6 * @@ -337,7 +337,7 @@ public static function cidrValidate($cidr) return isset($cidr[0], $cidr[1]) && self::ip__validate($cidr[0]) && preg_match('@\d{1,2}@', $cidr[1]); } - + /** * Expand IPv6 * @@ -368,7 +368,7 @@ static public function ip__v6_normalize($ip) } return $ip; } - + /** * Reduce IPv6 * @@ -385,7 +385,7 @@ static public function ip__v6_reduce($ip) } return $ip; } - + /** * Get URL form IP. Check if it's belong to cleantalk. * @@ -403,7 +403,7 @@ static public function ip__is_cleantalks($ip) }else return false; } - + /** * Get URL form IP. Check if it's belong to cleantalk. * @@ -421,7 +421,7 @@ static public function ip__resolve__cleantalks($ip) }else return $ip; } - + /** * Get URL form IP * @@ -438,7 +438,7 @@ static public function ip__resolve($ip) } return $ip; } - + /** * Resolve DNS to IP * @@ -449,7 +449,7 @@ static public function ip__resolve($ip) */ static public function dns__resolve($host, $out = false) { - + // Get DNS records about URL if(function_exists('dns_get_record')){ $records = dns_get_record($host, DNS_A); @@ -457,7 +457,7 @@ static public function dns__resolve($host, $out = false) $out = $records[0]['ip']; } } - + // Another try if first failed if(!$out && function_exists('gethostbynamel')){ $records = gethostbynamel($host); @@ -465,15 +465,15 @@ static public function dns__resolve($host, $out = false) $out = $records[0]; } } - + return $out; - + } - + static public function http__user_agent(){ return defined( 'CLEANTALK_USER_AGENT' ) ? CLEANTALK_USER_AGENT : static::DEFAULT_USER_AGENT; } - + /** * Function sends raw http request * @@ -497,7 +497,7 @@ static public function http__request($url, $data = array(), $presets = null, $op global $apbct_debug; $apbct_debug['data'] = $data; } - + // Preparing presets $presets = is_array($presets) ? $presets : explode(' ', $presets); $curl_only = in_array( 'async', $presets ) || @@ -505,17 +505,17 @@ static public function http__request($url, $data = array(), $presets = null, $op in_array( 'ssl', $presets ) || in_array( 'split_to_array', $presets ) ? true : false; - + if(function_exists('curl_init')){ - + $ch = curl_init(); - + // Set data if it's not empty if(!empty($data)){ // If $data scalar converting it to array $opts[CURLOPT_POSTFIELDS] = $data; } - + // Merging OBLIGATORY options with GIVEN options // Using POST method by default $opts = static::array_merge__save_numeric_keys( @@ -539,39 +539,39 @@ static public function http__request($url, $data = array(), $presets = null, $op foreach($presets as $preset){ switch($preset){ - + // Do not follow redirects case 'dont_follow_redirects': $opts[CURLOPT_FOLLOWLOCATION] = false; $opts[CURLOPT_MAXREDIRS] = 0; break; - + // Get headers only case 'get_code': $opts[CURLOPT_HEADER] = true; $opts[CURLOPT_NOBODY] = true; break; - + // Make a request, don't wait for an answer case 'async': $opts[CURLOPT_CONNECTTIMEOUT_MS] = 1000; $opts[CURLOPT_TIMEOUT_MS] = 500; break; - + case 'get': $opts[CURLOPT_URL] .= $data ? '?' . str_replace( "&", "&", http_build_query( $data ) ) : ''; $opts[CURLOPT_CUSTOMREQUEST] = 'GET'; $opts[CURLOPT_POST] = false; $opts[CURLOPT_POSTFIELDS] = null; break; - + case 'ssl': $opts[CURLOPT_SSL_VERIFYPEER] = true; $opts[CURLOPT_SSL_VERIFYHOST] = 2; if(defined('CLEANTALK_CASERT_PATH') && CLEANTALK_CASERT_PATH) $opts[CURLOPT_CAINFO] = CLEANTALK_CASERT_PATH; break; - + case 'get_file': $opts[CURLOPT_CUSTOMREQUEST] = 'GET'; $opts[CURLOPT_POST] = false; @@ -581,59 +581,59 @@ static public function http__request($url, $data = array(), $presets = null, $op case 'http_20': $opts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; break; - + default: - + break; } } curl_setopt_array($ch, $opts); $result = curl_exec($ch); - + // RETURN if async request if(in_array('async', $presets)) return true; - + if( ! $result ){ - + $out = array( 'error' => curl_error( $ch ) ); - + }elseif( strpos( $result, 'error_message' ) && ! in_array( 'get_file', $presets ) ){ - + $out_tmp = json_decode( $result, true); $out = array( 'error' => $out_tmp['error_message'], 'error_original' => $out_tmp, ); - + }else{ - + // Split to array by lines if such preset given if( strpos( $result, PHP_EOL ) !== false && in_array( 'split_to_array', $presets ) ) $result = explode(PHP_EOL, $result); - + // Get code crossPHP method if(in_array('get_code', $presets)){ $curl_info = curl_getinfo($ch); $result = $curl_info['http_code']; } - + $out = $result; - + } - - + + curl_close($ch); - + // Curl not installed. Trying file_get_contents() }elseif( ini_get( 'allow_url_fopen' ) && ! $curl_only ){ - + // Trying to get code via get_headers() if( in_array( 'get_code', $presets ) ){ $headers = get_headers( $url ); $result = (int) preg_replace( '/.*(\d{3}).*/', '$1', $headers[0] ); - + // Making common request }else{ $opts = array( @@ -646,14 +646,14 @@ static public function http__request($url, $data = array(), $presets = null, $op $context = stream_context_create( $opts ); $result = @file_get_contents( $url, 0, $context ); } - + $out = $result === false ? 'FAILED_TO_USE_FILE_GET_CONTENTS' : $result; - + }else $out = array('error' => 'CURL not installed and allow_url_fopen is disabled'); - + return $out; } @@ -712,7 +712,7 @@ static public function http__get_data_from_remote_gz( $url ){ return $data; } - + /** * Wrapper for http_request * Requesting HTTP response code for $url @@ -722,26 +722,26 @@ static public function http__get_data_from_remote_gz( $url ){ * @return array|mixed|string */ public static function get_data_from_local_gz( $path ){ - + if ( file_exists( $path ) ) { - + if ( is_readable( $path ) ) { - + $data = file_get_contents( $path ); - + if ( $data !== false ){ - + if( static::get_mime_type( $data, 'application/x-gzip' ) ){ - + if( function_exists('gzdecode') ) { - + $data = gzdecode( $data ); - + if ( $data !== false ){ return $data; }else return array( 'error' => 'Can not unpack datafile'); - + }else return array( 'error' => 'Function gzdecode not exists. Please update your PHP at least to version 5.4 ' . $data['error'] ); }else @@ -753,18 +753,18 @@ public static function get_data_from_local_gz( $path ){ }else return array( 'error' => 'File doesn\'t exists: ' . $path ); } - + public static function http__download_remote_file( $url, $tmp_folder ){ - + $result = self::http__request( $url, array(), 'get_file' ); - + if( empty( $result['error'] ) ){ - + $file_name = basename( $url ); - + if( ! is_dir( $tmp_folder ) ) mkdir( $tmp_folder ); - + if( ! file_exists( $tmp_folder . $file_name ) ){ file_put_contents( $tmp_folder . $file_name, $result ); return $tmp_folder . $file_name; @@ -773,7 +773,7 @@ public static function http__download_remote_file( $url, $tmp_folder ){ }else return $result; } - + /** * Do multi curl requests. * @@ -788,17 +788,17 @@ public static function http__download_remote_file__multi( $urls, $write_to = '' if( ! is_array( $urls ) || empty( $urls ) ) { return array( 'error' => 'CURL_MULTI: Parameter is not an array.' ); } - + foreach( $urls as $url ) { if( ! is_string( $url ) ) { return array( 'error' => 'CURL_MULTI: Parameter elements must be strings.' ); } } - + $urls_count = count( $urls ); $curl_arr = array(); $master = curl_multi_init(); - + for($i = 0; $i < $urls_count; $i++) { $url =$urls[$i]; @@ -815,14 +815,14 @@ public static function http__download_remote_file__multi( $urls, $write_to = '' curl_setopt_array($curl_arr[$i], $opts); curl_multi_add_handle($master, $curl_arr[$i]); } - + do { curl_multi_exec($master,$running); // @ToDo place here sleep(500) to avoid possible CPU overusing } while($running > 0); - + $results = array(); - + for($i = 0; $i < $urls_count; $i++) { $info = curl_getinfo($curl_arr[$i], CURLINFO_HTTP_CODE); @@ -834,14 +834,14 @@ public static function http__download_remote_file__multi( $urls, $write_to = '' } else { $results[] = curl_multi_getcontent( $curl_arr[$i] ); } - + } else { $results[] = 'error'; } } return $results; } - + /** * @param $url string * @@ -852,8 +852,8 @@ public static function getFilenameFromUrl( $url ) $array = explode( '/', $url ); return end( $array ); } - - + + /** * Gets every HTTP_ headers from $_SERVER * @@ -864,7 +864,7 @@ public static function getFilenameFromUrl( $url ) */ public static function http__get_headers() { - + $headers = array(); if ( !is_array($_SERVER) ) { @@ -888,7 +888,7 @@ public static function http__get_headers() } return $headers; } - + /** * Merging arrays without reseting numeric keys * @@ -904,7 +904,7 @@ public static function array_merge__save_numeric_keys($arr1, $arr2) } return $arr1; } - + /** * Merging arrays without reseting numeric keys recursive * @@ -916,21 +916,21 @@ public static function array_merge__save_numeric_keys($arr1, $arr2) public static function array_merge__save_numeric_keys__recursive($arr1, $arr2) { foreach($arr2 as $key => $val){ - + // Array | array => array if(isset($arr1[$key]) && is_array($arr1[$key]) && is_array($val)){ $arr1[$key] = self::array_merge__save_numeric_keys__recursive($arr1[$key], $val); - + // Scalar | array => array }elseif(isset($arr1[$key]) && !is_array($arr1[$key]) && is_array($val)){ $tmp = $arr1[$key] = $arr1[$key] = $val; $arr1[$key][] = $tmp; - + // array | scalar => array }elseif(isset($arr1[$key]) && is_array($arr1[$key]) && !is_array($val)){ $arr1[$key][] = $val; - + // scalar | scalar => scalar }else{ $arr1[$key] = $val; @@ -938,7 +938,7 @@ public static function array_merge__save_numeric_keys__recursive($arr1, $arr2) } return $arr1; } - + /** * Function removing non UTF8 characters from array|string|object * @@ -954,7 +954,7 @@ public static function removeNonUTF8($data) $val = self::removeNonUTF8($val); } unset($key, $val); - + //String }else{ if(!preg_match('//u', $data)) @@ -962,7 +962,7 @@ public static function removeNonUTF8($data) } return $data; } - + /** * Function convert anything to UTF8 and removes non UTF8 characters * @@ -979,7 +979,7 @@ public static function toUTF8($obj, $data_codepage = null) $val = self::toUTF8($val, $data_codepage); } unset($key, $val); - + //String }else{ if(!preg_match('//u', $obj) && function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')){ @@ -991,7 +991,7 @@ public static function toUTF8($obj, $data_codepage = null) } return $obj; } - + /** * Function convert from UTF8 * @@ -1008,7 +1008,7 @@ public static function fromUTF8($obj, $data_codepage = null) $val = self::fromUTF8($val, $data_codepage); } unset($key, $val); - + //String }else{ if(preg_match('u', $obj) && function_exists('mb_convert_encoding') && $data_codepage !== null) @@ -1016,7 +1016,7 @@ public static function fromUTF8($obj, $data_codepage = null) } return $obj; } - + /** * Checks if the string is JSON type * @@ -1028,7 +1028,7 @@ static public function is_json($string) { return is_string($string) && is_array(json_decode($string, true)) ? true : false; } - + /** * Checks if given string is valid regular expression * @@ -1065,7 +1065,7 @@ static public function convert_to_regexp( $string ){ public static function time__get_interval_start( $range = 300 ){ return time() - ( ( time() - strtotime( date( 'd F Y' ) ) ) % $range ); } - + /** * Get mime type from file or data * @@ -1085,7 +1085,7 @@ static function get_mime_type( $data, $type = '' ) } return $type; } - + /** * Pops line from the csv buffer and fromat it by map to array * @@ -1098,7 +1098,7 @@ public static function buffer__csv__get_map( &$csv ){ $line = static::buffer__csv__pop_line( $csv ); return explode( ',', $line ); } - + /** * Parse Comma-separated values * @@ -1114,7 +1114,7 @@ static function buffer__parse__csv( $buffer ){ } return $buffer; } - + /** * Parse Newline-separated values * @@ -1133,7 +1133,7 @@ static function buffer__parse__nsv( $buffer ){ unset( $value ); return $buffer; } - + /** * Pops line from buffer without formatting * @@ -1161,7 +1161,7 @@ static public function buffer__csv__pop_line_to_array( &$csv, $map = array(), $s $line = strpos( $line, '\'' ) === 0 ? str_getcsv( $line, ',', '\'' ) : explode( ',', $line ); - + if( $stripslashes ){ $line = array_map( function( $elem ){ return stripslashes( $elem ); @@ -1171,10 +1171,10 @@ static public function buffer__csv__pop_line_to_array( &$csv, $map = array(), $s } if( $map ) $line = array_combine( $map, $line ); - + return $line; } - + /** * Create an array from csv string according to map * @@ -1190,7 +1190,7 @@ static public function buffer__csv__to_array( &$csv, $map = array() ){ } return $out; } - + static function buffer__trim_and_clear_from_empty_lines( $buffer ){ $buffer = (array) $buffer; foreach( $buffer as $indx => &$line ){ @@ -1200,13 +1200,13 @@ static function buffer__trim_and_clear_from_empty_lines( $buffer ){ } return $buffer; } - + static function buffer__parse__in_lines( $buffer ){ $buffer = explode( "\n", $buffer ); $buffer = self::buffer__trim_and_clear_from_empty_lines( $buffer ); return $buffer; } - + static function search_page_errors($string_page){ return ( empty($string_page) @@ -1241,5 +1241,5 @@ static function arg_to_timestamp($arg) return $arg; } - -} \ No newline at end of file + +} diff --git a/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php b/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php index ac8c16d..3c42999 100644 --- a/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php +++ b/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php @@ -11,13 +11,13 @@ class RemoteCalls const COOLDOWN = 10; public static function check() { - + return Get::is_set('spbc_remote_call_token', 'spbc_remote_call_action', 'plugin_name') && in_array(Get::get('plugin_name'), array('security','spbc')); } public static function perform(){ - + $usp = State::getInstance(); $action = strtolower(Get::get('spbc_remote_call_action')); @@ -41,11 +41,11 @@ public static function perform(){ // Scanner actions if ( strpos( $action, 'scanner__' ) !== false ) { - + $action = Get::get( 'no_sql' ) ? $action . '___no_sql' : $action; - + if ( method_exists( '\Cleantalk\USP\ScannerController', $action ) ) { - + $scanner_controller = new \Cleantalk\USP\ScannerController( CT_USP_SITE_ROOT, array( $usp->data->db_request_string, $usp->data->db_user, $usp->data->db_password) @@ -85,9 +85,9 @@ static function action__close_renew_banner() { } static function action__update_security_firewall() { - + $result = FW::update( State::getInstance()->key ); - + die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error']))); } @@ -104,4 +104,4 @@ static function action__private_record_delete() die(empty($result['error']) ? 'OK' : 'FAIL '.json_encode(array('error' => $result['error']))); } -} \ No newline at end of file +} From 655a8289526eae5e290cfa09a40a69b8ab30e936 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Wed, 20 Mar 2024 17:57:28 +0500 Subject: [PATCH 4/9] New. Scanner. Background scanner log layout implemented. --- uniforce/inc/cron_functions.php | 15 ++++ uniforce/inc/scanner.php | 70 +++++++++++++++++++ uniforce/js/settings.js | 7 +- uniforce/lib/Cleantalk/USP/Common/State.php | 25 +++++-- .../lib/Cleantalk/USP/ScannerController.php | 3 + 5 files changed, 113 insertions(+), 7 deletions(-) diff --git a/uniforce/inc/cron_functions.php b/uniforce/inc/cron_functions.php index 70e5f88..4490a75 100644 --- a/uniforce/inc/cron_functions.php +++ b/uniforce/inc/cron_functions.php @@ -139,6 +139,21 @@ function usp_scanner__launch(){ return true; } + $usp->data->stat->scanner_background_log = array( + 'create_db' => array(), + 'clear_table' => array(), + 'get_signatures' => array(), + 'surface_analysis' => array(), + 'get_approved' => array(), + 'signature_analysis' => array(), + 'heuristic_analysis' => array(), + 'auto_cure' => array(), + //'frontend_analysis', + //'outbound_links', + 'send_results' => array() + ); + $usp->data->save(); + return Helper::http__request( CT_USP_URI, array( diff --git a/uniforce/inc/scanner.php b/uniforce/inc/scanner.php index a612941..e35645d 100644 --- a/uniforce/inc/scanner.php +++ b/uniforce/inc/scanner.php @@ -413,6 +413,8 @@ function usp_scanner__display(){ return; } + + //get next scan launch block $scanner_next_launch = Cron::getTaskNextCall('scanner_launch', 'Y-m-d H:i:s'); if ($scanner_next_launch) { echo '

'; @@ -439,6 +441,74 @@ function usp_scanner__display(){ } echo '

'; + //background log layout + $background_log = !empty($usp->data->stat->scanner_background_log->convertToArray()) + ? $usp->data->stat->scanner_background_log->convertToArray() + : false; + $background_log_formatted = array(); + foreach ($background_log as $stage => $values) { + $additional_info = ''; + if (!empty($values['processed'])) { + $additional_info = ', files processed ' . $values['processed']; + } + if (!empty($values['updated'])) { + $additional_info = ', signatures updated ' . $values['updated']; + } + switch ($stage) { + case 'create_db': + $stage_name = 'Database creating'; + break; + case 'clear_table': + $stage_name = 'Database clearing'; + break; + case 'get_signatures': + $stage_name = 'Signatures getting'; + break; + case 'surface_analysis': + $stage_name = 'Surface analysis'; + break; + case 'get_approved': + $stage_name = 'Approved hashes get'; + break; + case 'signature_analysis': + $stage_name = 'Signature analysis'; + break; + case 'heuristic_analysis': + $stage_name = 'Heuristic analysis'; + break; + case 'auto_cure': + $stage_name = 'Automatic cure'; + break; + //'frontend_analysis', + //'outbound_links', + case 'send_results': + $stage_name = 'Sending results'; + break; + default: + $stage_name = $stage; + } + $background_log_formatted[$stage_name] = array( + 'success' => isset($values['end']) && $values['end'] ? 'OK' : 'FAIL', + 'additional_info' => $additional_info, + ); + } + $background_templated = ''; + foreach ($background_log_formatted as $stage => $states) + { + $background_templated .= ''; + $background_templated .= $stage . ': ' . $states['success'] . $states['additional_info']; + $background_templated .= ''; + } + if ($background_log) { + echo '

Click to show/hide last background scheduled scan log

'; + $template = ' + + '; + printf($template, $background_templated); + } + // Statistics link echo '

'; echo sprintf( diff --git a/uniforce/js/settings.js b/uniforce/js/settings.js index d415bac..06042f3 100644 --- a/uniforce/js/settings.js +++ b/uniforce/js/settings.js @@ -34,6 +34,11 @@ jQuery(document).ready(function() { update(); }); + //show background scan log + $("#background_scan_log_toggler").on('click', function(event){ + $("#background_scan_log").toggle('slow'); + }); + jQuery('.ctusp_tab_navigation').on('click', '.ctusp_tab_navigation-title', function (event) { usp_switchTab(event.currentTarget); }); @@ -293,4 +298,4 @@ function uspSettingsDependencies(settingsIDs, enable){ elem.getAttribute('disabled') === null ? do_disable() : do_enable(); }); -} \ No newline at end of file +} diff --git a/uniforce/lib/Cleantalk/USP/Common/State.php b/uniforce/lib/Cleantalk/USP/Common/State.php index 0ed54c9..402aeae 100644 --- a/uniforce/lib/Cleantalk/USP/Common/State.php +++ b/uniforce/lib/Cleantalk/USP/Common/State.php @@ -3,9 +3,9 @@ namespace Cleantalk\USP\Common; /* - * + * * CleanTalk Security State class - * + * * @package Security Plugin by CleanTalk * @subpackage State * @Version 2.0 @@ -77,7 +77,7 @@ class State extends \Cleantalk\USP\Common\Storage{ 'db_user' => '', 'db_password' => '', 'db_created' => '', - + // Application 'is_installed' => false, 'detected_cms' => 'Unknown', @@ -114,6 +114,19 @@ class State extends \Cleantalk\USP\Common\Storage{ 'php_logs' => array( 'last_sent' => 0, ), + 'scanner_background_log' => array( + 'create_db' => array(), + 'clear_table' => array(), + 'get_signatures' => array(), + 'surface_analysis' => array(), + 'get_approved' => array(), + 'signature_analysis' => array(), + 'heuristic_analysis' => array(), + 'auto_cure' => array(), + //'frontend_analysis', + //'outbound_links', + 'send_results' => array() + ), ), // Account @@ -187,13 +200,13 @@ class State extends \Cleantalk\USP\Common\Storage{ 'logs_sent_time' => 0, 'last_update' => 0, ); - + private $default_plugin_meta = array( 'version' => '1.0.0', 'latest_version' => '1.0.0', 'is_installed' => false, ); - + public function __construct( ...$options ) { // Default options to get @@ -211,7 +224,7 @@ public function __construct( ...$options ) $option = is_array( $option ) ? array_merge( $this->$def_option_name, $option ) : $this->$def_option_name; - + // Generating salt if($option_name === 'data'){ diff --git a/uniforce/lib/Cleantalk/USP/ScannerController.php b/uniforce/lib/Cleantalk/USP/ScannerController.php index d06c251..6e321bf 100644 --- a/uniforce/lib/Cleantalk/USP/ScannerController.php +++ b/uniforce/lib/Cleantalk/USP/ScannerController.php @@ -155,6 +155,9 @@ public function action__scanner__controller(){ break; } + $state = (string)($this->state); + $usp->data->stat->scanner_background_log->$state = (array)$result; + $usp->data->save(); // Make next call if everything is ok if( ! isset( $end ) && empty( $result['error'] ) ){ From bac131464d55afd859e945ff32fa6e38d57b3fb7 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Thu, 21 Mar 2024 17:20:43 +0500 Subject: [PATCH 5/9] Fix. Stages results collection. --- uniforce/inc/cron_functions.php | 3 +- uniforce/inc/scanner.php | 124 ++++++++++-------- uniforce/lib/Cleantalk/USP/Common/State.php | 3 +- .../lib/Cleantalk/USP/ScannerController.php | 13 +- 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/uniforce/inc/cron_functions.php b/uniforce/inc/cron_functions.php index 4490a75..97f0da0 100644 --- a/uniforce/inc/cron_functions.php +++ b/uniforce/inc/cron_functions.php @@ -150,7 +150,8 @@ function usp_scanner__launch(){ 'auto_cure' => array(), //'frontend_analysis', //'outbound_links', - 'send_results' => array() + 'send_results' => array(), + 'last_executed' => array() ); $usp->data->save(); diff --git a/uniforce/inc/scanner.php b/uniforce/inc/scanner.php index e35645d..eb45e37 100644 --- a/uniforce/inc/scanner.php +++ b/uniforce/inc/scanner.php @@ -442,73 +442,83 @@ function usp_scanner__display(){ echo '

'; //background log layout - $background_log = !empty($usp->data->stat->scanner_background_log->convertToArray()) + $background_log = is_object($usp->data->stat->scanner_background_log) && !empty($usp->data->stat->scanner_background_log->convertToArray()) ? $usp->data->stat->scanner_background_log->convertToArray() - : false; - $background_log_formatted = array(); - foreach ($background_log as $stage => $values) { - $additional_info = ''; - if (!empty($values['processed'])) { - $additional_info = ', files processed ' . $values['processed']; - } - if (!empty($values['updated'])) { - $additional_info = ', signatures updated ' . $values['updated']; - } - switch ($stage) { - case 'create_db': - $stage_name = 'Database creating'; - break; - case 'clear_table': - $stage_name = 'Database clearing'; - break; - case 'get_signatures': - $stage_name = 'Signatures getting'; - break; - case 'surface_analysis': - $stage_name = 'Surface analysis'; - break; - case 'get_approved': - $stage_name = 'Approved hashes get'; - break; - case 'signature_analysis': - $stage_name = 'Signature analysis'; - break; - case 'heuristic_analysis': - $stage_name = 'Heuristic analysis'; - break; - case 'auto_cure': - $stage_name = 'Automatic cure'; - break; + : array(); + $has_ran = !empty($background_log) && !empty($background_log['last_executed']); + if ($has_ran) { + $background_log_formatted = array(); + foreach ($background_log as $stage => $values) { + $additional_info = ''; + if (!empty($values['processed'])) { + $additional_info = ', files processed on last iteration ' . $values['processed']; + } + if (!empty($values['updated'])) { + $additional_info = ', signatures updated ' . $values['updated']; + } + if (!empty($values['time'])) { + $additional_info = ', on ' . date('Y-m-d H:i:s', (int)$values['time']); + } + switch ($stage) { + case 'create_db': + $stage_name = 'Database creating'; + break; + case 'clear_table': + $stage_name = 'Database clearing'; + break; + case 'get_signatures': + $stage_name = 'Signatures getting'; + break; + case 'surface_analysis': + $stage_name = 'Surface analysis'; + break; + case 'get_approved': + $stage_name = 'Approved hashes get'; + break; + case 'signature_analysis': + $stage_name = 'Signature analysis'; + break; + case 'heuristic_analysis': + $stage_name = 'Heuristic analysis'; + break; + case 'auto_cure': + $stage_name = 'Automatic cure'; + break; //'frontend_analysis', //'outbound_links', - case 'send_results': - $stage_name = 'Sending results'; - break; - default: - $stage_name = $stage; + case 'send_results': + $stage_name = 'Sending results'; + break; + case 'last_executed': + $stage_name = 'Last run'; + break; + default: + $stage_name = $stage; + } + $background_log_formatted[$stage_name] = array( + 'success' => isset($values['end']) && $values['end'] ? 'OK' : 'FAIL', + 'additional_info' => $additional_info, + ); } - $background_log_formatted[$stage_name] = array( - 'success' => isset($values['end']) && $values['end'] ? 'OK' : 'FAIL', - 'additional_info' => $additional_info, - ); - } - $background_templated = ''; - foreach ($background_log_formatted as $stage => $states) - { - $background_templated .= ''; - $background_templated .= $stage . ': ' . $states['success'] . $states['additional_info']; - $background_templated .= ''; - } - if ($background_log) { - echo '

Click to show/hide last background scheduled scan log

'; - $template = ' + $background_templated = ''; + foreach ($background_log_formatted as $stage => $states) + { + $background_templated .= ''; + $background_templated .= $stage . ': ' . $states['success'] . $states['additional_info']; + $background_templated .= ''; + } + if (!empty($background_templated)) { + echo '

Click to show/hide last background scheduled scan log

'; + $template = ' '; - printf($template, $background_templated); + printf($template, $background_templated); + } } + // Statistics link echo '

'; echo sprintf( diff --git a/uniforce/lib/Cleantalk/USP/Common/State.php b/uniforce/lib/Cleantalk/USP/Common/State.php index 402aeae..11960d6 100644 --- a/uniforce/lib/Cleantalk/USP/Common/State.php +++ b/uniforce/lib/Cleantalk/USP/Common/State.php @@ -125,7 +125,8 @@ class State extends \Cleantalk\USP\Common\Storage{ 'auto_cure' => array(), //'frontend_analysis', //'outbound_links', - 'send_results' => array() + 'send_results' => array(), + 'last_executed' => array() ), ), diff --git a/uniforce/lib/Cleantalk/USP/ScannerController.php b/uniforce/lib/Cleantalk/USP/ScannerController.php index 6e321bf..ef9ed67 100644 --- a/uniforce/lib/Cleantalk/USP/ScannerController.php +++ b/uniforce/lib/Cleantalk/USP/ScannerController.php @@ -126,7 +126,7 @@ public function action__scanner__controller(){ $result = $this->action__scanner__signature_analysis( $this->offset, - 10, + 100, $this->root ); @@ -137,7 +137,7 @@ public function action__scanner__controller(){ $result = $this->action__scanner__heuristic_analysis( $this->offset, - 10, + 100, $this->root ); @@ -183,7 +183,12 @@ public function action__scanner__controller(){ ? $usp->error_delete( $this->state, 'and_save_data', 'cron_scan' ) : $usp->error_add( $this->state, $result, 'cron_scan' ); - Cron::updateTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); + if (isset($end)) { + $usp->data->stat->scanner_background_log->last_executed = array('end' => empty( $result['error'] ), 'time' => time()); + $usp->data->save(); + + Cron::updateTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); + } return true; } @@ -593,6 +598,8 @@ public function action__scanner__signature_analysis( $offset = null, $amount = n } //end of iteration check + error_log('CTDEBUG: [' . __FUNCTION__ . '] [$signatures_ok_hashes]: ' . var_export($signatures_ok_hashes,true)); + //do bulk update for every good file try { $update_ok_files_count = $this->scanner__db_update_ok_files($signatures_ok_hashes, 'signatures'); From 5600864f8d54457fef397308912bd8a04c6eb435 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Thu, 21 Mar 2024 17:48:26 +0500 Subject: [PATCH 6/9] Update. Stop background scan if manual scan is run. --- uniforce/inc/cron_functions.php | 17 +++--------- uniforce/js/scanner-plugin.js | 3 ++- .../lib/Cleantalk/USP/Common/RemoteCalls.php | 9 +++++++ uniforce/lib/Cleantalk/USP/Common/State.php | 1 + .../lib/Cleantalk/USP/ScannerController.php | 26 +++++++++++++++++-- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/uniforce/inc/cron_functions.php b/uniforce/inc/cron_functions.php index 97f0da0..49d6120 100644 --- a/uniforce/inc/cron_functions.php +++ b/uniforce/inc/cron_functions.php @@ -139,22 +139,11 @@ function usp_scanner__launch(){ return true; } - $usp->data->stat->scanner_background_log = array( - 'create_db' => array(), - 'clear_table' => array(), - 'get_signatures' => array(), - 'surface_analysis' => array(), - 'get_approved' => array(), - 'signature_analysis' => array(), - 'heuristic_analysis' => array(), - 'auto_cure' => array(), - //'frontend_analysis', - //'outbound_links', - 'send_results' => array(), - 'last_executed' => array() - ); + \Cleantalk\USP\ScannerController::clearBackgroundScanLog($usp); + $usp->data->scanner->background_scan_stop = false; $usp->data->save(); + return Helper::http__request( CT_USP_URI, array( diff --git a/uniforce/js/scanner-plugin.js b/uniforce/js/scanner-plugin.js index 67ffd12..a195fa3 100644 --- a/uniforce/js/scanner-plugin.js +++ b/uniforce/js/scanner-plugin.js @@ -280,6 +280,7 @@ class spbc_Scanner{ plugin_name: 'spbc', // Adding security code offset: this.offset, no_sql: this.settings['no_sql'], + background_scan_stop: true, }; var params = { @@ -289,7 +290,7 @@ class spbc_Scanner{ complete: null, errorOutput: this.errorOutput, context: this, - timeout: 40000 + timeout: 40000, }; switch (this.state) { diff --git a/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php b/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php index 3c42999..4b8631e 100644 --- a/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php +++ b/uniforce/lib/Cleantalk/USP/Common/RemoteCalls.php @@ -37,6 +37,15 @@ public static function perform(){ // Check API key if($token == strtolower(md5($usp->settings->key)) ){ + //stop background scan if GET param provided + if ( + isset($_GET['background_scan_stop']) && + $usp->data->scanner->background_scan_stop !== (bool)$_GET['background_scan_stop'] + ) { + $usp->data->scanner->background_scan_stop = (bool)$_GET['background_scan_stop']; + $usp->data->save(); + } + $action = 'action__'.$action; // Scanner actions diff --git a/uniforce/lib/Cleantalk/USP/Common/State.php b/uniforce/lib/Cleantalk/USP/Common/State.php index 11960d6..9666e25 100644 --- a/uniforce/lib/Cleantalk/USP/Common/State.php +++ b/uniforce/lib/Cleantalk/USP/Common/State.php @@ -155,6 +155,7 @@ class State extends \Cleantalk\USP\Common\Storage{ 'offset' => 0, ), 'cured' => array(), + 'background_scan_stop' => false, ), '2fa_keys' => array(), ); diff --git a/uniforce/lib/Cleantalk/USP/ScannerController.php b/uniforce/lib/Cleantalk/USP/ScannerController.php index ef9ed67..c941b86 100644 --- a/uniforce/lib/Cleantalk/USP/ScannerController.php +++ b/uniforce/lib/Cleantalk/USP/ScannerController.php @@ -83,6 +83,11 @@ public function action__scanner__controller(){ $usp = State::getInstance(); + if ($usp->data->scanner->background_scan_stop) { + static::clearBackgroundScanLog($usp); + return true; + } + sleep(5); switch( $this->state ){ @@ -598,8 +603,6 @@ public function action__scanner__signature_analysis( $offset = null, $amount = n } //end of iteration check - error_log('CTDEBUG: [' . __FUNCTION__ . '] [$signatures_ok_hashes]: ' . var_export($signatures_ok_hashes,true)); - //do bulk update for every good file try { $update_ok_files_count = $this->scanner__db_update_ok_files($signatures_ok_hashes, 'signatures'); @@ -1211,4 +1214,23 @@ public static function get_files( $offset = 0, $amount = 1500, $path = CT_USP_SI ? $scanner->files : false; } + + public static function clearBackgroundScanLog($usp) + { + $usp->data->stat->scanner_background_log = array( + 'create_db' => array(), + 'clear_table' => array(), + 'get_signatures' => array(), + 'surface_analysis' => array(), + 'get_approved' => array(), + 'signature_analysis' => array(), + 'heuristic_analysis' => array(), + 'auto_cure' => array(), + //'frontend_analysis', + //'outbound_links', + 'send_results' => array(), + 'last_executed' => array() + ); + $usp->data->save(); + } } From b662cfd8e797901bb2b2140eb9016b82314a9688 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Fri, 22 Mar 2024 13:25:21 +0500 Subject: [PATCH 7/9] Mod. Do not update cron on background scan end. --- uniforce/lib/Cleantalk/USP/ScannerController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/ScannerController.php b/uniforce/lib/Cleantalk/USP/ScannerController.php index c941b86..a70402e 100644 --- a/uniforce/lib/Cleantalk/USP/ScannerController.php +++ b/uniforce/lib/Cleantalk/USP/ScannerController.php @@ -191,8 +191,6 @@ public function action__scanner__controller(){ if (isset($end)) { $usp->data->stat->scanner_background_log->last_executed = array('end' => empty( $result['error'] ), 'time' => time()); $usp->data->save(); - - Cron::updateTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); } return true; From 47d17e68715ba188824f3de71ad790cbaa2fd5fa Mon Sep 17 00:00:00 2001 From: alexandergull Date: Fri, 22 Mar 2024 13:47:17 +0500 Subject: [PATCH 8/9] Fix. Update cron on save settings. --- uniforce/inc/admin.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/uniforce/inc/admin.php b/uniforce/inc/admin.php index 96f4059..9a9803e 100644 --- a/uniforce/inc/admin.php +++ b/uniforce/inc/admin.php @@ -551,6 +551,15 @@ function usp_do_save_settings() { // Recognizing new key $new_key_is_set = $usp->settings->key !== $settings['key']; + + if( $settings['scanner_auto_start'] != $usp->settings->scanner_auto_start ) { + if ($settings['scanner_auto_start'] == 1) { + Cron::updateTask( 'scanner_launch', 'usp_scanner__launch', 86400, time() + 86400 ); + } else { + Cron::removeTask( 'scanner_launch'); + } + } + // Set values foreach ( $settings as $setting => $value) { $usp->settings->$setting = $value; From a25eb4b6136af138a50bd21cde8abe067698cb24 Mon Sep 17 00:00:00 2001 From: alexandergull Date: Thu, 4 Apr 2024 15:20:16 +0500 Subject: [PATCH 9/9] Fix. Cron. Cron file. Delete global sign to the variable by defaults, global variable cannot be updated by FileDB call. --- uniforce/data/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniforce/data/cron.php b/uniforce/data/cron.php index 36a0354..1d30696 100644 --- a/uniforce/data/cron.php +++ b/uniforce/data/cron.php @@ -1,2 +1,2 @@