Changeset 978150
- Timestamp:
- 09/03/2014 07:42:03 PM (12 years ago)
- Location:
- sucuri-scanner/trunk
- Files:
-
- 1 added
- 8 edited
-
inc/css/sucuriscan-default-css.css (modified) (2 diffs)
-
inc/tpl/lastlogins-all.html.tpl (modified) (1 diff)
-
inc/tpl/lastlogins-loggedin.html.tpl (modified) (1 diff)
-
inc/tpl/monitoring-logs.html.tpl (modified) (1 diff)
-
inc/tpl/monitoring-logs.snippet.tpl (modified) (2 diffs)
-
inc/tpl/settings-general.html.tpl (modified) (8 diffs)
-
inc/tpl/settings-heartbeat.html.tpl (added)
-
inc/tpl/settings.html.tpl (modified) (2 diffs)
-
sucuri.php (modified) (53 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sucuri-scanner/trunk/inc/css/sucuriscan-default-css.css
r967131 r978150 182 182 .sucuriscan-monitoring-logs .sucuriscan-monitoring-date-form select + select + select{width:60px} 183 183 .sucuriscan-monitoring-logs .sucuriscan-target-date{font-size:12px;color:#999;margin-right:5px} 184 .sucuriscan-monitoring-logs .sucuriscan-denial-type{font-size:14px} 185 .sucuriscan-monitoring-logs .sucuriscan-denial-type-date{font-style:italic;color:#999} 184 186 /* Monitoring AccessLog Styles */ 185 187 .sucuriscan-request-summary{margin:-15px;margin-top:-3px} 186 .sucuriscan-request-summary ul{margin:0} 187 .sucuriscan-request-summary label, .sucuriscan-request-summary span{display:inline-block;font-size:14px} 188 .sucuriscan-request-summary label{width:200px;font-weight:bold} 189 .sucuriscan-request-summary span{max-width:395px;font-family:monospace;vertical-align:top;word-break:break-all} 188 .sucuriscan-request-summary td{font-size:14px} 189 .sucuriscan-request-summary tr td:first-child{font-weight:bold} 190 .sucuriscan-request-summary td+td{font-family:monospace;word-break:break-all} 190 191 /* Hardening Status */ 191 192 .sucuriscan-hstatus{position:relative;margin:0 -12px;padding:10px 12px;border:1px solid transparent} … … 220 221 .sucuriscan-maincontent .sucuriscan-settings{margin-top:0} 221 222 .sucuriscan-maincontent .sucuriscan-settings form{display:inline-block} 222 .sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{ min-width:220px}223 .sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{width:220px} 223 224 .sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0} 225 .sucuriscan-maincontent .sucuriscan-settings-heartbeat{} 224 226 .sucuriscan-maincontent .sucuriscan-wpcron-list{margin-top:0} 225 227 /* Responsive Styles */ -
sucuri-scanner/trunk/inc/tpl/lastlogins-all.html.tpl
r956731 r978150 4 4 <tr> 5 5 <th colspan="6" class="thead-with-button"> 6 <span>User last logins</span> 7 <span class="thead-topright-action sucuriscan-lastlogin-outof"> 8 %%SUCURI.UserList.Limit%% per page out of %%SUCURI.UserList.Total%% 6 <span>User last logins (%%SUCURI.UserList.Total%%)</span> 7 <span class="thead-topright-action"> 8 <form action="%%SUCURI.URL.Lastlogins%%" method="post"> 9 <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" /> 10 <button type="submit" name="sucuriscan_reset_lastlogins" class="button button-primary">Reset logs</button> 11 </form> 9 12 </span> 10 13 </th> -
sucuri-scanner/trunk/inc/tpl/lastlogins-loggedin.html.tpl
r956731 r978150 8 8 <th>ID</th> 9 9 <th>Username</th> 10 <th>Last Activity (GMT/UTC)</th>11 <th>Registered (GMT/UTC)</th>10 <th>Last Activity</th> 11 <th>Registered</th> 12 12 <th>IP Address</th> 13 13 <th> </th> -
sucuri-scanner/trunk/inc/tpl/monitoring-logs.html.tpl
r945045 r978150 46 46 47 47 <tr> 48 <th>Denial Type</th> 49 <th>Time</th> 50 <th>Remote Address</th> 48 <th width="250">Denial Type</th> 49 <th width="120">Remote Address</th> 51 50 <th>Request Path</th> 52 51 </tr> -
sucuri-scanner/trunk/inc/tpl/monitoring-logs.snippet.tpl
r939379 r978150 1 1 2 2 <tr class="%%SUCURI.AuditLog.CssClass%%"> 3 <td>%%SUCURI.AuditLog.SucuriBlockReason%%</td>4 3 <td> 5 <span class="sucuriscan-monospace" title="%%SUCURI.AuditLog.RequestDate%% %%SUCURI.AuditLog.RequestTime%% %%SUCURI.AuditLog.RequestTimezone%%"> 6 %%SUCURI.AuditLog.RequestTime%% %%SUCURI.AuditLog.RequestTimezone%% 7 </span> 4 <span class="sucuriscan-denial-type">%%SUCURI.AuditLog.SucuriBlockReason%%</span><br> 5 <span class="sucuriscan-denial-type-date">Date/Time: %%SUCURI.AuditLog.LocalRequestTime%%</span> 8 6 </td> 9 7 <td><span class="sucuriscan-monospace">%%SUCURI.AuditLog.RemoteAddr%%</span></td> … … 17 15 <div id="sucuriscan-reqsummary-%%SUCURI.AuditLog.Id%%" style="display:none"> 18 16 <div class="sucuriscan-request-summary"> 19 <ul class="sucuriscan-list-as-table"> 20 <li> 21 <label>Blocked Reason:</label> 22 <span>%%SUCURI.AuditLog.SucuriBlockReason%%</span> 23 </li> 24 <li> 25 <label>Remote Address:</label> 26 <span>%%SUCURI.AuditLog.RemoteAddr%%</span> 27 </li> 28 <li> 29 <label>Date/Time (Timezone)</label> 30 <span>%%SUCURI.AuditLog.RequestDate%% %%SUCURI.AuditLog.RequestTime%% (%%SUCURI.AuditLog.RequestTimezone%%)</span> 31 </li> 32 <li> 33 <label>Resource Path:</label> 34 <span>%%SUCURI.AuditLog.ResourcePath%%</span> 35 </li> 36 <li> 37 <label>Request Method:</label> 38 <span>%%SUCURI.AuditLog.RequestMethod%%</span> 39 </li> 40 <li> 41 <label>HTTP Protocol:</label> 42 <span>%%SUCURI.AuditLog.HttpProtocol%%</span> 43 </li> 44 <li> 45 <label>HTTP Status:</label> 46 <span>%%SUCURI.AuditLog.HttpStatus%% %%SUCURI.AuditLog.HttpStatusTitle%%</span> 47 </li> 48 <li> 49 <label>HTTP Bytes Sent:</label> 50 <span>%%SUCURI.AuditLog.HttpBytesSent%%</span> 51 </li> 52 <li> 53 <label>HTTP Referer:</label> 54 <span>%%SUCURI.AuditLog.HttpReferer%%</span> 55 </li> 56 <li> 57 <label>HTTP User Agent:</label> 58 <span>%%SUCURI.AuditLog.HttpUserAgent%%</span> 59 </li> 60 </ul> 17 <table class="wp-list-table widefat"> 18 <thead> 19 <tr> 20 <th width="200">Information</th> 21 <th> </th> 22 </tr> 23 </thead> 24 25 <tbody> 26 <tr class="alternate"> 27 <td>Blocked Reason</td> 28 <td>%%SUCURI.AuditLog.SucuriBlockReason%%</td> 29 </tr> 30 <tr> 31 <td>Remote Address</td> 32 <td>%%SUCURI.AuditLog.RemoteAddr%%</td> 33 </tr> 34 <tr class="alternate"> 35 <td>Date & Time (Local Time)</td> 36 <td>%%SUCURI.AuditLog.LocalRequestTime%%</td> 37 </tr> 38 <tr> 39 <td>Resource Path</td> 40 <td>%%SUCURI.AuditLog.ResourcePath%%</td> 41 </tr> 42 <tr class="alternate"> 43 <td>Request Method</td> 44 <td>%%SUCURI.AuditLog.RequestMethod%%</td> 45 </tr> 46 <tr> 47 <td>HTTP Protocol</td> 48 <td>%%SUCURI.AuditLog.HttpProtocol%%</td> 49 </tr> 50 <tr class="alternate"> 51 <td>HTTP Status</td> 52 <td>%%SUCURI.AuditLog.HttpStatus%% %%SUCURI.AuditLog.HttpStatusTitle%%</td> 53 </tr> 54 <tr> 55 <td>HTTP Bytes Sent</td> 56 <td>%%SUCURI.AuditLog.HttpBytesSent%%</td> 57 </tr> 58 <tr class="alternate"> 59 <td>HTTP Referer</td> 60 <td>%%SUCURI.AuditLog.HttpReferer%%</td> 61 </tr> 62 <tr> 63 <td>HTTP User Agent</td> 64 <td>%%SUCURI.AuditLog.HttpUserAgent%%</td> 65 </tr> 66 </tbody> 67 </table> 61 68 </div> 62 69 </div> -
sucuri-scanner/trunk/inc/tpl/settings-general.html.tpl
r965266 r978150 6 6 <tr> 7 7 <th colspan="3" class="thead-with-button"> 8 <span> PluginSettings</span>8 <span>General Settings</span> 9 9 <form action="%%SUCURI.URL.Settings%%" method="post" class="thead-topright-action"> 10 10 <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" /> … … 26 26 monitoring tool forever even if you remove the API key and generate it again. 27 27 </p> 28 29 <div class="sucuriscan-inline-alert-warning sucuriscan-%%SUCURI.InvalidDomainVisibility%%"> 30 <p> 31 Your domain <code>%%SUCURI.CleanDomain%%</code> does not seems to have a DNS 32 <code>A</code> record so it will be considered as <em>invalid</em> by the API 33 interface when you request the generation of a new key. Adding <code>www</code> 34 at the beginning of the domain name may fix this issue. 35 </p> 36 </div> 28 37 </td> 29 38 </tr> … … 108 117 109 118 <tr> 119 <td>API request timeout</td> 120 <td>%%SUCURI.RequestTimeout%%</td> 121 <td class="td-with-button"> 122 <form action="%%SUCURI.URL.Settings%%" method="post"> 123 <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" /> 124 <input type="text" name="sucuriscan_request_timeout" class="input-text" placeholder="Timeout in seconds..." /> 125 <button type="submit" class="button-primary">Change</button> 126 </form> 127 </td> 128 </tr> 129 130 <tr class="alternate"> 110 131 <td>Filesystem scanner</td> 111 132 <td>%%SUCURI.FsScannerStatus%%</td> … … 119 140 </tr> 120 141 121 <tr class="alternate">142 <tr> 122 143 <td>Scan modified files</td> 123 144 <td>%%SUCURI.ScanModfilesStatus%%</td> … … 131 152 </tr> 132 153 133 <tr >154 <tr class="alternate"> 134 155 <td>Integrity checking</td> 135 156 <td>%%SUCURI.ScanChecksumsStatus%%</td> … … 143 164 </tr> 144 165 145 <tr class="alternate">166 <tr> 146 167 <td>Last Scanning</td> 147 168 <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td> … … 154 175 </tr> 155 176 156 <tr >177 <tr class="alternate"> 157 178 <td>Scanning frequency</td> 158 179 <td>%%SUCURI.ScanningFrequency%%</td> … … 168 189 </tr> 169 190 170 <tr class=" alternatesucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">191 <tr class="sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%"> 171 192 <td>Scanning interface</td> 172 193 <td>%%SUCURI.ScanningInterface%%</td> -
sucuri-scanner/trunk/inc/tpl/settings.html.tpl
r956731 r978150 10 10 <li> 11 11 <a href="#" data-tabname="settings-ignorerules">Ignore Notifications</a> 12 </li> 13 <li> 14 <a href="#" data-tabname="settings-heartbeat">Heartbeat</a> 12 15 </li> 13 16 </ul> … … 25 28 %%SUCURI.Settings.IgnoreRules%% 26 29 </div> 30 31 <div id="sucuriscan-settings-heartbeat"> 32 %%SUCURI.Settings.Heartbeat%% 33 </div> 27 34 </div> 28 35 </div> -
sucuri-scanner/trunk/sucuri.php
r968714 r978150 320 320 add_action( $sucuriscan_admin_notice_name, 'SucuriScanInterface::setup_notice' ); 321 321 322 /** 323 * Heartbeat API 324 * 325 * Update the settings of the Heartbeat API according to the values set by an 326 * administrator. This tool may cause an increase in the CPU usage, a bad 327 * configuration may cause low account to run out of resources, but in better 328 * cases it may improve the performance of the site by reducing the quantity of 329 * requests sent to the server per session. 330 */ 331 add_filter( 'init', 'SucuriScanHeartbeat::register_script', 1 ); 332 add_filter( 'heartbeat_settings', 'SucuriScanHeartbeat::update_settings' ); 333 add_filter( 'heartbeat_send', 'SucuriScanHeartbeat::respond_to_send', 10, 3 ); 334 add_filter( 'heartbeat_received', 'SucuriScanHeartbeat::respond_to_received', 10, 3 ); 335 add_filter( 'heartbeat_nopriv_send', 'SucuriScanHeartbeat::respond_to_send', 10, 3 ); 336 add_filter( 'heartbeat_nopriv_received', 'SucuriScanHeartbeat::respond_to_received', 10, 3 ); 337 322 338 } 323 339 … … 573 589 574 590 /** 591 * Get the clean version of the current domain. 592 * 593 * @return string The domain of the current site. 594 */ 595 public static function get_domain(){ 596 if( function_exists('get_site_url') ){ 597 $site_url = get_site_url(); 598 } else { 599 if( !isset($_SERVER['HTTP_HOST']) ){ 600 $_SERVER['HTTP_HOST'] = 'localhost'; 601 } 602 603 $site_url = $_SERVER['HTTP_HOST']; 604 } 605 606 $pattern = '/([fhtps]+:\/\/)?([^:]+)(:[0-9:]+)?/'; 607 $domain_name = preg_replace( $pattern, '$2', $site_url ); 608 609 return $domain_name; 610 } 611 612 /** 575 613 * Check whether the site is behing the Sucuri CloudProxy network. 576 614 * … … 579 617 */ 580 618 public static function is_behind_cloudproxy( $verbose=FALSE ){ 581 if( isset($_SERVER['SERVER_NAME']) ){ 582 $http_host = preg_replace('/^(.*):[0-9]+/', '$1', $_SERVER['SERVER_NAME']); 583 } else { 584 $http_host = 'localhost'; 585 } 586 619 $http_host = self::get_domain(); 587 620 $host_by_name = @gethostbyname($http_host); 588 621 $host_by_addr = @gethostbyaddr($host_by_name); … … 599 632 600 633 return $status; 634 } 635 636 /** 637 * Get the email address set by the administrator to receive the notifications 638 * sent by the plugin, if the email is missing the WordPress email address is 639 * chosen by default. 640 * 641 * @return string The administrator email address. 642 */ 643 public static function get_site_email(){ 644 $email = get_option('admin_email'); 645 646 if( self::is_valid_email($email) ){ 647 return $email; 648 } 649 650 return FALSE; 651 } 652 653 /** 654 * Retrieve the date in localized format, based on timestamp. 655 * 656 * If the locale specifies the locale month and weekday, then the locale will 657 * take over the format for the date. If it isn't, then the date format string 658 * will be used instead. 659 * 660 * @param integer $timestamp Unix timestamp. 661 * @return string The date, translated if locale specifies it. 662 */ 663 public static function datetime( $timestamp=0 ){ 664 if( is_numeric($timestamp) && $timestamp > 0 ){ 665 $date_format = get_option('date_format'); 666 $time_format = get_option('time_format'); 667 $timezone_format = sprintf( '%s %s', $date_format, $time_format ); 668 669 return date_i18n( $timezone_format, $timestamp ); 670 } 671 672 return NULL; 601 673 } 602 674 … … 717 789 718 790 return $text; 791 } 792 793 /** 794 * Check whether an list is a multidimensional array or not. 795 * 796 * @param array $list An array or multidimensional array of different values. 797 * @return boolean TRUE if the list is multidimensional, FALSE otherwise. 798 */ 799 public static function is_multi_list( $list=array() ){ 800 if( !empty($list) ){ 801 foreach( $list as $item ){ 802 if( is_array($item) ){ 803 return TRUE; 804 } 805 } 806 } 807 808 return FALSE; 809 } 810 811 /** 812 * Join array elements with a string no matter if it is multidimensional. 813 * 814 * @param string $separator Character that will act as a separator, default to an empty string. 815 * @param array $list The array of strings to implode. 816 * @return string String of all the items in the list, with the separator between them. 817 */ 818 public static function implode( $separator='', $list=array() ){ 819 if( self::is_multi_list($list) ){ 820 $pieces = array(); 821 822 foreach( $list as $items ){ 823 $pieces[] = @implode( $separator, $items ); 824 } 825 826 $joined_pieces = '(' . implode( '), (', $pieces ) . ')'; 827 828 return $joined_pieces; 829 } else { 830 return implode( $separator, $list ); 831 } 719 832 } 720 833 … … 1678 1791 1679 1792 /** 1793 * Default values for the plugin options. 1794 * 1795 * @return array Default plugin option values. 1796 */ 1797 private static function get_default_option_values(){ 1798 $defaults = array( 1799 'sucuriscan_api_key' => FALSE, 1800 'sucuriscan_account' => '', 1801 'sucuriscan_fs_scanner' => 'enabled', 1802 'sucuriscan_scan_frequency' => 'hourly', 1803 'sucuriscan_scan_interface' => 'spl', 1804 'sucuriscan_scan_modfiles' => 'enabled', 1805 'sucuriscan_scan_checksums' => 'enabled', 1806 'sucuriscan_runtime' => 0, 1807 'sucuriscan_lastlogin_redirection' => 'enabled', 1808 'sucuriscan_notify_to' => '', 1809 'sucuriscan_emails_sent' => 0, 1810 'sucuriscan_emails_per_hour' => 5, 1811 'sucuriscan_last_email_at' => time(), 1812 'sucuriscan_prettify_mails' => 'enabled', 1813 'sucuriscan_notify_success_login' => 'enabled', 1814 'sucuriscan_notify_failed_login' => 'enabled', 1815 'sucuriscan_notify_post_publication' => 'enabled', 1816 'sucuriscan_notify_theme_editor' => 'enabled', 1817 'sucuriscan_maximum_failed_logins' => 30, 1818 'sucuriscan_ignored_events' => '', 1819 'sucuriscan_verify_ssl_cert' => 'true', 1820 'sucuriscan_request_timeout' => 90, 1821 'sucuriscan_heartbeat' => 'enabled', 1822 'sucuriscan_heartbeat_pulse' => 15, 1823 'sucuriscan_heartbeat_interval' => 'standard', 1824 'sucuriscan_heartbeat_autostart' => 'enabled', 1825 ); 1826 1827 return $defaults; 1828 } 1829 1830 /** 1831 * Retrieve the default values for some specific options. 1832 * 1833 * @param string|array $settings Either an array that will be complemented or a string with the name of the option. 1834 * @return string|array The default values for the specified options. 1835 */ 1836 private static function get_default_options( $settings='' ){ 1837 $default_options = self::get_default_option_values(); 1838 1839 // Use framework built-in function. 1840 if( function_exists('get_option') ){ 1841 $admin_email = get_option('admin_email'); 1842 $default_options['sucuriscan_account'] = $admin_email; 1843 $default_options['sucuriscan_notify_to'] = $admin_email; 1844 } 1845 1846 if( is_array($settings) ){ 1847 foreach( $default_options as $option_name => $option_value ){ 1848 if( !isset($settings[$option_name]) ){ 1849 $settings[$option_name] = $option_value; 1850 } 1851 } 1852 1853 return $settings; 1854 } 1855 1856 if( is_string($settings) ){ 1857 if( isset($default_options[$settings]) ){ 1858 return $default_options[$settings]; 1859 } 1860 } 1861 1862 return FALSE; 1863 } 1864 1865 /** 1680 1866 * Retrieve specific options from the database. 1681 1867 * … … 1830 2016 1831 2017 return $option_value; 1832 }1833 1834 /**1835 * Retrieve the default values for some specific options.1836 *1837 * @param string|array $settings Either an array that will be complemented or a string with the name of the option.1838 * @return string|array The default values for the specified options.1839 */1840 private static function get_default_options( $settings='' ){1841 $admin_email = '';1842 1843 // Use framework built-in function.1844 if( function_exists('get_option') ){1845 $admin_email = get_option('admin_email');1846 }1847 1848 $default_options = array(1849 'sucuriscan_api_key' => FALSE,1850 'sucuriscan_account' => $admin_email,1851 'sucuriscan_fs_scanner' => 'enabled',1852 'sucuriscan_scan_frequency' => 'hourly',1853 'sucuriscan_scan_interface' => 'spl',1854 'sucuriscan_scan_modfiles' => 'enabled',1855 'sucuriscan_scan_checksums' => 'enabled',1856 'sucuriscan_runtime' => 0,1857 'sucuriscan_lastlogin_redirection' => 'enabled',1858 'sucuriscan_notify_to' => $admin_email,1859 'sucuriscan_emails_sent' => 0,1860 'sucuriscan_emails_per_hour' => 5,1861 'sucuriscan_last_email_at' => time(),1862 'sucuriscan_prettify_mails' => 'enabled',1863 'sucuriscan_notify_success_login' => 'enabled',1864 'sucuriscan_notify_failed_login' => 'enabled',1865 'sucuriscan_notify_post_publication' => 'enabled',1866 'sucuriscan_notify_theme_editor' => 'enabled',1867 'sucuriscan_maximum_failed_logins' => 30,1868 'sucuriscan_ignored_events' => '',1869 'sucuriscan_verify_ssl_cert' => 'true',1870 );1871 1872 if( is_array($settings) ){1873 foreach( $default_options as $option_name => $option_value ){1874 if( !isset($settings[$option_name]) ){1875 $settings[$option_name] = $option_value;1876 }1877 }1878 1879 return $settings;1880 }1881 1882 if( is_string($settings) ){1883 if( isset($default_options[$settings]) ){1884 return $default_options[$settings];1885 }1886 }1887 1888 return FALSE;1889 2018 } 1890 2019 … … 1979 2108 1980 2109 return FALSE; 1981 }1982 1983 /**1984 * Get the email address set by the administrator to receive the notifications1985 * sent by the plugin, if the email is missing the WordPress email address is1986 * chosen by default.1987 *1988 * @return string The administrator email address.1989 */1990 public static function get_site_email(){1991 $email = self::get_option('admin_email');1992 1993 if( self::is_valid_email($email) ){1994 return $email;1995 }1996 1997 return FALSE;1998 }1999 2000 /**2001 * Get the clean version of the current domain.2002 *2003 * @return string The domain of the current site.2004 */2005 public static function get_domain(){2006 $http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';2007 $domain_name = preg_replace( '/^www\./', '', $http_host );2008 2009 return $domain_name;2010 2110 } 2011 2111 … … 2141 2241 if( $runtime > 0 ){ 2142 2242 if( $format ){ 2143 return date( 'd/M/Y H:i:s', $runtime);2243 return SucuriScan::datetime($runtime); 2144 2244 } 2145 2245 … … 2370 2470 } 2371 2471 2372 $title = s printf( 'Sucuri notification (%s)', str_replace('_', chr(32), $event));2472 $title = str_replace('_', chr(32), $event); 2373 2473 $mail_sent = SucuriScanMail::send_mail( $email, $title, $content, $email_params ); 2374 2474 … … 3114 3214 3115 3215 /** 3216 * Seconds before consider a HTTP request as timeout. 3217 * 3218 * @return integer Seconds to consider a HTTP request timeout. 3219 */ 3220 public static function request_timeout(){ 3221 return intval( self::get_option(':request_timeout') ); 3222 } 3223 3224 /** 3116 3225 * Generate an user-agent for the HTTP requests. 3117 3226 * … … 3146 3255 $req_args = array( 3147 3256 'method' => $method, 3148 'timeout' => 90,3257 'timeout' => self::request_timeout(), 3149 3258 'redirection' => 2, 3150 3259 'httpversion' => '1.0', … … 3219 3328 public static function set_plugin_key( $api_key='', $validate=FALSE ){ 3220 3329 if( $validate ){ 3221 if( !preg_match('/^ ([a-z0-9]{32})$/', $api_key) ){3330 if( !preg_match('/^[a-z0-9]{32}$/', $api_key) ){ 3222 3331 SucuriScanInterface::error( 'Invalid API key format' ); 3223 3332 return FALSE; … … 3602 3711 ); 3603 3712 3604 if( preg_match('/^ ([0-9]{4})\-([0-9]{2})\-([0-9]{2})$/', $date) ){3713 if( preg_match('/^[0-9]{4}(\-[0-9]{2}){2}$/', $date) ){ 3605 3714 $params['date'] = $date; 3606 3715 } … … 3896 4005 $headers = array(); 3897 4006 $subject = ucwords(strtolower($subject)); 3898 $wp_domain = SucuriScanOption::get_domain();4007 $wp_domain = self::get_domain(); 3899 4008 $force = FALSE; 3900 4009 $debug = FALSE; … … 3931 4040 if( $debug ){ die($message); } 3932 4041 4042 $subject = sprintf( 'Sucuri Alert, %s, %s', $wp_domain, $subject ); 4043 3933 4044 $email_sent = wp_mail( 3934 4045 $email, 3935 "Sucuri WP Notification: {$wp_domain} - {$subject}",4046 $subject, 3936 4047 $message, 3937 4048 $headers … … 4074 4185 $params['PageNonce'] = wp_create_nonce('sucuriscan_page_nonce'); 4075 4186 $params['PageStyleClass'] = isset($params['PageStyleClass']) ? $params['PageStyleClass'] : 'base'; 4076 $params['CleanDomain'] = SucuriScanOption::get_domain();4077 $params['AdminEmail'] = SucuriScanOption::get_site_email();4187 $params['CleanDomain'] = self::get_domain(); 4188 $params['AdminEmail'] = self::get_site_email(); 4078 4189 4079 4190 return $params; … … 4362 4473 4363 4474 return $html_links; 4475 } 4476 4477 } 4478 4479 /** 4480 * Heartbeat library. 4481 * 4482 * The purpose of the Heartbeat API is to simulate bidirectional connection 4483 * between the browser and the server. Initially it was used for autosave, post 4484 * locking and log-in expiration warning while a user is writing or editing. The 4485 * idea was to have an API that sends XHR (XML HTTP Request) requests to the 4486 * server every fifteen seconds and triggers events (or callbacks) on receiving 4487 * data. 4488 * 4489 * @see https://core.trac.wordpress.org/ticket/23216 4490 */ 4491 class SucuriScanHeartbeat extends SucuriScanOption { 4492 4493 /** 4494 * Stop execution of the heartbeat API in certain parts of the site. 4495 * 4496 * @return void 4497 */ 4498 public static function register_script(){ 4499 global $pagenow; 4500 4501 $status = SucuriScanOption::get_option(':heartbeat'); 4502 4503 // Enable heartbeat everywhere. 4504 if( $status == 'enabled' ){ /* do_nothing */ } 4505 4506 // Disable heartbeat everywhere. 4507 elseif( $status == 'disabled' ){ 4508 wp_deregister_script('heartbeat'); 4509 } 4510 4511 // Disable heartbeat only on the dashboard and home pages. 4512 elseif( 4513 $status == 'dashboard' 4514 && $pagenow == 'index.php' 4515 ){ 4516 wp_deregister_script('heartbeat'); 4517 } 4518 4519 // Disable heartbeat everywhere except in post edition. 4520 elseif( 4521 $status == 'addpost' 4522 && $pagenow != 'post.php' 4523 && $pagenow != 'post-new.php' 4524 ){ 4525 wp_deregister_script('heartbeat'); 4526 } 4527 } 4528 4529 /** 4530 * Update the settings of the Heartbeat API according to the values set by an 4531 * administrator. This tool may cause an increase in the CPU usage, a bad 4532 * configuration may cause low account to run out of resources, but in better 4533 * cases it may improve the performance of the site by reducing the quantity of 4534 * requests sent to the server per session. 4535 * 4536 * @param array $settings Heartbeat settings. 4537 * @return array Updated version of the heartbeat settings. 4538 */ 4539 public static function update_settings( $settings=array() ){ 4540 $pulse = SucuriScanOption::get_option(':heartbeat_pulse'); 4541 $autostart = SucuriScanOption::get_option(':heartbeat_autostart'); 4542 4543 if( $pulse < 15 || $pulse > 60 ){ 4544 SucuriScanOption::delete_option(':heartbeat_pulse'); 4545 $pulse = 15; 4546 } 4547 4548 $settings['interval'] = $pulse; 4549 $settings['autostart'] = ( $autostart == 'disabled' ? FALSE : TRUE ); 4550 4551 return $settings; 4552 } 4553 4554 /** 4555 * Respond to the browser according to the data received. 4556 * 4557 * @param array $response Response received. 4558 * @param array $data Data received from the beat. 4559 * @param string $screen_id Identifier of the screen the heartbeat occurred on. 4560 * @return array Response with new data. 4561 */ 4562 public static function respond_to_received( $response=array(), $data=array(), $screen_id='' ) { 4563 $interval = SucuriScanOption::get_option(':heartbeat_interval'); 4564 4565 if( 4566 $interval == 'slow' 4567 || $interval == 'fast' 4568 || $interval == 'standard' 4569 ){ 4570 $response['heartbeat_interval'] = $interval; 4571 } else { 4572 SucuriScanOption::delete_option(':heartbeat_interval'); 4573 } 4574 4575 return $response; 4576 } 4577 4578 /** 4579 * Respond to the browser according to the data sent. 4580 * 4581 * @param array $response Response sent. 4582 * @param string $screen_id Identifier of the screen the heartbeat occurred on. 4583 * @return array Response with new data. 4584 */ 4585 public static function respond_to_send( $response=array(), $screen_id='' ) { 4586 return $response; 4587 } 4588 4589 /** 4590 * Allowed values for the heartbeat status. 4591 * 4592 * @return array Allowed values for the heartbeat status. 4593 */ 4594 public static function statuses_allowed(){ 4595 return array( 4596 'enabled' => 'Enable everywhere', 4597 'disabled' => 'Disable everywhere', 4598 'dashboard' => 'Disable on dashboard page', 4599 'addpost' => 'Everywhere except post addition', 4600 ); 4601 } 4602 4603 /** 4604 * Allowed values for the heartbeat intervals. 4605 * 4606 * @return array Allowed values for the heartbeat intervals. 4607 */ 4608 public static function intervals_allowed(){ 4609 return array( 4610 'slow' => 'Slow interval', 4611 'fast' => 'Fast interval', 4612 'standard' => 'Standard interval', 4613 ); 4614 } 4615 4616 /** 4617 * Allowed values for the heartbeat pulses. 4618 * 4619 * @return array Allowed values for the heartbeat pulses. 4620 */ 4621 public static function pulses_allowed(){ 4622 $pulses = array(); 4623 4624 for( $i=15; $i<=60; $i++ ){ 4625 $pulses[$i] = sprintf( 'Run every %d seconds', $i ); 4626 } 4627 4628 return $pulses; 4364 4629 } 4365 4630 … … 4665 4930 // Will be TRUE only if the scanning results were retrieved from the cache. 4666 4931 $display_results = (bool) $res; 4667 $clean_domain = SucuriScan Option::get_domain();4932 $clean_domain = SucuriScan::get_domain(); 4668 4933 4669 4934 // If the results are not cached, then request a new scanning. … … 5141 5406 if( $clear_cache_resp ){ 5142 5407 if( isset($clear_cache_resp->messages[0]) ){ 5408 // Clear W3 Total Cache if it is installed. 5409 if( function_exists('w3tc_flush_all') ){ w3tc_flush_all(); } 5410 5143 5411 SucuriScanInterface::info($clear_cache_resp->messages[0]); 5144 5412 } else { … … 5315 5583 } 5316 5584 5317 $template_variables['AuditLogs.TargetDate'] = htmlentities($date);5585 $template_variables['AuditLogs.TargetDate'] = SucuriScan::escape($date); 5318 5586 $template_variables['AuditLogs.DateYears'] = sucuriscan_monitoring_dates('years', $date); 5319 5587 $template_variables['AuditLogs.DateMonths'] = sucuriscan_monitoring_dates('months', $date); … … 5338 5606 'request_time', 5339 5607 'request_timezone', 5608 'request_timestamp', 5609 'local_request_time', 5340 5610 'remote_addr', 5341 5611 'sucuri_block_reason', … … 5399 5669 if( isset($access_log->{$attr_name}) ){ 5400 5670 $attr_value = $access_log->{$attr_name}; 5671 5672 if( 5673 empty($attr_value) 5674 && $attr_name == 'sucuri_block_reason' 5675 ){ 5676 $attr_value = 'Unknown'; 5677 } 5401 5678 } 5402 5679 5403 $audit_log_snippet[$attr_title] = $attr_value; 5680 elseif( $attr_name == 'local_request_time' ){ 5681 $attr_value = SucuriScan::datetime($access_log->request_timestamp); 5682 } 5683 5684 $audit_log_snippet[$attr_title] = SucuriScan::escape($attr_value); 5404 5685 } 5405 5686 … … 5428 5709 if( !array_key_exists($access_log->sucuri_block_reason, $types) ){ 5429 5710 $denial_type_k = SucuriScan::human2var($access_log->sucuri_block_reason); 5430 $types[$denial_type_k] = $access_log->sucuri_block_reason; 5711 $denial_type_v = $access_log->sucuri_block_reason; 5712 if( empty($denial_type_v) ){ $denial_type_v = 'Unknown'; } 5713 $types[$denial_type_k] = $denial_type_v; 5431 5714 } 5432 5715 } … … 5735 6018 } 5736 6019 5737 SucuriScanInterface::info('Hardening reverted for upload directory <code>/wp-content/uploads/</code>');6020 SucuriScanInterface::info('Hardening reverted for upload directory.'); 5738 6021 } else { 5739 6022 SucuriScanInterface::error( … … 5769 6052 $cp = 1; 5770 6053 $upmsg = NULL; 5771 $htaccess_upload = ABSPATH . '/wp-content/.htaccess';6054 $htaccess_upload = WP_CONTENT_DIR . '/.htaccess'; 5772 6055 5773 6056 if( !is_readable($htaccess_upload) ){ … … 5790 6073 $upmsg = SucuriScanInterface::error('Unable to create <code>.htaccess</code> file, folder destination is not writable.'); 5791 6074 } else { 5792 $upmsg = SucuriScanInterface::info('Hardening applied successfully to content directory <code>/wp-content/</code>');6075 $upmsg = SucuriScanInterface::info('Hardening applied successfully to content directory.'); 5793 6076 $cp = 1; 5794 6077 } … … 5807 6090 } 5808 6091 5809 SucuriScanInterface::info('Hardening reverted for content directory <code>/wp-content/</code>');6092 SucuriScanInterface::info('Hardening reverted for content directory.'); 5810 6093 } else { 5811 6094 SucuriScanInterface::info( 5812 'File <code> /wp-content/.htaccess</code> does not exists or is not writable,5813 you will need to remove the following code manually from there:6095 'File <code>' . WP_CONTENT_DIR . '/.htaccess</code> does not exists or is not 6096 writable, you will need to remove the following code manually from there: 5814 6097 <code><Files *.php>deny from all</Files></code>' 5815 6098 ); … … 5820 6103 $description = 'This option blocks direct PHP access to any file inside wp-content. If you experience ' 5821 6104 . 'any issue after this with a theme or plugin in your site, like for example images not displaying, ' 5822 . 'remove the <code>.htaccess</code> file located at the <code>/wp-content/</code>directory.'6105 . 'remove the <code>.htaccess</code> file located in the content directory.' 5823 6106 . '</p><p><b>Note:</b> Many <em>(insecure)</em> themes and plugins use a PHP file in this directory ' 5824 6107 . 'to generate images like thumbnails and captcha codes, this is intentional so it is recommended ' … … 5870 6153 $upmsg = SucuriScanInterface::error('Unable to create <code>.htaccess</code> file, folder destination is not writable.'); 5871 6154 } else { 5872 $upmsg = SucuriScanInterface::info('Hardening applied successfully to library\'s directory <code>/wp-includes/</code>');6155 $upmsg = SucuriScanInterface::info('Hardening applied successfully to library\'s directory.'); 5873 6156 $cp = 1; 5874 6157 } … … 5888 6171 @file_put_contents($htaccess_upload, $htaccess_content, LOCK_EX); 5889 6172 } 5890 SucuriScanInterface::info('Hardening reverted for library\'s directory <code>/wp-includes/</code>');6173 SucuriScanInterface::info('Hardening reverted for library\'s directory.'); 5891 6174 } else { 5892 6175 SucuriScanInterface::error( … … 6338 6621 $snippet_data = array( 6339 6622 'AuditLog.CssClass' => $css_class, 6340 'AuditLog.DateTime' => date( 'd/M/Y H:i:s', $audit_log['timestamp']),6341 'AuditLog.Account' => $audit_log['account'],6342 'AuditLog.Message' => $audit_log['message'],6623 'AuditLog.DateTime' => SucuriScan::datetime($audit_log['timestamp']), 6624 'AuditLog.Account' => SucuriScan::escape($audit_log['account']), 6625 'AuditLog.Message' => SucuriScan::escape($audit_log['message']), 6343 6626 'AuditLog.Extra' => '', 6344 6627 ); … … 6349 6632 $snippet_data['AuditLog.Extra'] .= '<ul class="sucuriscan-list-as-table ' . $css_scrollable . '">'; 6350 6633 foreach( $audit_log['extra'] as $log_extra ){ 6351 $snippet_data['AuditLog.Extra'] .= '<li>' . $log_extra. '</li>';6634 $snippet_data['AuditLog.Extra'] .= '<li>' . SucuriScan::escape($log_extra) . '</li>'; 6352 6635 } 6353 6636 $snippet_data['AuditLog.Extra'] .= '</ul>'; … … 6659 6942 'ModifiedFiles.CheckSum' => $file_info['checksum'], 6660 6943 'ModifiedFiles.FilePath' => $file_path, 6661 'ModifiedFiles.DateTime' => $mod_date6944 'ModifiedFiles.DateTime' => SucuriScan::datetime($mod_date), 6662 6945 )); 6663 6946 $counter += 1; … … 6820 7103 foreach( $user_list as $user ){ 6821 7104 $user->user_registered_timestamp = strtotime($user->user_registered); 6822 $user->user_registered_formatted = date('D, M/Y H:i',$user->user_registered_timestamp);7105 $user->user_registered_formatted = SucuriScan::datetime($user->user_registered_timestamp); 6823 7106 $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate'; 6824 7107 … … 6979 7262 SucuriScanInterface::check_permissions(); 6980 7263 7264 // Reset the file with the last-logins logs. 7265 if( 7266 SucuriScanInterface::check_nonce() 7267 && SucuriScanRequest::post(':reset_lastlogins') !== FALSE 7268 ){ 7269 $file_path = sucuriscan_lastlogins_datastore_filepath(); 7270 7271 if( unlink($file_path) ){ 7272 sucuriscan_lastlogins_datastore_exists(); 7273 SucuriScanInterface::info( 'Last-Logins logs were reset successfully.' ); 7274 } else { 7275 SucuriScanInterface::error( 'Could not reset the last-logins logs.' ); 7276 } 7277 } 7278 6981 7279 // Page pseudo-variables initialization. 6982 7280 $template_variables = array( … … 7024 7322 $user_snippet['AdminUsers.NoLastLogins'] = 'hidden'; 7025 7323 $user_snippet['AdminUsers.NoLastLoginsTable'] = 'visible'; 7026 $user_snippet['AdminUsers.RegisteredAt'] = $admin->user_registered;7324 $user_snippet['AdminUsers.RegisteredAt'] = 'Unknown'; 7027 7325 $counter = 0; 7028 7326 7029 foreach( $admin->lastlogins as $lastlogin ){ 7327 foreach( $admin->lastlogins as $i => $lastlogin ){ 7328 if( $i == 0 ){ 7329 $user_snippet['AdminUsers.RegisteredAt'] = SucuriScan::datetime($lastlogin->user_registered_timestamp); 7330 } 7331 7030 7332 $css_class = ( $counter % 2 == 0 ) ? '' : 'alternate'; 7031 7333 $user_snippet['AdminUsers.LastLogins'] .= SucuriScanTemplate::get_snippet('lastlogins-admins-lastlogin', array( 7032 7334 'AdminUsers.RemoteAddr' => SucuriScan::escape($lastlogin->user_remoteaddr), 7033 'AdminUsers.Datetime' => SucuriScan:: escape($lastlogin->user_lastlogin),7335 'AdminUsers.Datetime' => SucuriScan::datetime($lastlogin->user_lastlogin_timestamp), 7034 7336 'AdminUsers.CssClass' => $css_class, 7035 7337 )); … … 7264 7566 if( preg_match('/^a:[0-9]+:.+/', $line) ){ 7265 7567 $last_login = @unserialize($line); 7568 $last_login['user_lastlogin_timestamp'] = strtotime($last_login['user_lastlogin']); 7569 $last_login['user_registered_timestamp'] = 0; 7266 7570 7267 7571 // Only administrators can see all login stats. … … 7284 7588 foreach( $user_account->data as $var_name=>$var_value ){ 7285 7589 $last_login[$var_name] = $var_value; 7590 7591 if( $var_name == 'user_registered' ){ 7592 $last_login['user_registered_timestamp'] = strtotime($var_value); 7593 } 7286 7594 } 7287 7595 } … … 7290 7598 $last_logins['entries'][] = (object) $last_login; 7291 7599 $parsed_lines += 1; 7600 } 7601 7602 else { 7603 $last_logins['total'] -= 1; 7292 7604 } 7293 7605 … … 7346 7658 $row = $last_logins['entries'][1]; 7347 7659 7348 $message_tpl = 'Last time you logged in was at <code>%s</code> from <code>%s</code> - <code>%s</code>'; 7349 $lastlogin_message = sprintf( $message_tpl, date('d/M/Y H:i'), $row->user_remoteaddr, $row->user_hostname ); 7660 $lastlogin_message = sprintf( 7661 'Last time you logged in was at <code>%s</code> from <code>%s</code> - <code>%s</code>', 7662 date('d/M/Y H:i'), $row->user_remoteaddr, $row->user_hostname 7663 ); 7350 7664 $lastlogin_message .= chr(32).'(<a href="'.SucuriScanTemplate::get_url('lastlogins').'">view all logs</a>)'; 7351 7665 SucuriScanInterface::info( $lastlogin_message ); … … 7377 7691 foreach( (array) $logged_in_users as $logged_in_user ){ 7378 7692 $counter += 1; 7379 $logged_in_user['last_activity_datetime'] = date('d/M/Y H:i',$logged_in_user['last_activity']);7380 $logged_in_user['user_registered_datetime'] = date('d/M/Y H:i', strtotime($logged_in_user['user_registered']));7693 $logged_in_user['last_activity_datetime'] = SucuriScan::datetime($logged_in_user['last_activity']); 7694 $logged_in_user['user_registered_datetime'] = SucuriScan::datetime( strtotime($logged_in_user['user_registered']) ); 7381 7695 7382 7696 $template_variables['LoggedInUsers.List'] .= SucuriScanTemplate::get_snippet('lastlogins-loggedin', array( … … 7585 7899 'FailedLogins.Username' => SucuriScan::escape($login_data['user_login']), 7586 7900 'FailedLogins.RemoteAddr' => SucuriScan::escape($login_data['remote_addr']), 7587 'FailedLogins.Datetime' => date('d/M/Y H:i',$login_data['attempt_time']),7901 'FailedLogins.Datetime' => SucuriScan::datetime($login_data['attempt_time']), 7588 7902 'FailedLogins.UserAgent' => SucuriScan::escape($login_data['user_agent']), 7589 7903 )); … … 7821 8135 'Settings.Notifications' => sucuriscan_settings_notifications(), 7822 8136 'Settings.IgnoreRules' => sucuriscan_settings_ignore_rules(), 8137 'Settings.Heartbeat' => sucuriscan_settings_heartbeat(), 7823 8138 ); 7824 8139 … … 7971 8286 } 7972 8287 8288 // Update the API request timeout. 8289 if( $request_timeout = SucuriScanRequest::post(':request_timeout', '[0-9]+') ){ 8290 SucuriScanOption::update_option(':request_timeout', $request_timeout); 8291 SucuriScanInterface::info( 'API request timeout set to <code>' . $request_timeout . '</code> seconds.' ); 8292 } 8293 7973 8294 // Update the notification settings. 7974 8295 if( SucuriScanRequest::post(':save_notification_settings') !== FALSE ){ … … 8029 8350 } 8030 8351 8352 // Update the settings for the heartbeat API. 8353 if( $heartbeat_status = SucuriScanRequest::post(':heartbeat_status') ){ 8354 $statuses_allowed = SucuriScanHeartbeat::statuses_allowed(); 8355 8356 if( array_key_exists($heartbeat_status, $statuses_allowed) ){ 8357 SucuriScanOption::update_option(':heartbeat', $heartbeat_status); 8358 SucuriScanInterface::info( 'Heartbeat status set to <code>' . $heartbeat_status . '</code>' ); 8359 } else { 8360 SucuriScanInterface::error( 'Heartbeat status not allowed.' ); 8361 } 8362 } 8363 8364 // Update the value of the heartbeat pulse. 8365 if( $heartbeat_pulse = SucuriScanRequest::post(':heartbeat_pulse') ){ 8366 $pulses_allowed = SucuriScanHeartbeat::pulses_allowed(); 8367 8368 if( array_key_exists($heartbeat_pulse, $pulses_allowed) ){ 8369 SucuriScanOption::update_option(':heartbeat_pulse', $heartbeat_pulse); 8370 SucuriScanInterface::info( 'Heartbeat pulse set to <code>' . $heartbeat_pulse . '</code> seconds.' ); 8371 } else { 8372 SucuriScanInterface::error( 'Heartbeat pulse not allowed.' ); 8373 } 8374 } 8375 8376 // Update the value of the heartbeat interval. 8377 if( $heartbeat_interval = SucuriScanRequest::post(':heartbeat_interval') ){ 8378 $intervals_allowed = SucuriScanHeartbeat::intervals_allowed(); 8379 8380 if( array_key_exists($heartbeat_interval, $intervals_allowed) ){ 8381 SucuriScanOption::update_option(':heartbeat_interval', $heartbeat_interval); 8382 SucuriScanInterface::info( 'Heartbeat interval set to <code>' . $heartbeat_interval . '</code>' ); 8383 } else { 8384 SucuriScanInterface::error( 'Heartbeat interval not allowed.' ); 8385 } 8386 } 8387 8388 // Enable or disable the auto-start execution of heartbeat. 8389 if( $heartbeat_autostart = SucuriScanRequest::post(':heartbeat_autostart', '(en|dis)able') ){ 8390 $action_d = $heartbeat_autostart . 'd'; 8391 SucuriScanOption::update_option(':heartbeat_autostart', $action_d); 8392 SucuriScanInterface::info( 'Heartbeat auto-start was <code>' . $action_d . '</code>' ); 8393 } 8031 8394 } 8032 8395 } … … 8082 8445 $runtime_scan_human = SucuriScanOption::get_filesystem_runtime(TRUE); 8083 8446 8447 // Check whether the domain name is valid or not. 8448 if( !$api_key ){ 8449 $clean_domain = SucuriScan::get_domain(); 8450 $domain_address = @gethostbyname($clean_domain); 8451 $invalid_domain = ( $domain_address == $clean_domain ) ? TRUE : FALSE; 8452 } 8453 8084 8454 // Generate the HTML code for the option list in the form select fields. 8085 8455 $scan_freq_options = SucuriScanTemplate::get_select_options( $sucuriscan_schedule_allowed, $scan_freq ); … … 8094 8464 'APIKey.ManualKeyFormVisibility' => SucuriScanTemplate::visibility($display_manual_key_form), 8095 8465 'APIKey.RemoveVisibility' => SucuriScanTemplate::visibility($api_key), 8466 'InvalidDomainVisibility' => SucuriScanTemplate::visibility($invalid_domain), 8096 8467 /* Filesystem scanner */ 8097 8468 'FsScannerStatus' => 'Enabled', … … 8125 8496 'VerifySSLCert' => 'Undefined', 8126 8497 'VerifySSLCertOptions' => $verify_ssl_cert_options, 8498 'RequestTimeout' => SucuriScanOption::get_option(':request_timeout') . ' seconds', 8127 8499 'ModalWhenAPIRegistered' => $api_registered_modal, 8128 8500 ); … … 8228 8600 if( array_key_exists($post_type, $ignored_events) ){ 8229 8601 $is_ignored_text = 'YES'; 8230 $was_ignored_at = @date('d/M/Y - H:i:s',$ignored_events[$post_type]);8602 $was_ignored_at = SucuriScan::datetime($ignored_events[$post_type]); 8231 8603 $is_ignored_class = 'danger'; 8232 8604 $button_action = 'remove'; … … 8258 8630 8259 8631 return SucuriScanTemplate::get_section('settings-ignorerules', $template_variables); 8632 } 8633 8634 /** 8635 * Read and parse the content of the heartbeat settings template. 8636 * 8637 * @return string Parsed HTML code for the ignored-rules settings panel. 8638 */ 8639 function sucuriscan_settings_heartbeat(){ 8640 // Current values set in the options table. 8641 $heartbeat_status = SucuriScanOption::get_option(':heartbeat'); 8642 $heartbeat_pulse = SucuriScanOption::get_option(':heartbeat_pulse'); 8643 $heartbeat_interval = SucuriScanOption::get_option(':heartbeat_interval'); 8644 $heartbeat_autostart = SucuriScanOption::get_option(':heartbeat_autostart'); 8645 8646 // Allowed values for each setting. 8647 $statuses_allowed = SucuriScanHeartbeat::statuses_allowed(); 8648 $pulses_allowed = SucuriScanHeartbeat::pulses_allowed(); 8649 $intervals_allowed = SucuriScanHeartbeat::intervals_allowed(); 8650 8651 // HTML select form fields. 8652 $heartbeat_options = SucuriScanTemplate::get_select_options( $statuses_allowed, $heartbeat_status ); 8653 $heartbeat_pulse_options = SucuriScanTemplate::get_select_options( $pulses_allowed, $heartbeat_pulse ); 8654 $heartbeat_interval_options = SucuriScanTemplate::get_select_options( $intervals_allowed, $heartbeat_interval ); 8655 8656 $template_variables = array( 8657 'HeartbeatStatus' => 'Undefined', 8658 'HeartbeatPulse' => 'Undefined', 8659 'HeartbeatInterval' => 'Undefined', 8660 /* Heartbeat Options. */ 8661 'HeartbeatStatusOptions' => $heartbeat_options, 8662 'HeartbeatPulseOptions' => $heartbeat_pulse_options, 8663 'HeartbeatIntervalOptions' => $heartbeat_interval_options, 8664 /* Heartbeat Auto-Start. */ 8665 'HeartbeatAutostart' => 'Enabled', 8666 'HeartbeatAutostartSwitchText' => 'Disable', 8667 'HeartbeatAutostartSwitchValue' => 'disable', 8668 'HeartbeatAutostartSwitchCssClass' => 'button-danger', 8669 ); 8670 8671 if( array_key_exists($heartbeat_status, $statuses_allowed) ){ 8672 $template_variables['HeartbeatStatus'] = $statuses_allowed[$heartbeat_status]; 8673 } 8674 8675 if( array_key_exists($heartbeat_pulse, $pulses_allowed) ){ 8676 $template_variables['HeartbeatPulse'] = $pulses_allowed[$heartbeat_pulse]; 8677 } 8678 8679 if( array_key_exists($heartbeat_interval, $intervals_allowed) ){ 8680 $template_variables['HeartbeatInterval'] = $intervals_allowed[$heartbeat_interval]; 8681 } 8682 8683 if( $heartbeat_autostart == 'disabled' ){ 8684 $template_variables['HeartbeatAutostart'] = 'Disabled'; 8685 $template_variables['HeartbeatAutostartSwitchText'] = 'Enable'; 8686 $template_variables['HeartbeatAutostartSwitchValue'] = 'enable'; 8687 $template_variables['HeartbeatAutostartSwitchCssClass'] = 'button-success'; 8688 } 8689 8690 return SucuriScanTemplate::get_section('settings-heartbeat', $template_variables); 8260 8691 } 8261 8692 … … 8497 8928 $cronjobs = _get_cron_array(); 8498 8929 $schedules = wp_get_schedules(); 8499 $date_format = _x('M j, Y - H:i', 'Publish box date format', 'cron-view' );8500 8930 $counter = 0; 8501 8931 … … 8503 8933 foreach( (array) $cronhooks as $hook => $events ){ 8504 8934 foreach( (array) $events as $key => $event ){ 8935 if( empty($event['args']) ){ 8936 $event['args'] = array( '<em>empty</em>' ); 8937 } 8938 8505 8939 $template_variables['Cronjobs.Total'] += 1; 8506 8940 $template_variables['Cronjobs.List'] .= SucuriScanTemplate::get_snippet('infosys-cronjobs', array( 8507 8941 'Cronjob.Hook' => $hook, 8508 8942 'Cronjob.Schedule' => $event['schedule'], 8509 'Cronjob.NextTime' => date_i18n($date_format,$timestamp),8510 'Cronjob.Arguments' => !empty($event['args']) ? implode(', ', $event['args']) : '<em>empty</em>',8943 'Cronjob.NextTime' => SucuriScan::datetime($timestamp), 8944 'Cronjob.Arguments' => SucuriScan::implode(', ', $event['args']), 8511 8945 'Cronjob.CssClass' => ( $counter % 2 == 0 ) ? '' : 'alternate', 8512 8946 ));
Note: See TracChangeset
for help on using the changeset viewer.