<?php /** * Code related to the settings-scanner.php interface. * * PHP version 5 * * @category Library * @package Sucuri * @subpackage SucuriScanner * @author Daniel Cid <[email protected]> * @copyright 2010-2018 Sucuri Inc. * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2 * @link https://wordpress.org/plugins/sucuri-scanner */ if (!defined('SUCURISCAN_INIT') || SUCURISCAN_INIT !== true) { if (!headers_sent()) { /* Report invalid access if possible. */ header('HTTP/1.1 403 Forbidden'); } exit(1); } /** * Returns the HTML to configure the scanner. * * @category Library * @package Sucuri * @subpackage SucuriScanner * @author Daniel Cid <[email protected]> * @copyright 2010-2018 Sucuri Inc. * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2 * @link https://wordpress.org/plugins/sucuri-scanner */ class SucuriScanSettingsScanner extends SucuriScanSettings { /** * Renders a page with information about the cronjobs feature. * * @param bool $nonce True if the CSRF protection worked. * @return string Page with information about the cronjobs. */ public static function cronjobs($nonce) { $params = array( 'Cronjob.Schedules' => '', ); if ($nonce) { // Modify the scheduled tasks (run now, remove, re-schedule). $allowed_actions = array_keys(SucuriScanEvent::availableSchedules()); $allowed_actions[] = 'runnow'; /* execute in the next 10 seconds */ $allowed_actions[] = 'remove'; /* can be reinstalled automatically */ $allowed_actions = sprintf('(%s)', implode('|', $allowed_actions)); $cronjob_action = SucuriScanRequest::post(':cronjob_action', $allowed_actions); if ($cronjob_action) { $cronjobs = SucuriScanRequest::post(':cronjobs', '_array'); if (!empty($cronjobs)) { $total_tasks = count($cronjobs); if ($cronjob_action == 'runnow') { /* Force execution of the selected scheduled tasks. */ SucuriScanInterface::info( sprintf( __('%d tasks has been scheduled to run in the next ten seconds.', 'sucuri-scanner'), $total_tasks /* some cronjobs will be ignored */ ) ); SucuriScanEvent::reportNoticeEvent( sprintf( __('Force execution of scheduled tasks: (multiple entries): %s', 'sucuri-scanner'), @implode(',', $cronjobs) ) ); foreach ($cronjobs as $task_name) { wp_schedule_single_event(time() + 10, $task_name); } } elseif ($cronjob_action == 'remove' || $cronjob_action == '_oneoff') { /* Force deletion of the selected scheduled tasks. */ SucuriScanInterface::info( sprintf( __('%d scheduled tasks have been removed.', 'sucuri-scanner'), $total_tasks /* some cronjobs will be ignored */ ) ); SucuriScanEvent::reportNoticeEvent( sprintf( __('Delete scheduled tasks: (multiple entries): %s', 'sucuri-scanner'), @implode(',', $cronjobs) ) ); foreach ($cronjobs as $task_name) { wp_clear_scheduled_hook($task_name); } } else { SucuriScanInterface::info( sprintf( __('%d tasks has been re-scheduled to run <code>%s</code>.', 'sucuri-scanner'), $total_tasks, /* some cronjobs will be ignored */ $cronjob_action /* frequency to run cronjob */ ) ); SucuriScanEvent::reportNoticeEvent( sprintf( __('Re-configure scheduled tasks %s: (multiple entries): %s', 'sucuri-scanner'), $cronjob_action, @implode(',', $cronjobs) ) ); foreach ($cronjobs as $task_name) { $next_due = wp_next_scheduled($task_name); wp_schedule_event($next_due, $cronjob_action, $task_name); } } } else { SucuriScanInterface::error(__('No scheduled tasks were selected from the list.', 'sucuri-scanner')); } } } $available = SucuriScanEvent::availableSchedules(); /* Hardcode the first one to allow the immediate execution of the cronjob(s) */ $params['Cronjob.Schedules'] .= '<option value="runnow">' . __('Execute Now (in +10 seconds)', 'sucuri-scanner') . '</option>'; foreach ($available as $freq => $name) { $params['Cronjob.Schedules'] .= sprintf('<option value="%s">%s</option>', $freq, $name); } $hasSPL = SucuriScanFileInfo::isSplAvailable(); $params['NoSPL.Visibility'] = SucuriScanTemplate::visibility(!$hasSPL); return SucuriScanTemplate::getSection('settings-scanner-cronjobs', $params); } /** * Process the Ajax request to retrieve the list of cronjobs. * * @return void */ public static function cronjobsAjax() { if (SucuriScanRequest::post('form_action') !== 'get_cronjobs') { return; } $response = ''; $cronjobs = _get_cron_array(); foreach ($cronjobs as $timestamp => $cronhooks) { foreach ((array) $cronhooks as $hook => $events) { foreach ((array) $events as $key => $event) { if (empty($event['args'])) { $event['args'] = array('[]'); } $response .= SucuriScanTemplate::getSnippet( 'settings-scanner-cronjobs', array( 'Cronjob.Hook' => $hook, 'Cronjob.Schedule' => $event['schedule'], 'Cronjob.NextTime' => SucuriScan::datetime($timestamp), 'Cronjob.NextTimeHuman' => SucuriScan::humanTime($timestamp), 'Cronjob.Arguments' => json_encode($event['args']), ) ); } } } if (!$response) { $response = '<tr><td colspan="5">' . __('no data available', 'sucuri-scanner') . '</td></tr>'; } wp_send_json($response, 200); } /** * Returns the HTML for the folder scanner skipper. * * If the website has too many files it would be wise to force the plugin to * ignore some directories that are not relevant for the scanner. This includes * directories with media files like images, audio, videos, etc and directories * used to store cache data. * * @param bool $nonce True if the CSRF protection worked, false otherwise. * @return string HTML for the folder scanner skipper. */ public static function ignoreFolders($nonce) { $params = array(); $params['IgnoreScan.List'] = ''; if ($nonce) { $ign_ress = SucuriScanRequest::post(':ignorefolder'); $ign_dirs = SucuriScanRequest::post(':unignorefolders', '_array'); if ($ign_ress !== false && SucuriScanFSScanner::ignoreDirectory($ign_ress)) { SucuriScanInterface::info(__('Selected files have been successfully processed.', 'sucuri-scanner')); SucuriScanEvent::reportWarningEvent(sprintf(__('This directory will not be scanned: %s', 'sucuri-scanner'), $ign_ress)); } if ($ign_dirs !== false && is_array($ign_dirs) && !empty($ign_dirs)) { foreach ($ign_dirs as $dir) { SucuriScanFSScanner::unignoreDirectory($dir); } SucuriScanInterface::info(__('Selected files have been successfully processed.', 'sucuri-scanner')); SucuriScanEvent::reportNoticeEvent( __('Directories will be scanned: (multiple entries): ', 'sucuri-scanner') . @implode(',', $ign_dirs) /* all directories */ ); } } $ignored_dirs = SucuriScanFSScanner::getIgnoredDirectories(); foreach ($ignored_dirs['directories'] as $index => $folder) { $ts = $ignored_dirs['ignored_at_list'][$index]; $params['IgnoreScan.List'] .= SucuriScanTemplate::getSnippet( 'settings-scanner-ignore-folders', array( 'IgnoreScan.Directory' => $folder, 'IgnoreScan.IgnoredAt' => SucuriScan::datetime($ts), ) ); } if (empty($ignored_dirs['directories'])) { $params['IgnoreScan.List'] .= '<tr><td colspan="3">' . __('no data available', 'sucuri-scanner') . '</td></tr>'; } return SucuriScanTemplate::getSection('settings-scanner-ignore-folders', $params); } }