|
Server : Apache System : Linux server.mata-lashes.com 3.10.0-1160.90.1.el7.x86_64 #1 SMP Thu May 4 15:21:22 UTC 2023 x86_64 User : matalashes ( 1004) PHP Version : 8.1.29 Disable Function : NONE Directory : /home/matalashes/www/wp-content/plugins/security-malware-firewall/inc/ |
Upload File : |
<?php
use CleantalkSP\SpbctWP\Helper as SpbcHelper;
use CleantalkSP\SpbctWP\API as SpbcAPI;
use CleantalkSP\SpbctWP\Helpers\CSV;
use CleantalkSP\SpbctWP\Scanner\FrontendScan;
use CleantalkSP\Variables\Get;
use CleantalkSP\Variables\Post;
use CleantalkSP\Variables\Request;
use CleantalkSP\SpbctWP\Scanner\Cure;
use CleantalkSP\SpbctWP\Scanner\Links;
use CleantalkSP\SpbctWP\Scanner;
use CleantalkSP\SpbctWP\Helpers\HTTP;
use CleantalkSP\Common\Helpers\Arr;
use CleantalkSP\SpbctWP\DTO;
use CleantalkSP\Fpdf\Pdf;
/**
* Cron wrapper function for launchBackground
*
* @return bool|string|string[]|void
*/
function spbc_scanner__launch()
{
$result = \CleantalkSP\SpbctWP\Scanner\ScannerQueue::launchBackground();
if (\CleantalkSP\SpbctWP\RemoteCalls::check()) {
$result = empty($result['error'])
? 'OK'
: 'FAIL ' . die(json_encode($result));
}
return $result;
}
/**
* Cron wrapper function for controllerBackground
*
* @param null $transaction_id
* @param null $stage
* @param null $offset
* @param null $amount
*
* @return bool|string|string[]
*/
function spbc_scanner__controller($transaction_id = null, $stage = null, $offset = null, $amount = null)
{
$result = \CleantalkSP\SpbctWP\Scanner\ScannerQueue::controllerBackground($transaction_id, $stage, $offset, $amount);
if (\CleantalkSP\SpbctWP\RemoteCalls::check()) {
$result = empty($result['error'])
? 'OK'
: 'FAIL ' . die(json_encode($result));
}
return $result;
}
/**
* /**
* For debug purpose
* Clear table from results
*
* @param $direct_call
*
* @return array|void
*/
function spbc_scanner_clear($direct_call = false)
{
if ( ! $direct_call) {
spbc_check_ajax_referer('spbc_secret_nonce', 'security');
}
global $spbc;
$spbc->plugins = array();
$spbc->save('plugins');
$spbc->themes = array();
$spbc->save('themes');
$spbc->data['scanner'] = array(
'last_wp_version' => null,
'cron' => array(
'state' => 'get_hashes',
'total_scanned' => 0,
'offset' => 0,
),
);
$spbc->save('data');
$out = [
'deleted_files_entries' => Scanner\Controller::resetCheckResult(),
'deleted_frontend_entries' => Scanner\Frontend::resetCheckResult(),
'deleted_links' => Scanner\Links::resetCheckResult(),
];
if ($direct_call) {
return $out;
}
wp_send_json($out);
}
function spbc_scanner_count_files($direct_call = false, $path = ABSPATH)
{
if ( ! $direct_call) {
spbc_check_ajax_referer('spbc_secret_nonce', 'security');
}
ini_set('max_execution_time', '120');
$start = microtime(true);
global $spbc;
$path_to_scan = realpath($path);
$root_path = realpath(ABSPATH);
$init_params = array(
'count' => true,
'extensions' => 'php, html, htm',
'files_mandatory' => array(),
'dir_exceptions' => array(SPBC_PLUGIN_DIR . 'quarantine')
);
if ( ! empty($spbc->settings['scanner__dir_exclusions'])) {
$init_params['dir_exceptions'] = array_merge($init_params['dir_exceptions'], explode("\n", $spbc->settings['scanner__dir_exclusions']));
}
$scaner = new Scanner\Surface($path_to_scan, $root_path, $init_params);
$output = array(
'total' => $scaner->files_count,
'exec_time' => microtime(true) - $start,
);
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_links_count($direct_call = false)
{
if ( ! $direct_call) {
spbc_check_ajax_referer('spbc_secret_nonce', 'security');
}
$links_scanner = new Links(array('count' => true));
$output = array(
'success' => true,
'total' => $links_scanner->posts_total,
);
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_links_count_found($total = true, /* Out */ $count = 0)
{
global $wpdb;
$sql_result = $wpdb->get_results(
'SELECT COUNT(*) AS cnt FROM ' . SPBC_TBL_SCAN_LINKS
. (! $total ? ' WHERE scan_id = (SELECT MAX(scan_id) FROM ' . SPBC_TBL_SCAN_LINKS . ');' : ''), // only latest scan
ARRAY_A
);
if ($sql_result) {
$count = ! $sql_result[0]['cnt'] ? 0 : $sql_result[0]['cnt'];
}
return $count;
}
function spbc_scanner_links_count_found__domains()
{
global $wpdb;
$count = $wpdb->get_results(
'SELECT COUNT(link_id) AS cnt FROM ' . SPBC_TBL_SCAN_LINKS,
OBJECT_K
);
return $count ? key($count) : 0;
}
function spbc_scanner_links_get_scanned__domains($offset = 0, $amount = 20, $order = null, $by = null, $get_array = false)
{
global $wpdb;
$offset = intval($offset);
$amount = intval($amount);
$data = $wpdb->get_results(
'SELECT domain, spam_active, page_url, COUNT(domain) as link_count
FROM ' . SPBC_TBL_SCAN_LINKS . '
GROUP BY domain
' . ($order && $by ? "ORDER BY $by $order" : '') . '
LIMIT ' . $offset . ',' . $amount . ';',
$get_array === true ? ARRAY_A : OBJECT
);
return $data;
}
function spbc_scanner_file_send($direct_call = false, $file_id = null)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
$file_id = preg_match('@[a-zA-Z0-9]{32}@', Post::get('file_id')) ? Post::get('file_id') : null;
}
global $spbc, $wpdb;
$root_path = spbc_get_root_path();
if ($file_id) {
// Getting file info.
$sql = 'SELECT fast_hash, path, source_type, source, source_status, version, mtime, weak_spots, full_hash, real_full_hash, status, checked_signatures, checked_heuristic
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ($file_info['status'] === 'APPROVED_BY_CT' || $file_info['status'] === 'APPROVED_BY_CLOUD') {
$output = array('error' => 'IT_IS_IMPOSIBLE_RESEND_APPROVED_FILE');
if ( !$direct_call ) {
wp_send_json($output);
}
return $output;
}
// Scan file before send it
// Heuristic
$result_heur = Scanner\Controller::scanFileForHeuristic($file_info, $root_path);
if ( ! empty($result_heur['error'])) {
$output = array('error' => 'RESCANNING_FAILED');
if ( !$direct_call ) {
wp_send_json($output);
}
return $output;
}
// Signature
$signatures = $wpdb->get_results('SELECT * FROM ' . SPBC_TBL_SCAN_SIGNATURES, ARRAY_A);
$result_sign = Scanner\Controller::scanFileForSignatures($file_info, $root_path, $signatures);
if ( ! empty($result_sign['error'])) {
$output = array('error' => 'RESCANNING_FAILED');
if ( !$direct_call ) {
wp_send_json($output);
}
return $output;
}
$api_response = Arr::mergeWithSavingNumericKeysRecursive($result_sign, $result_heur);
$wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'checked_signatures' => $file_info['checked_signatures'],
'checked_heuristic' => $file_info['checked_heuristic'],
'status' => $file_info['status'] === 'MODIFIED' ? 'MODIFIED' : $api_response['status'],
'severity' => $api_response['severity'],
'weak_spots' => json_encode($api_response['weak_spots']),
'full_hash' => md5_file($root_path . $file_info['path']),
),
array('fast_hash' => $file_info['fast_hash']),
array('%s', '%s', '%s', '%s', '%s', '%s'),
array('%s')
);
$file_info['weak_spots'] = $api_response['weak_spots'];
$file_info['full_hash'] = md5_file($root_path . $file_info['path']);
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_readable($root_path . $file_info['path'])) {
if (filesize($root_path . $file_info['path']) > 0) {
if (filesize($root_path . $file_info['path']) < 1048570) {
// Updating file_info if file source is unknown
if ( ! isset($file_info['version'], $file_info['source'], $file_info['source_type'])) {
$file_info_updated = spbc_get_source_info_of($file_info['path']);
if ($file_info_updated) {
$file_info = array_merge($file_info, $file_info_updated);
}
}
// Getting file && API call
$file = file_get_contents($root_path . $file_info['path']);
try {
$dto = new DTO\MScanFilesDTO(
array(
'path_to_sfile' => $file_info['path'],
'attached_sfile' => $file,
'md5sum_sfile' => $file_info['full_hash'],
'dangerous_code' => $file_info['weak_spots'],
'version' => $file_info['version'],
'source' => $file_info['source'],
'source_type' => $file_info['source_type'],
'source_status' => $file_info['source_status'],
'real_hash' => $file_info['real_full_hash'],
)
);
} catch ( \InvalidArgumentException $e ) {
return array('error' => "File can not be send. Error: \n" . substr($e->getMessage(), 0, 100));
}
$api_response = SpbcAPI::method__security_pscan_files_send($spbc->settings['spbc_key'], $dto);
if (empty($api_response['error'])) {
if ($api_response['file_id']) {
// Updating "last_sent"
$sql_result = $wpdb->query(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET'
. ' last_sent = ' . current_time('timestamp') . ','
. ' pscan_processing_status = "NEW",'
. ' pscan_pending_queue = 0,'
. ' pscan_file_id = "' . $api_response["file_id"] . '"'
. ' WHERE fast_hash = "' . $file_id . '"'
);
if ($sql_result !== false) {
$output = array('success' => true, 'result' => $api_response);
//set new cron to update statuses
\CleantalkSP\SpbctWP\Cron::updateTask(
'scanner_update_pscan_files_status',
'spbc_scanner_update_pscan_files_status',
SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD,
time() + SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD
);
//error on fail
} else {
$output = array('error' => 'DB_COULDNT_UPDATE pscan_processing_status');
}
} else {
$output = array('error' => 'API_RESPONSE: file_id is NULL');
}
} else {
if ($api_response['error'] === 'QUEUE_FULL') {
//do something with not queued files
$sql_result = $wpdb->query(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET'
. ' last_sent = ' . current_time('timestamp') . ','
. ' pscan_pending_queue = 1'
. ' WHERE fast_hash = "' . $file_id . '"'
);
if ($sql_result !== false) {
$output = array('success' => true, 'result' => $api_response);
//set new cron to resend unqueued files
\CleantalkSP\SpbctWP\Cron::updateTask('scanner_resend_pscan_files', 'spbc_scanner_resend_pscan_files', SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD, time() + SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD);
//error on fail
} else {
$output = array('error' => 'DB_COULD_NOT_UPDATE pscan_pending_queue');
}
} else {
//out API error if error is not queue_full
$output = $api_response;
}
}
} else {
$output = array('error' => 'FILE_SIZE_TO_LARGE');
}
} else {
$output = array('error' => 'FILE_SIZE_ZERO');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
if ( !$direct_call ) {
wp_send_json($output);
}
return $output;
}
function spbc_scanner_file_delete($direct_call = false, $file_id = null)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $wpdb;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
$file_path = $file_info['status'] == 'QUARANTINED' ? $file_info['q_path'] : $root_path . $file_info['path'];
if (file_exists($file_path)) {
if (is_writable($file_path)) {
// Getting file && API call
$remembered_file_content = file_get_contents($file_path);
$result = unlink($file_path);
if ($result) {
$response_content = HTTP::getContentFromURL(get_option('home'));
$response_content_admin = HTTP::getContentFromURL(get_option('home') . '/wp-admin/');
$response_code = HTTP::getResponseCode(get_option('home'));
$response_code_admin = HTTP::getResponseCode(get_option('home') . '/wp-admin/');
if (
isset(
$response_content['error'],
$response_content_admin['error'],
$response_code['error'],
$response_code_admin['error']
) ||
(is_string($response_code) && preg_match('/5\d\d/', $response_code)) ||
(is_string($response_code_admin) && preg_match('/5\d\d/', $response_code_admin)) ||
spbc_search_page_errors($response_content) ||
spbc_search_page_errors($response_content_admin)
) {
$output = array('error' => 'WEBSITE_RESPONSE_BAD');
$result = file_put_contents($file_path, $remembered_file_content);
$output['error'] .= $result === false ? ' REVERT_FAILED' : ' REVERT_OK';
} else {
// Deleting row from DB
if ($wpdb->query('DELETE FROM ' . SPBC_TBL_SCAN_FILES . ' WHERE fast_hash = "' . $file_id . '"') !== false) {
$output = array('success' => true);
} else {
$output = array('error' => 'DB_COULDNT_DELETE_ROW');
}
}
} else {
$output = array('error' => 'FILE_COULDNT_DELETE');
}
unset($remembered_file_content);
} else {
$output = array('error' => 'FILE_NOT_WRITABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_approve($direct_call = false, $file_id = null)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $spbc, $wpdb;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT path, full_hash, status, severity
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_readable($root_path . $file_info['path'])) {
// Getting file && API call
$md5 = md5_file($root_path . $file_info['path']);
if ($md5) {
$previous = json_encode(array('status' => $file_info['status'],
'severity' => $file_info['severity']
));
// Updating all other statuses
$wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'status' => 'APROVED',
'real_full_hash' => $md5,
'previous_state' => $previous,
),
array('fast_hash' => $file_id),
array('%s', '%s', '%s'),
array('%s')
);
// Set severity to NULL
// Using strait query because WPDB doesn't support NULL values
$sql = 'UPDATE ' . SPBC_TBL_SCAN_FILES . '
SET severity = NULL
WHERE fast_hash = "' . $file_id . '"';
$sql_result = $wpdb->query($sql, ARRAY_A);
if ($sql_result !== false) {
$output = array('success' => true);
} else {
$output = array('error' => 'DB_COULDNT_UPDATE_ROW_APPROVE');
}
} else {
$output = array('error' => 'FILE_COULDNT_MD5');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
/**
* Checks analysis status of passed file(s)
*
* @param bool $direct_call Direct call flag. Show that the function was called directly from other function, not from AJAX
* @param string|array $file_ids_input IDs of files to check the analysis status
* @return array|true[]
*/
function spbc_scanner_pscan_check_analysis_status($direct_call = false, $file_ids_input = '')
{
// Check ajax nonce
if ( !$direct_call ) {
check_ajax_referer('spbc_secret_nonce', 'security');
$file_ids_input = Post::get('file_id', 'hash') ? (string)Post::get('file_id') : '';
}
global $spbc, $wpdb;
// Parse if there are more than 1 file
$_file_ids_input = is_string($file_ids_input) ? explode(',', $file_ids_input) : $file_ids_input;
// Prepare counters
$counters = array(
'queued' => 0,
'updated' => 0,
'failed' => 0,
'skipped' => 0,
'total' => count($_file_ids_input)
);
// Prepare out array
$out = array('counters' => $counters);
/*
* Processing files start
*/
foreach ( $_file_ids_input as $file_id ) {
/*
* Process a single file start
*/
// Get file info.
$file_info = spbc_scanner_get_file_by_id($file_id);
// Validate file info
try {
$file_info = spbc_scanner_pscan_validate_file_info($file_info);
} catch (\Exception $e) {
$out['error_detail'][] = array(
'error' => $e->getMessage(),
);
$counters['failed']++;
continue;
}
try {
$file_info = spbc_scanner_pscan_update_check_exclusions($file_info);
} catch (\Exception $e) {
switch ($e->getMessage()) {
case 'skipped':
$counters['skipped']++;
break;
case 'queued':
$counters['queued']++;
break;
}
continue;
}
// Perform API call
$api_response = SpbcAPI::method__security_pscan_status(
$spbc->settings['spbc_key'],
$file_info['pscan_file_id']
);
// Validate API response
try {
$api_response = spbc_scanner_validate_pscan_status_response($api_response);
} catch ( Exception $exception ) {
$out['error_detail'][] = array(
'file_path' => $file_info['file_path'],
'pscan_file_id' => $file_info['pscan_file_id'],
'fast_hash' => $file_id,
'error' => 'API response validation failed "' . $exception->getMessage() . "\"",
);
continue;
}
if ( $api_response['processing_status'] !== 'DONE' ) {
/*
* If file process is not finished, update data
*/
// Set old processing status to compare with next
$old_processing_status = !empty($file_info['pscan_processing_status']) ? $file_info['pscan_processing_status'] : null;
// Update processing status
if ( $api_response['processing_status'] !== $old_processing_status ) {
// Keep update result
$update_result = $wpdb->query(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET '
. ' pscan_pending_queue = 0, '
. ' pscan_processing_status = "' . $api_response['processing_status'] . '"'
. ' WHERE pscan_file_id = "' . $file_info['pscan_file_id'] . '"'
);
}
} else {
if ( $api_response['file_status'] === 'SAFE' ) {
/*
* Do something with SAFE files
*/
// Prepare query for good files update
$update_query = $wpdb->prepare(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET '
. ' pscan_processing_status = "DONE",'
. ' pscan_pending_queue = 0, '
. ' pscan_status = "SAFE",'
. ' pscan_balls = %s,'
. ' status = "APPROVED_BY_CLOUD" '
. ' WHERE pscan_file_id = %s',
isset($api_response['file_balls']) ? $api_response['file_balls'] : '{SAFE:0}',
$file_info['pscan_file_id']
);
} else {
/*
* Do something with DANGEROUS files
*/
// Prepare query for bad files update
$update_query = $wpdb->prepare(
'UPDATE ' . SPBC_TBL_SCAN_FILES
. ' SET '
. ' pscan_processing_status = "DONE",'
. ' pscan_status = %s ,'
. ' pscan_balls = %s,'
. ' status = "DENIED_BY_CLOUD"'
. ' WHERE pscan_file_id = %s',
$api_response['file_status'],
$api_response['file_balls'],
$file_info['pscan_file_id']
);
}
// Run prepared query and keep update result
$update_result = $wpdb->query($update_query);
}
if ( $update_result === false ) {
// Collect errors
$out['error_detail'][] = array(
'file_path' => $file_info['path'],
'pscan_file_id' => $file_info['pscan_file_id'],
'fast_hash' => $file_id,
'error' => 'COULDNT_UPDATE file status',
);
} else {
// All is fine, inc updated counter
$counters['updated']++;
}
/*
* Process a single file end
*/
}
/*
* Processing files end
*/
// Process errors
if ( !empty($out['error_detail']) ) {
$out['error'] = 'Some files where not updated.';
}
// Fill counters
$out['counters'] = $counters;
// Shift cron task
\CleantalkSP\SpbctWP\Cron::updateTask(
'scanner_update_pscan_files_status',
'spbc_scanner_update_pscan_files_status',
SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD,
time() + SPBC_PSCAN_UPDATE_FILES_STATUS_PERIOD
);
// Resend queued files if available
if ( $counters['queued'] > 0 && $spbc->settings['spbc_scanner_user_can_force_pscan_update'] ) {
spbc_scanner_resend_pscan_files();
}
if (!$direct_call) {
wp_send_json_success($out);
}
return $out;
}
/**
* Validate file info collected for pscan status updating process
* @param $file_info array|false array of file info or false if we could not collect this
* @return array origin array of file info
* @throws Exception
*/
function spbc_scanner_pscan_validate_file_info($file_info)
{
// SQL query result validation
if ( $file_info !== false ) {
// Validate path
$file_path = !empty($file_info['path']) ? $file_info['path'] : false;
if (!$file_path) {
throw new Exception('can not get file path');
}
// Set pscan file id to be sure that file is correctly reached from db
$pscan_file_id = !empty($file_info['pscan_file_id']) ? $file_info['pscan_file_id'] : false;
if ( !$pscan_file_id ) {
throw new Exception('can not get pscan_file_id');
}
} else {
throw new Exception('can not get file info');
}
return $file_info;
}
/**
* Check if status updater should skip this file
* @param $file_info
* @return array array of file info
* @throws Exception message contains reason for skip the file
*/
function spbc_scanner_pscan_update_check_exclusions(array $file_info)
{
global $spbc;
//skip quarantined files
if (isset($file_info['status']) && $file_info['status'] === 'QUARANTINED') {
throw new Exception('skipped');
}
// skip not queued files
$pscan_pending_queue = isset($file_info['pscan_pending_queue']) && $file_info['pscan_pending_queue'] == '1';
if ($pscan_pending_queue) {
throw new Exception('queued');
}
//skip maual analysis checked
if (!empty($file_info['analysis_status'])) {
throw new Exception('skipped');
}
//skip already checked
if (isset($file_info['pscan_processing_status']) &&
$file_info['pscan_processing_status'] === 'DONE' &&
$spbc->settings['spbc_scanner_user_can_force_pscan_update'] !== true
) {
throw new Exception('skipped');
}
return $file_info;
}
/**
* @param array $response API Response
* @return mixed API Response
* @throws Exception if validation failed
*/
function spbc_scanner_validate_pscan_status_response($response)
{
// Check if API error
if ( !empty($response['error']) ) {
throw new Exception('API error: "' . $response['error'] . "\"");
}
// Check if processing_status is set and correct
if ( !isset($response['processing_status']) ) {
throw new Exception('response provided no processing status');
}
// Set allowed statuses
$allowed_statuses_array = array(
'NEW',
'DONE',
'ERROR',
'IN_SCANER',
'NEW_CLOUD',
'IN_CLOUD',
'IN_SANDBOX',
'NEW_SANDBOX',
'UNKNOWN'
);
// Check allowed statuses
if ( !in_array($response['processing_status'], $allowed_statuses_array) ) {
throw new Exception('response provided unknown processing status "' . $response['processing_status'] . "\"");
}
// Check precessing status
if ( $response['processing_status'] === 'DONE' && !isset($response['file_status']) ) {
throw new Exception('process finished, but status is unset');
}
if ( $response['processing_status'] === 'DONE' ) {
// Check file_status
if ( !in_array($response['file_status'], array('DANGEROUS', 'SAFE')) ) {
throw new Exception('process finished, but status is unknown: "' . $response['file_status'] . "\"");
}
if ( $response['file_status'] === 'DANGEROUS' ) {
// Check balls set on DANGEROUS file_status
if ( !isset($response['file_balls']) ) {
throw new Exception('process finished, but points in unset');
}
}
}
return $response;
}
function spbc_scanner_file_approve__bulk($ids = array())
{
if ( ! $ids) {
return array('error' => 'Noting to approve');
}
$out = array();
foreach ($ids as $id) {
$result = spbc_scanner_file_approve(true, $id);
if ( ! empty($result['error'])) {
$file_info = spbc_scanner_get_file_by_id($id);
$file_path = isset($file_info['path']) ? $file_info['path'] : 'UNKNOWN_FILE';
$out['error'] = 'Some files where not updated.';
$out['error_detail'][] = array(
'file_path' => $file_path,
'error' => $result['error'],
);
}
}
return $out;
}
function spbc_scanner_file_disapprove__bulk($ids = array())
{
if ( ! $ids) {
return array('error' => 'Noting to disapprove');
}
$out = array();
foreach ($ids as $id) {
$result = spbc_scanner_file_disapprove(true, $id);
if ( ! empty($result['error'])) {
$file_info = spbc_scanner_get_file_by_id($id);
$file_path = isset($file_info['path']) ? $file_info['path'] : 'UNKNOWN_FILE';
$out['error'] = 'Some files where not updated.';
$out['error_detail'][] = array(
'file_path' => $file_path,
'error' => $result['error'],
);
}
}
return $out;
}
function spbc_scanner_file_send_for_analysis__bulk($fast_hashes_list = array())
{
if ( ! $fast_hashes_list) {
return array('error' => 'Record has no file id to send.');
}
global $wpdb;
$sql_result = $wpdb->get_results(
'SELECT fast_hash FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE last_sent IS NULL
AND status NOT IN ("OK","APROVED","APPROVED_BY_CT","APPROVED_BY_CLOUD")',
ARRAY_A
);
$sql_result = array_map(
function ($data) {
return $data['fast_hash'];
},
$sql_result
);
$not_sent_files_intersection = array_values(array_intersect($fast_hashes_list, $sql_result));
$out = array(
'files_sent_counter' => 0
);
if ( ! empty($not_sent_files_intersection)) {
foreach ($not_sent_files_intersection as $fast_hash) {
$result = spbc_scanner_file_send(true, $fast_hash);
if ( ! empty($result['error'])) {
$file_info = spbc_scanner_get_file_by_id($fast_hash);
$file_path = isset($file_info['path']) ? $file_info['path'] : 'UNKNOWN_FILE';
$out['error'] = 'Some files where not updated.';
$out['error_detail'][] = array(
'file_path' => $file_path,
'error' => $result['error'],
);
}
$out['files_sent_counter']++;
}
} else {
$out['error'] = 'All the files have been already sent.';
}
return $out;
}
function spbc_scanner_get_files_by_category($status)
{
global $wpdb;
$ids = array();
switch ($status) {
case 'critical':
$res = $wpdb->get_results('SELECT fast_hash from ' . SPBC_TBL_SCAN_FILES . ' WHERE severity = "CRITICAL" AND status <> "QUARANTINED"');
break;
case 'suspicious':
$res = $wpdb->get_results('SELECT fast_hash from ' . SPBC_TBL_SCAN_FILES . ' WHERE status = "MODIFIED" AND severity <> "CRITICAL"');
break;
case 'unknown':
$res = $wpdb->get_results('SELECT fast_hash from ' . SPBC_TBL_SCAN_FILES . ' WHERE status <> "APROVED" AND source IS NULL AND path NOT LIKE "%wp-content%themes%" AND path NOT LIKE "%wp-content%plugins%" AND (severity <> "CRITICAL" OR severity IS NULL)');
break;
case 'approved':
$res = $wpdb->get_results('SELECT fast_hash from ' . SPBC_TBL_SCAN_FILES . ' WHERE status = "APROVED"');
break;
case 'analysis_log':
$res = $wpdb->get_results('SELECT fast_hash from ' . SPBC_TBL_SCAN_FILES . ' WHERE last_sent IS NOT NULL');
break;
}
foreach ($res as $tmp) {
$ids[] = $tmp->fast_hash;
}
return $ids;
}
function spbc_scanner_file_disapprove($direct_call = false, $file_id = null)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $spbc, $wpdb;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT path, full_hash, previous_state
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_readable($root_path . $file_info['path'])) {
// Getting file && API call
$md5 = md5_file($root_path . $file_info['path']);
if ($md5) {
$previous = json_decode($file_info['previous_state'], true);
$wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'status' => $previous['status'],
'severity' => $previous['severity'],
'real_full_hash' => $md5,
),
array('fast_hash' => $file_id),
array('%s', '%s', '%s'),
array('%s')
);
if ($sql_result !== false) {
$output = array('success' => true);
} else {
$output = array('error' => 'DB_COULDNT_UPDATE_ROW_APPROVE');
}
} else {
$output = array('error' => 'FILE_COULDNT_MD5');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_page_view($direct_call = false, $page_url = false)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $spbc, $wpdb;
$page_url = $direct_call
? $page_url
: Post::get('page_url');
$page_content = HTTP::getContentFromURL($page_url);
if ( ! empty($page_content)) {
// Getting signatures
$check_list = array('redirects', 'dbd', 'signatures_js', 'signatures_html');
if ($spbc->settings['scanner__frontend_analysis__csrf']) {
$check_list[] = 'csrf';
}
$fe_scanner = new FrontendScan($check_list);
$recheck_res = $fe_scanner->setHomeUrl(get_option('home'))
->setExceptUrls(CSV::parseNSV($spbc->settings['scanner__frontend_analysis__domains_exclusions']))
->setSignatures($wpdb->get_results('SELECT * FROM ' . SPBC_TBL_SCAN_SIGNATURES, ARRAY_A))
->setContent($page_content)
->check()
->getResult();
if (count($recheck_res) === 0) {
// If the malware not more present
$page_id = $wpdb->get_var(
$wpdb->prepare(
'SELECT page_id'
. ' FROM ' . SPBC_TBL_SCAN_FRONTEND
. ' WHERE url = %s',
$page_url
)
);
delete_post_meta($page_id, '_spbc_frontend__last_checked');
delete_post_meta($page_id, 'spbc_frontend__last_checked');
$wpdb->query(
$wpdb->prepare(
'DELETE'
. ' FROM ' . SPBC_TBL_SCAN_FRONTEND
. ' WHERE url = %s',
$page_url
)
);
wp_send_json([
'success' => false,
'content' => esc_html__('The malware found earlier no longer present. The notice about the malware will be replaced from the results list.', 'security-malware-firewall'), // Content of the modal
'file_path' => esc_html__('The malware no longer found', 'security-malware-firewall') // Title of the modal
]);
}
$page_text = array();
// Getting file info.
$sql_result = $wpdb->get_results(
$wpdb->prepare(
'SELECT weak_spots'
. ' FROM ' . SPBC_TBL_SCAN_FRONTEND
. ' WHERE url = %s'
. ' LIMIT 1',
$page_url
),
ARRAY_A
);
$result = $sql_result[0];
foreach (preg_split("/((\r?\n)|(\r\n?))/", $page_content) as $line) {
$page_text[] = htmlspecialchars($line);
}
$output = array(
'success' => true,
'file' => $page_text,
'file_path' => $page_url,
'difference' => null,
'weak_spots' => $result['weak_spots']
);
} else {
$output = array('error' => 'FILE_TEXT_EMPTY');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
}
$red_line = '<span style=\"background: rgb(200,80,80);\">';
$red_line_end = '</span>';
$output['weak_spots'] = str_replace('__SPBCT_RED__', $red_line, $output['weak_spots']);
$output['weak_spots'] = str_replace('__SPBCT_RED_END__', $red_line_end, $output['weak_spots']);
wp_send_json($output);
}
function spbc_scanner_page_approve()
{
global $wpdb;
check_ajax_referer('spbc_secret_nonce', 'security');
$page_url = Post::get('page_url');
$page_id = (int) Post::get('page_id');
if ($page_url && filter_var($page_url, FILTER_VALIDATE_URL)) {
// Getting file info.
$sql = 'UPDATE ' . SPBC_TBL_SCAN_FRONTEND . ' SET approved = 1 WHERE url = %s';
$sql = $wpdb->prepare($sql, $page_url);
$wpdb->query($sql);
update_post_meta($page_id, '_spbc_frontend__approved', 1);
}
}
function spbc_scanner_file_view($direct_call = false, $file_id = null)
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $spbc, $wpdb;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
$file_path = $file_info['status'] == 'QUARANTINED' ? $file_info['q_path'] : $root_path . $file_info['path'];
if (file_exists($file_path)) {
if (is_readable($file_path)) {
// Getting file && API call
$file = file($file_path);
if ($file !== false && count($file)) {
$file_text = array();
for ($i = 0; isset($file[ $i ]); $i++) {
$file_text[ $i + 1 ] = htmlspecialchars($file[ $i ]);
$file_text[ $i + 1 ] = preg_replace("/[^\S]{4}/", " ", $file_text[ $i + 1 ]);
}
if ( ! empty($file_text)) {
$output = array(
'success' => true,
'file' => $file_text,
'file_path' => $file_path,
'difference' => $file_info['difference'],
'weak_spots' => $file_info['weak_spots']
);
} else {
$output = array('error' => 'FILE_TEXT_EMPTY');
}
} else {
$output = array('error' => 'FILE_EMPTY');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_compare($direct_call = false, $file_id = null, $_platform = 'wordpress')
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $wpdb, $wp_version;
$_cms_version = $wp_version;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT path, source_type, source, version, status, severity, weak_spots, difference
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_readable($root_path . $file_info['path'])) {
// Getting file && API call
$file = file($root_path . $file_info['path']);
if ($file !== false && count($file)) {
$file_text = array();
for ($i = 0; isset($file[ $i ]); $i++) {
$file_text[ $i + 1 ] = htmlspecialchars($file[ $i ]);
$file_text[ $i + 1 ] = preg_replace("/[^\S]{4}/", " ", $file_text[ $i + 1 ]);
}
if ( ! empty($file_text)) {
$file_original = Scanner\Helper::getOriginalFile($file_info);
if ( $file_original && is_string($file_original) ) {
$file_original = explode("\n", $file_original);
for ($i = 0; isset($file_original[ $i ]); $i++) {
$file_original_text[ $i + 1 ] = htmlspecialchars($file_original[ $i ]);
$file_original_text[ $i + 1 ] = preg_replace("/[^\S]{4}/", " ", $file_original_text[ $i + 1 ]);
}
if ( ! empty($file_original_text)) {
$output = array(
'success' => true,
'file' => $file_text,
'file_original' => $file_original_text,
'file_path' => $root_path . $file_info['path'],
// 'weak_spots' => $file_info['weak_spots'],
'difference' => Scanner\Helper::getDifferenceFromOriginal($root_path, $file_info, $file_original)
);
} else {
$output = array('error' => 'FILE_ORIGINAL_TEXT_EMPTY');
}
} else {
$output = array('error' => 'GET_FILE_REMOTE_FAILED');
}
} else {
$output = array('error' => 'FILE_TEXT_EMPTY');
}
} else {
$output = array('error' => 'FILE_EMPTY');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_replace($direct_call = false, $file_id = null, $_platform = 'wordpress')
{
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$time_start = microtime(true);
global $wpdb;
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT path, source_type, source, version, status, severity, source_type
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_writable($root_path . $file_info['path'])) {
// Getting file && API call
$original_file = Scanner\Helper::getOriginalFile($file_info);
if ($original_file && !isset($original_file['error'])) {
$file_desc = fopen($root_path . $file_info['path'], 'w');
if ($file_desc && is_string($original_file)) {
$res_fwrite = fwrite($file_desc, $original_file);
if ($res_fwrite) {
fclose($file_desc);
$db_result = $wpdb->query(
'DELETE FROM ' . SPBC_TBL_SCAN_FILES
. ' WHERE fast_hash = "' . $file_id . '";'
);
if ($db_result) {
$output = array('success' => true,);
} else {
$output = array('error' => 'FILE_DB_DELETE_FAIL');
}
} else {
$output = array('error' => 'FILE_COULDNT_WRITE');
}
} else {
$output = array('error' => 'FILE_COULDNT_OPEN');
}
} else {
$output = array('error' => 'GET_FILE_FAILED');
}
} else {
$output = array('error' => 'FILE_NOT_WRITABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
$exec_time = round(microtime(true) - $time_start);
$output['exec_time'] = $exec_time;
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_quarantine($direct_call = false, $file_id = null)
{
global $wpdb, $spbc;
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($root_path . $file_info['path'])) {
if (is_writable($root_path . $file_info['path'])) {
$q_path = SPBC_PLUGIN_DIR . 'quarantine/'
. str_replace('/', '__', str_replace('\\', '__', $file_info['path'])) . '___'
. md5($file_info['path'] . rand(0, 99999999)) . '.punished';
if ( ! is_dir(SPBC_PLUGIN_DIR . 'quarantine/')) {
mkdir(SPBC_PLUGIN_DIR . 'quarantine/');
}
if (copy($root_path . $file_info['path'], $q_path)) {
$result = $wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'status' => 'QUARANTINED',
'q_path' => $q_path,
//should be offset to use in date()
'q_time' => current_time('timestamp'),
'previous_state' => json_encode(array(
'status' => $file_info['status'],
)),
),
array('full_hash' => $file_info['full_hash']),
array('%s', '%s', '%d', '%s'),
array('%s')
);
if ($result !== false && $result > 0) {
if (unlink($root_path . $file_info['path'])) {
$response_content = HTTP::getContentFromURL(get_option('home'));
$response_content_admin = HTTP::getContentFromURL(get_option('home') . '/wp-admin/');
$response_code = HTTP::getResponseCode(get_option('home'));
$response_code_admin = HTTP::getResponseCode(get_option('home') . '/wp-admin/');
if (
isset(
$response_content['error'],
$response_content_admin['error'],
$response_code['error'],
$response_code_admin['error']
) ||
(is_string($response_code) && preg_match('/5\d\d/', $response_code)) ||
(is_string($response_code_admin) && preg_match('/5\d\d/', $response_code_admin)) ||
spbc_search_page_errors($response_content) ||
spbc_search_page_errors($response_content_admin)
) {
$output = array('error' => 'WEBSITE_RESPONSE_BAD');
$result = spbc_scanner_file_quarantine__restore(true, $file_info['fast_hash']);
$output['error'] .= ! empty($result['error']) ? ' REVERT_FAILED ' . $result['error'] : ' REVERT_OK';
} else {
$output = array('success' => true,);
}
} else {
$output = array('error' => 'DELETE_FAILED');
}
} else {
$output = array('error' => 'UPDATE_TABLE_FAILED');
}
} else {
$output = array('error' => 'COPY_FAILED');
}
} else {
$output = array('error' => 'FILE_NOT_WRITABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
if ($direct_call) {
return spbc_humanize_output($output);
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_quarantine__restore($direct_call = false, $file_id = null)
{
global $wpdb;
if ( ! $direct_call) {
check_ajax_referer('spbc_secret_nonce', 'security');
}
$root_path = spbc_get_root_path();
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($file_info['q_path'])) {
if (is_writable($file_info['q_path'])) {
if (copy($file_info['q_path'], $root_path . $file_info['path'])) {
$previous = json_decode($file_info['previous_state'], true);
$result = $wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'status' => $previous['status'],
'q_path' => null,
'q_time' => null,
),
array('fast_hash' => $file_info['fast_hash']),
array('%s', '%s', '%d',),
array('%s')
);
if ($result !== false && $result > 0) {
if (unlink($file_info['q_path'])) {
$output = array('success' => true,);
} else {
$output = array('error' => 'DELETE_FAILED');
}
} else {
$output = array('error' => 'UPDATE_TABLE_FAILED');
}
} else {
$output = array('error' => 'COPY_FAILED');
}
} else {
$output = array('error' => 'FILE_NOT_WRITABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
function spbc_scanner_file_download($direct_call = false, $file_id = null)
{
global $wpdb;
$file_id = $direct_call
? $file_id
: Post::get('file_id', 'hash');
if ($file_id) {
// Getting file info.
$sql = 'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1';
$sql_result = $wpdb->get_results($sql, ARRAY_A);
$file_info = $sql_result[0];
if ( ! empty($file_info)) {
if (file_exists($file_info['q_path'])) {
if (is_readable($file_info['q_path'])) {
// Getting file && API call
$file_path = substr($file_info['q_path'], stripos($file_info['q_path'], 'wp-content'));
$file = HTTP::getContentFromURL(get_home_url() . '/' . $file_path);
if ($file !== false) {
$output = array(
'file_name' => preg_replace('/.*(\/|\\\\)(.*)/', '$2', $file_info['path']),
'file_content' => $file,
);
} else {
$output = array('error' => 'FILE_EMPTY');
}
} else {
$output = array('error' => 'FILE_NOT_READABLE');
}
} else {
$output = array('error' => 'FILE_NOT_EXISTS');
}
} else {
$output = array('error' => 'FILE_NOT_FOUND');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
if ($direct_call) {
return $output;
} else {
wp_send_json($output);
}
}
/**
* Delete file from analysis log
*/
function spbc_scanner_analysis_log_delete_from_log()
{
check_ajax_referer('spbc_secret_nonce', 'security');
global $wpdb;
$file_id = Post::get('file_id', 'hash');
$output = array('error' => false);
if ($file_id) {
$updated_rows = $wpdb->update(
SPBC_TBL_SCAN_FILES,
array(
'last_sent' => null,
'pscan_status' => null,
'pscan_processing_status' => null,
'pscan_pending_queue' => null,
'pscan_balls' => null,
'pscan_file_id' => null,
),
array(
'fast_hash' => $file_id
)
);
if ( ! $updated_rows) {
$output = array('error' => 'DB_ERROR');
}
} else {
$output = array('error' => 'WRONG_FILE_ID');
}
wp_send_json($output);
}
/**
* Replacing error codes by readable and translatable format.
* We have to add new error descriptions here future.
*
* @param $output_array
*
* @return array
*/
function spbc_humanize_output($output_array)
{
if (is_array($output_array) && array_key_exists('error', $output_array)) {
$errors_codes = array(
'WEBSITE_RESPONSE_BAD',
'REVERT_OK'
);
$errors_texts = array(
esc_html__('The requested action caused a website error.', 'security-malware-firewall'),
// WEBSITE_RESPONSE_BAD
esc_html__('The changes were reverted.', 'security-malware-firewall'),
// REVERT_OK
);
foreach ($output_array as $key => $item) {
$output_array[ $key ] = str_replace($errors_codes, $errors_texts, $item);
}
}
return $output_array;
}
function spbc_scanner_get_file_by_id($file_id)
{
global $wpdb;
$file_info = $wpdb->get_row(
'SELECT *
FROM ' . SPBC_TBL_SCAN_FILES . '
WHERE fast_hash = "' . $file_id . '"
LIMIT 1',
ARRAY_A
);
return $file_info ?: false;
}
/**
* Save scanner logs to pdf
*
* @param $direct_call
*
* @return array|void
*/
function spbc_scanner_save_to_pdf($direct_call = false)
{
if ( !$direct_call ) {
spbc_check_ajax_referer('spbc_secret_nonce', 'security');
}
$pdf = new Pdf();
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->drawScanCommonStatsTable();
$pdf->Ln();
$pdf->drawScanResultsOfScanType('heuristic_results');
$pdf->drawScanResultsOfScanType('signature_results');
$pdf->AddPage();
$pdf->drawFilesListByType('critical_files');
$pdf->Output();
}
function spbc_scanner_get_pdf_file_name($direct_call = false)
{
if ( !$direct_call ) {
spbc_check_ajax_referer('spbc_secret_nonce', 'security');
}
global $spbc;
wp_send_json_success('spbct-mscan-'
. preg_replace('/^http(s)?:\/\//', '', site_url())
. '-'
. date('M-d-Y', $spbc->data['scanner']['last_scan'])
. '.pdf');
}