share
9 years ago
.htaccess
11 years ago
anti_malware.php
5 years ago
class-api.php
4 weeks ago
class-centralised-logging.php
4 weeks ago
class-coupon.php
7 months ago
class-email-sodium.php
4 weeks ago
class-firewall-log.php
4 weeks ago
class-helpers.php
9 months ago
class-import-export.php
5 months ago
class-ip.php
5 months ago
class-nfw-database.php
7 months ago
class-plugin-upgrade.php
4 weeks ago
class-security-updates.php
4 weeks ago
class-session.php
4 weeks ago
class_mail.php
4 weeks ago
firewall.php
4 weeks ago
fw_fileguard.php
5 months ago
fw_livelog.php
1 year ago
help.php
4 weeks ago
helpers.php
4 weeks ago
i18n-extra.php
4 weeks ago
i18n.php
1 year ago
index.html
13 years ago
init_update.php
2 years ago
install.php
1 year ago
install_default.php
4 weeks ago
loader.php
7 months ago
mail_template_firewall.php
1 year ago
mail_template_plugin.php
4 weeks ago
scheduled_tasks.php
3 years ago
settings_dashboard.php
4 weeks ago
settings_dashboard_about.php
4 weeks ago
settings_dashboard_statistics.php
2 months ago
settings_event_notifications.php
4 weeks ago
settings_events.php
2 months ago
settings_firewall_options.php
2 months ago
settings_firewall_policies.php
4 weeks ago
settings_login_protection.php
2 months ago
settings_logs.php
4 weeks ago
settings_logs_firewall_log.php
4 weeks ago
settings_logs_live_log.php
2 months ago
settings_monitoring.php
4 weeks ago
settings_monitoring_file_check.php
2 months ago
settings_monitoring_file_guard.php
2 months ago
settings_network.php
2 months ago
settings_security_rules.php
2 months ago
settings_security_rules_editor.php
4 weeks ago
settings_security_rules_update.php
4 weeks ago
sign.pub
7 years ago
thickbox.php
4 years ago
widget.php
3 years ago
wpplus.php
5 months ago
settings_monitoring_file_check.php
813 lines
| 1 | <?php |
| 2 | /* |
| 3 | +=====================================================================+ |
| 4 | | _ _ _ _ _____ _ _ _ | |
| 5 | | | \ | (_)_ __ (_) __ _| ___(_)_ __ _____ ____ _| | | | |
| 6 | | | \| | | '_ \ | |/ _` | |_ | | '__/ _ \ \ /\ / / _` | | | | |
| 7 | | | |\ | | | | || | (_| | _| | | | | __/\ V V / (_| | | | | |
| 8 | | |_| \_|_|_| |_|/ |\__,_|_| |_|_| \___| \_/\_/ \__,_|_|_| | |
| 9 | | |__/ | |
| 10 | | (c) NinTechNet Limited ~ https://nintechnet.com/ | |
| 11 | +=====================================================================+ |
| 12 | */ |
| 13 | |
| 14 | if (! defined('NFW_ENGINE_VERSION') ) { |
| 15 | die('Forbidden'); |
| 16 | } |
| 17 | |
| 18 | $log_dir = NFW_LOG_DIR . '/nfwlog/cache/'; |
| 19 | $nfmon_snapshot = $log_dir . 'nfilecheck_snapshot.php'; |
| 20 | $nfmon_diff = $log_dir . 'nfilecheck_diff.php'; |
| 21 | $err = ''; |
| 22 | $success = ''; |
| 23 | |
| 24 | // Scheduled scan ? |
| 25 | if (defined('NFSCANDO') ) { |
| 26 | |
| 27 | $snapproc = nf_fc_metrics('start'); |
| 28 | $err = nf_sub_monitoring_scan($nfmon_snapshot, $nfmon_diff ); |
| 29 | if (! empty( $err ) ) { |
| 30 | nfw_log_error( $err ); |
| 31 | } |
| 32 | $nfw_options = nfw_get_option('nfw_options'); |
| 33 | if (empty($nfw_options['enabled']) ) { return; } |
| 34 | $nfw_options['snapproc'] = nf_fc_metrics('stop', $snapproc ); |
| 35 | nfw_update_option('nfw_options', $nfw_options); |
| 36 | |
| 37 | // Changes detected : |
| 38 | if (! $err && file_exists($nfmon_diff) ) { |
| 39 | nf_scan_email($nfmon_diff, $log_dir); |
| 40 | // No changes detected : |
| 41 | } else { |
| 42 | // Always send a report after a scan ? |
| 43 | if (! empty($nfw_options['report_scan']) ) { |
| 44 | nf_scan_email(0, 0); |
| 45 | } |
| 46 | } |
| 47 | return; |
| 48 | } |
| 49 | |
| 50 | // Block immediately if user is not allowed : |
| 51 | nf_not_allowed( 'block', __LINE__ ); |
| 52 | |
| 53 | if (! empty($_REQUEST['nfw_act'])) { |
| 54 | if ( empty($_POST['nfwnonce']) || ! wp_verify_nonce($_POST['nfwnonce'], 'filecheck_save') ) { |
| 55 | wp_nonce_ays('filecheck_save'); |
| 56 | } |
| 57 | if ( $_REQUEST['nfw_act'] == 'create') { |
| 58 | if (! $err = nf_sub_monitoring_create($nfmon_snapshot) ) { |
| 59 | $success = __('Snapshot successfully created.', 'ninjafirewall'); |
| 60 | if (file_exists($nfmon_diff) ) { |
| 61 | unlink($nfmon_diff); |
| 62 | } |
| 63 | } |
| 64 | } elseif ( $_REQUEST['nfw_act'] == 'delete') { |
| 65 | // Delete de current snapshot file : |
| 66 | if (file_exists($nfmon_snapshot) ) { |
| 67 | unlink ($nfmon_snapshot); |
| 68 | $success = __('Snapshot file successfully deleted.', 'ninjafirewall'); |
| 69 | // Remove old diff file as well : |
| 70 | if ( file_exists($nfmon_diff . '.php') ) { |
| 71 | unlink($nfmon_diff . '.php'); |
| 72 | } |
| 73 | // Clear scheduled scan (if any) and its options : |
| 74 | if ( wp_next_scheduled('nfscanevent') ) { |
| 75 | wp_clear_scheduled_hook('nfscanevent'); |
| 76 | } |
| 77 | $nfw_options = nfw_get_option('nfw_options'); |
| 78 | $nfw_options['report_scan'] = 0; |
| 79 | $nfw_options['sched_scan'] = 0; |
| 80 | nfw_update_option('nfw_options', $nfw_options); |
| 81 | } |
| 82 | } elseif ( $_REQUEST['nfw_act'] == 'scan') { |
| 83 | // Scan disk for changes : |
| 84 | if (! file_exists($nfmon_snapshot) ) { |
| 85 | $err = __('You must create a snapshot first.', 'ninjafirewall'); |
| 86 | } else { |
| 87 | |
| 88 | $snapproc = nf_fc_metrics('start'); |
| 89 | $err = nf_sub_monitoring_scan($nfmon_snapshot, $nfmon_diff); |
| 90 | if (! empty( $err ) ) { |
| 91 | nfw_log_error( $err ); |
| 92 | } |
| 93 | $nfw_options = nfw_get_option('nfw_options'); |
| 94 | $nfw_options['snapproc'] = nf_fc_metrics('stop', $snapproc ); |
| 95 | nfw_update_option('nfw_options', $nfw_options); |
| 96 | |
| 97 | if (! $err) { |
| 98 | if (file_exists($nfmon_diff) ) { |
| 99 | $err = __('NinjaFirewall detected that changes were made to your files.', 'ninjafirewall'); |
| 100 | $changes = 1; |
| 101 | } else { |
| 102 | $success = __('No changes detected.', 'ninjafirewall'); |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | } elseif ( $_REQUEST['nfw_act'] == 'scheduled') { |
| 107 | nf_scheduled_scan(); |
| 108 | $success = __('Your changes have been saved.', 'ninjafirewall'); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | $nfw_options = nfw_get_option('nfw_options'); |
| 113 | |
| 114 | if ( empty($nfw_options['snapdir']) ) { |
| 115 | $nfw_options['snapdir'] = ''; |
| 116 | if ( file_exists($nfmon_snapshot) ) { |
| 117 | unlink($nfmon_snapshot); |
| 118 | } |
| 119 | } |
| 120 | if (! isset($nfw_options['snapexclude']) ) { |
| 121 | $nfw_options['snapexclude'] = '/'. basename(WP_CONTENT_DIR) .'/nfwlog/'; |
| 122 | if ( is_dir( WP_CONTENT_DIR .'/ninjascanner/' ) ) { |
| 123 | $nfw_options['snapexclude'] .= ',/'. basename(WP_CONTENT_DIR) .'/ninjascanner/'; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | |
| 128 | if ( $err ) { |
| 129 | echo '<div class="error notice is-dismissible"><p>' . $err . '</p></div>'; |
| 130 | } elseif ( $success ) { |
| 131 | echo '<div class="updated notice is-dismissible"><p>' . $success . '</p></div>'; |
| 132 | } |
| 133 | |
| 134 | // If we don't have a snapshopt, offer to create one : |
| 135 | if (! file_exists($nfmon_snapshot) ) { |
| 136 | ?> |
| 137 | <div class="nfw-notice nfw-notice-orange"> |
| 138 | <p><?php _e('File Check lets you perform file integrity monitoring upon request or on a specific interval. To start, create a snapshot of your files by clicking the button below.', 'ninjafirewall' ) ?></p> |
| 139 | </div> |
| 140 | |
| 141 | <form method="post" name="monitor_form"> |
| 142 | <?php wp_nonce_field('filecheck_save', 'nfwnonce', 0); ?> |
| 143 | <table class="form-table nfw-table"> |
| 144 | <tr> |
| 145 | <th scope="row" class="row-med"><?php _e('Create a snapshot of all files stored in that directory', 'ninjafirewall') ?></th> |
| 146 | <td><input class="large-text" type="text" name="snapdir" value="<?php |
| 147 | if (! empty($nfw_options['snapdir']) ) { |
| 148 | echo htmlspecialchars($nfw_options['snapdir']); |
| 149 | } else { |
| 150 | echo htmlspecialchars(ABSPATH); |
| 151 | } |
| 152 | ?>" required /> |
| 153 | <p class="description"><?php printf( __('Default: %s', 'ninjafirewall'), htmlentities( rtrim( ABSPATH, '/\\ ' ) ) ) ?></p> |
| 154 | </td> |
| 155 | </tr> |
| 156 | |
| 157 | <tr> |
| 158 | <th scope="row" class="row-med"><?php _e('Exclude the following files/folders (optional)', 'ninjafirewall') ?></th> |
| 159 | <td><input class="large-text" type="text" name="snapexclude" value="<?php echo htmlentities($nfw_options['snapexclude']); ?>" placeholder="<?php _e('e.g.,', 'ninjafirewall') ?> /wp-content/nfwlog/" maxlength="255"><br /><p class="description"><?php _e('Full or partial case-sensitive string(s). Multiple values must be comma-separated', 'ninjafirewall') ?> (<code>,</code>).</p></td> |
| 160 | </tr> |
| 161 | |
| 162 | <tr> |
| 163 | <th scope="row" class="row-med"> </th> |
| 164 | <td> |
| 165 | <label><input type="checkbox" name="snapnoslink" value="1" checked="checked" /><?php _e('Do not follow symbolic links (default)', 'ninjafirewall') ?></label> |
| 166 | </td> |
| 167 | </tr> |
| 168 | |
| 169 | </table> |
| 170 | <input type="hidden" name="nfw_act" value="create" /> |
| 171 | <p><input type="submit" class="button-primary" value="<?php _e('Create Snapshot', 'ninjafirewall') ?>" /></p> |
| 172 | <input type="hidden" name="tab" value="filecheck" /> |
| 173 | </form> |
| 174 | <?php |
| 175 | return; |
| 176 | } |
| 177 | |
| 178 | // We have a snapshot : |
| 179 | $stat = stat($nfmon_snapshot); |
| 180 | $count = -2; |
| 181 | $fh = fopen($nfmon_snapshot, 'r'); |
| 182 | while (! feof($fh) ) { |
| 183 | fgets($fh); |
| 184 | ++$count; |
| 185 | } |
| 186 | fclose($fh); |
| 187 | // Look for new/mod/del files : |
| 188 | $res = $new_file = $del_file = $mod_file = array(); |
| 189 | // If no changes were detected, we display the last ones (if any) : |
| 190 | if (! file_exists($nfmon_diff) && file_exists($nfmon_diff . '.php') ) { |
| 191 | $nfmon_diff = $nfmon_diff . '.php'; |
| 192 | } |
| 193 | if (file_exists($nfmon_diff) ) { |
| 194 | $fh = fopen($nfmon_diff, 'r'); |
| 195 | while (! feof($fh) ) { |
| 196 | $res = explode('::', fgets($fh) ); |
| 197 | if ( empty($res[1]) ) { continue; } |
| 198 | // New file : |
| 199 | if ($res[1] == 'N') { |
| 200 | $s_tmp = explode(':', rtrim($res[2])); |
| 201 | $new_file[$res[0]] = $s_tmp[0] .':'. |
| 202 | $s_tmp[1] .':'. |
| 203 | $s_tmp[2] .':'. |
| 204 | $s_tmp[3] .':'. |
| 205 | date('Y-m-d H~i~s O', $s_tmp[4]) .':'. |
| 206 | date('Y-m-d H~i~s O', $s_tmp[5]); |
| 207 | // Deleted file : |
| 208 | } elseif ($res[1] == 'D') { |
| 209 | $del_file[$res[0]] = 1; |
| 210 | // Modified file: |
| 211 | } elseif ($res[1] == 'M') { |
| 212 | $s_tmp = explode(':', $res[2]); |
| 213 | $mod_file[$res[0]] = $s_tmp[0] .':'. |
| 214 | $s_tmp[1] .':'. |
| 215 | $s_tmp[2] .':'. |
| 216 | $s_tmp[3] .':'. |
| 217 | date('Y-m-d H~i~s O', $s_tmp[4]) .':'. |
| 218 | date('Y-m-d H~i~s O', $s_tmp[5]) .'::'; |
| 219 | $s_tmp = explode(':', rtrim($res[3])); |
| 220 | $mod_file[$res[0]] .= $s_tmp[0] .':'. |
| 221 | $s_tmp[1] .':'. |
| 222 | $s_tmp[2] .':'. |
| 223 | $s_tmp[3] .':'. |
| 224 | date('Y-m-d H~i~s O', $s_tmp[4]) .':'. |
| 225 | date('Y-m-d H~i~s O', $s_tmp[5]); |
| 226 | } |
| 227 | } |
| 228 | fclose($fh); |
| 229 | $mod = 1; |
| 230 | } else { |
| 231 | $mod = 0; |
| 232 | } |
| 233 | ?> |
| 234 | <table class="form-table nfw-table"> |
| 235 | <tr> |
| 236 | <th scope="row" class="row-med"><?php _e('Last snapshot', 'ninjafirewall') ?></th> |
| 237 | <td> |
| 238 | <p><?php printf( __('Created on: %s', 'ninjafirewall'), date_i18n('M d, Y @ H:i:s O', $stat['ctime'])); ?></p> |
| 239 | <p><?php printf( __('Total files: %s ', 'ninjafirewall'), number_format_i18n($count) ); ?></p> |
| 240 | |
| 241 | <p><?php _e('Directory:', 'ninjafirewall') ?> <code><?php echo htmlspecialchars($nfw_options['snapdir']) ?></code></p> |
| 242 | <?php |
| 243 | if (! empty($nfw_options['snapexclude']) ) { |
| 244 | $res = @explode(',', $nfw_options['snapexclude']); |
| 245 | echo '<p>' . __('Exclusion:', 'ninjafirewall') . ' '; |
| 246 | foreach ($res as $exc) { |
| 247 | echo '<code>' . htmlspecialchars($exc) . '</code> '; |
| 248 | } |
| 249 | echo '</p>'; |
| 250 | } |
| 251 | echo '<p>' . __('Symlinks:', 'ninjafirewall') . ' '; |
| 252 | if ( empty($nfw_options['snapnoslink']) ) { |
| 253 | echo __('follow', 'ninjafirewall'); |
| 254 | } else { |
| 255 | echo __('do not follow', 'ninjafirewall'); |
| 256 | } |
| 257 | echo '</p>'; |
| 258 | if (! empty($nfw_options['snapproc']) ) { |
| 259 | echo '<p>' . sprintf( __('Processing time: %s seconds', 'ninjafirewall'), $nfw_options['snapproc']) . '</p>'; |
| 260 | } |
| 261 | ?> |
| 262 | <form method="post"> |
| 263 | <?php wp_nonce_field('filecheck_save', 'nfwnonce', 0); ?> |
| 264 | <p><input type="submit" name="dlsnap" value="<?php _e('Download Snapshot', 'ninjafirewall') ?>" class="button-secondary" /> <input type="submit" class="button-secondary" onClick="return nfwjs_del_snapshot();" value="<?php _e('Delete Snapshot', 'ninjafirewall') ?>" /><input type="hidden" name="nfw_act" value="delete" /></p> |
| 265 | <input type="hidden" name="tab" value="filecheck" /> |
| 266 | </form> |
| 267 | </td> |
| 268 | </tr> |
| 269 | <tr> |
| 270 | <th scope="row" class="row-med"><?php _e('Last changes', 'ninjafirewall') ?></th> |
| 271 | <td> |
| 272 | |
| 273 | <?php |
| 274 | // Show info about last changes, if any : |
| 275 | if ($mod) { |
| 276 | ?> |
| 277 | <p><?php printf( __('New files: %s', 'ninjafirewall'), count($new_file) ) ?></p> |
| 278 | <p><?php printf( __('Deleted files: %s', 'ninjafirewall'), count($del_file) ) ?></p> |
| 279 | <p><?php printf( __('Modified files: %s', 'ninjafirewall'), count($mod_file) ) ?></p> |
| 280 | |
| 281 | <form method="post"> |
| 282 | <?php wp_nonce_field('filecheck_save', 'nfwnonce', 0); ?> |
| 283 | <p><input type="button" value="<?php _e('View Changes', 'ninjafirewall') ?>" onClick="nfwjs_show_changes();" class="button-secondary" id="vcbtn" <?php |
| 284 | if (! empty($changes)) { |
| 285 | echo 'disabled="disabled" '; |
| 286 | } |
| 287 | ?>/> <input type="submit" name="dlmods" value="<?php _e('Download Changes', 'ninjafirewall') ?>" class="button-secondary" /></p> |
| 288 | </form> |
| 289 | <br /> |
| 290 | <?php |
| 291 | if (empty($changes)) { |
| 292 | echo '<div id="changes_table" style="display:none">'; |
| 293 | } else { |
| 294 | echo '<div id="changes_table">'; |
| 295 | } |
| 296 | |
| 297 | echo '<table border="0" width="100%">'; |
| 298 | |
| 299 | $more_info = __('Click a file to get more info about it.', 'ninjafirewall'); |
| 300 | if ($new_file) { |
| 301 | echo '<tr><td>'; |
| 302 | echo __('New files:', 'ninjafirewall') . ' ' . count($new_file). '<br />'; |
| 303 | echo '<select id="select-1" name="sometext" multiple="multiple" style="min-width:100%;width:100%;height:150px" onchange="nfwjs_file_info(this.value, 1);">'; |
| 304 | foreach($new_file as $k => $v) { |
| 305 | echo '<option value="' . htmlspecialchars($v) . '" title="' . htmlspecialchars($k) . '">' . htmlspecialchars($k) . '</option>'; |
| 306 | } |
| 307 | echo'</select> |
| 308 | <p class="description">' . $more_info . '</p> |
| 309 | <table id="table_new" style="width:100%;background-color:#F7F7F7;border:solid 1px #DFDFDF;display:none;"> |
| 310 | <tr> |
| 311 | <th style="padding:2px;width:25%;">' . __('Size', 'ninjafirewall') .'</th> |
| 312 | <td style="padding:2px" id="new_size"></td> |
| 313 | </tr> |
| 314 | <tr> |
| 315 | <th style="padding:2px;width:25%;">' . __('Access', 'ninjafirewall') .'</th> |
| 316 | <td style="padding:2px" id="new_chmod"></td> |
| 317 | </tr> |
| 318 | <tr> |
| 319 | <th style="padding:2px;width:25%;">' . __('Uid / Gid', 'ninjafirewall') .'</th> |
| 320 | <td style="padding:2px" id="new_uidgid"></td> |
| 321 | </tr> |
| 322 | <tr> |
| 323 | <th style="padding:2px;width:25%;">' . __('Modify', 'ninjafirewall') .'</th> |
| 324 | <td style="padding:2px" id="new_mtime"></td> |
| 325 | </tr> |
| 326 | <tr> |
| 327 | <th style="padding:2px;width:25%;">' . __('Change', 'ninjafirewall') .'</th> |
| 328 | <td style="padding:2px" id="new_ctime"></td> |
| 329 | </tr> |
| 330 | </table> |
| 331 | </td></tr>'; |
| 332 | |
| 333 | } |
| 334 | if ($del_file) { |
| 335 | echo ' |
| 336 | <tr> |
| 337 | <td>' . __('Deleted files:', 'ninjafirewall') .' '. count($del_file). '<br />' . |
| 338 | '<select name="sometext" multiple="multiple" style="min-width:100%;width:100%;height:150px">'; |
| 339 | foreach($del_file as $k => $v) { |
| 340 | echo '<option title="' . htmlspecialchars($k) . '">' . htmlspecialchars($k) . '</option>'; |
| 341 | } |
| 342 | echo'</select> |
| 343 | </td> |
| 344 | </tr>'; |
| 345 | |
| 346 | } |
| 347 | if ($mod_file) { |
| 348 | echo ' |
| 349 | <tr> |
| 350 | <td>' . __('Modified files:', 'ninjafirewall') .' '. count($mod_file). '<br />' . |
| 351 | '<select id="select-2" name="sometext" multiple="multiple" style="min-width:100%;width:100%;height:150px" onchange="nfwjs_file_info(this.value, 2);">'; |
| 352 | foreach($mod_file as $k => $v) { |
| 353 | echo '<option value="' . htmlspecialchars($v) . '" title="' . htmlspecialchars($k) . '">' . htmlspecialchars($k) . '</option>'; |
| 354 | } |
| 355 | echo'</select> |
| 356 | <p class="description">' . $more_info . '</p> |
| 357 | <table id="table_mod" style="width:100%;background-color:#F7F7F7;border:solid 1px #DFDFDF;display:none;"> |
| 358 | <tr> |
| 359 | <th style="padding:2px;width:25%;"> </th> |
| 360 | <td style="padding:2px"><b>' . __('Old', 'ninjafirewall') .'</b></td> |
| 361 | <td style="padding:2px"><b>' . __('New', 'ninjafirewall') .'</b></td> |
| 362 | </tr> |
| 363 | <tr> |
| 364 | <th style="padding:2px;width:25%;">' . __('Size', 'ninjafirewall') .'</th> |
| 365 | <td style="padding:2px" id="mod_size"></td> |
| 366 | <td style="padding:2px" id="mod_size2"></td> |
| 367 | </tr> |
| 368 | <tr> |
| 369 | <th style="padding:2px;width:25%;">' . __('Access', 'ninjafirewall') .'</th> |
| 370 | <td style="padding:2px" id="mod_chmod"></td> |
| 371 | <td style="padding:2px" id="mod_chmod2"></td> |
| 372 | </tr> |
| 373 | <tr> |
| 374 | <th style="padding:2px;width:25%;">' . __('Uid / Gid', 'ninjafirewall') .'</th> |
| 375 | <td style="padding:2px" id="mod_uidgid"></td> |
| 376 | <td style="padding:2px" id="mod_uidgid2"></td> |
| 377 | </tr> |
| 378 | <tr> |
| 379 | <th style="padding:2px;width:25%;">' . __('Modify', 'ninjafirewall') .'</th> |
| 380 | <td style="padding:2px" id="mod_mtime"></td> |
| 381 | <td style="padding:2px" id="mod_mtime2"></td> |
| 382 | </tr> |
| 383 | <tr> |
| 384 | <th style="padding:2px;width:25%;">' . __('Change', 'ninjafirewall') .'</th> |
| 385 | <td style="padding:2px" id="mod_ctime"></td> |
| 386 | <td style="padding:2px" id="mod_ctime2"></td> |
| 387 | </tr> |
| 388 | </table> |
| 389 | </td> |
| 390 | </tr>'; |
| 391 | } |
| 392 | echo ' |
| 393 | </table> |
| 394 | </div> |
| 395 | |
| 396 | </td> |
| 397 | </tr> |
| 398 | </table>'; |
| 399 | } else { |
| 400 | echo __('None', 'ninjafirewall') . ' |
| 401 | </td> |
| 402 | </tr> |
| 403 | </table> |
| 404 | <br />'; |
| 405 | } |
| 406 | ?> |
| 407 | <form method="post"> |
| 408 | <?php wp_nonce_field('filecheck_save', 'nfwnonce', 0); ?> |
| 409 | <input type="hidden" name="nfw_act" value="scan" /> |
| 410 | <p><input type="submit" class="button-primary" value="<?php _e('Scan System For File Changes', 'ninjafirewall') ?> »" /></p> |
| 411 | <input type="hidden" name="tab" value="filecheck" /> |
| 412 | </form> |
| 413 | |
| 414 | <br /> |
| 415 | <br /> |
| 416 | <?php |
| 417 | if (! isset($nfw_options['sched_scan']) ) { |
| 418 | $sched_scan = 0; |
| 419 | } else { |
| 420 | $sched_scan = $nfw_options['sched_scan']; |
| 421 | } |
| 422 | if ( empty($nfw_options['report_scan']) ) { |
| 423 | $report_scan = 0; |
| 424 | } else { |
| 425 | $report_scan = 1; |
| 426 | } |
| 427 | ?> |
| 428 | <h3><?php _e('Options', 'ninjafirewall') ?></h3> |
| 429 | <form method="post"> |
| 430 | <?php |
| 431 | wp_nonce_field('filecheck_save', 'nfwnonce', 0); |
| 432 | // If WP cron is disabled, we simply warn the user : |
| 433 | if ( defined('DISABLE_WP_CRON') ) { |
| 434 | ?> |
| 435 | <p class="description" style="color:red"><?php printf( __('It seems that %s is set. Ensure you have another way to run WP-Cron, otherwise NinjaFirewall scheduled scans will not work.', 'ninjafirewall'), '<code>DISABLE_WP_CRON</code>' ) ?></p> |
| 436 | <?php |
| 437 | } |
| 438 | ?> |
| 439 | <table class="form-table nfw-table"> |
| 440 | <tr> |
| 441 | <th scope="row" class="row-med"><?php _e('Enable scheduled scans', 'ninjafirewall') ?></th> |
| 442 | <td> |
| 443 | <p><label><input type="radio" name="sched_scan" value="0"<?php checked($sched_scan, 0) ?> /><?php _e('No (default)', 'ninjafirewall') ?></label></p> |
| 444 | <p><label><input type="radio" name="sched_scan" value="1"<?php checked($sched_scan, 1) ?> /><?php _e('Hourly', 'ninjafirewall') ?></label></p> |
| 445 | <p><label><input type="radio" name="sched_scan" value="2"<?php checked($sched_scan, 2) ?> /><?php _e('Twicedaily', 'ninjafirewall') ?></label></p> |
| 446 | <p><label><input type="radio" name="sched_scan" value="3"<?php checked($sched_scan, 3) ?> /><?php _e('Daily', 'ninjafirewall') ?></label></p> |
| 447 | <?php |
| 448 | if ( $nextscan = wp_next_scheduled('nfscanevent') ) { |
| 449 | $sched = new DateTime( date('M d, Y H:i:s', $nextscan) ); |
| 450 | $now = new DateTime( date('M d, Y H:i:s', time() ) ); |
| 451 | $diff = $now->diff($sched); |
| 452 | ?> |
| 453 | <p class="description"><?php printf( __('Next scan will start in approximately %s day(s), %s hour(s), %s minute(s) and %s second(s).', 'ninjafirewall'), $diff->format('%a') % 7, $diff->format('%h'), $diff->format('%i'), $diff->format('%s') ) ?></p> |
| 454 | <?php |
| 455 | // Ensure that the scheduled scan time is in the future, |
| 456 | // not in the past, otherwise send a warning because wp-cron |
| 457 | // is obviously not working as expected : |
| 458 | if ( $nextscan < time() ) { |
| 459 | ?> |
| 460 | <p class="description" style="color:red"><?php _e('The next scheduled scan date is in the past! WordPress wp-cron may not be working or may have been disabled.', 'ninjafirewall'); ?></p> |
| 461 | <?php |
| 462 | } |
| 463 | } |
| 464 | ?> |
| 465 | </td> |
| 466 | </tr> |
| 467 | <tr> |
| 468 | <th scope="row" class="row-med"><?php _e('Scheduled scan report', 'ninjafirewall') ?></th> |
| 469 | <td> |
| 470 | <p><label><input type="radio" name="report_scan" value="0"<?php checked($report_scan, 0) ?> /><?php _e('Send me a report by email only if changes are detected (default)', 'ninjafirewall') ?></label></p> |
| 471 | <p><label><input type="radio" name="report_scan" value="1"<?php checked($report_scan, 1) ?> /><?php _e('Always send me a report by email after a scheduled scan', 'ninjafirewall') ?></label></p> |
| 472 | </td> |
| 473 | </tr> |
| 474 | </table> |
| 475 | <input type="hidden" name="nfw_act" value="scheduled" /> |
| 476 | <p><input type="submit" class="button-primary" value="<?php _e('Save Scan Options', 'ninjafirewall') ?>" /></p> |
| 477 | <input type="hidden" name="tab" value="filecheck" /> |
| 478 | </form> |
| 479 | |
| 480 | <?php |
| 481 | |
| 482 | // --------------------------------------------------------------------- |
| 483 | |
| 484 | function nf_sub_monitoring_create($nfmon_snapshot) { |
| 485 | |
| 486 | // Check POST data: |
| 487 | if ( empty($_POST['snapdir']) ) { |
| 488 | return __('Enter the full path to the directory to be scanned.', 'ninjafirewall'); |
| 489 | } |
| 490 | if ( strpos( $_POST['snapdir'], '://' ) !== false ) { |
| 491 | return sprintf( __('The directory %s is not correct.', 'ninjafirewall'), '<code>'. htmlspecialchars($_POST['snapdir']) .'</code>'); |
| 492 | } |
| 493 | if ( strlen($_POST['snapdir']) > 1 ) { |
| 494 | $_POST['snapdir'] = trim($_POST['snapdir'], ' '); |
| 495 | $_POST['snapdir'] = rtrim($_POST['snapdir'], '/'); |
| 496 | } |
| 497 | if (! file_exists($_POST['snapdir']) ) { |
| 498 | return sprintf( __('The directory %s does not exist.', 'ninjafirewall'), '<code>'. htmlspecialchars($_POST['snapdir']) .'</code>'); |
| 499 | } |
| 500 | if (! is_readable($_POST['snapdir']) ) { |
| 501 | return sprintf( __('The directory %s is not readable.', 'ninjafirewall'), '<code>'. htmlspecialchars($_POST['snapdir']) .'</code>'); |
| 502 | } |
| 503 | if ( isset($_POST['snapnoslink']) ) { |
| 504 | $snapnoslink = 1; |
| 505 | } else { |
| 506 | $snapnoslink = 0; |
| 507 | } |
| 508 | |
| 509 | $snapexclude = ''; |
| 510 | if (! empty( $_POST['snapexclude'] ) ) { |
| 511 | $_POST['snapexclude'] = trim( $_POST['snapexclude'] ); |
| 512 | $_POST['snapexclude'] = preg_replace( '/\s*,\s*/', ',', $_POST['snapexclude'] ); |
| 513 | $tmp = preg_quote( $_POST['snapexclude'], '/' ); |
| 514 | $snapexclude = str_replace(',', '|', $tmp); |
| 515 | } |
| 516 | |
| 517 | @ini_set('max_execution_time', 0); |
| 518 | $snapproc = nf_fc_metrics('start'); |
| 519 | |
| 520 | if ($fh = fopen($nfmon_snapshot, 'w') ) { |
| 521 | fwrite($fh, '<?php die("Forbidden"); ?>' . "\n"); |
| 522 | $res = scd($_POST['snapdir'], $snapexclude, $fh, $snapnoslink); |
| 523 | fclose($fh); |
| 524 | |
| 525 | // Error ? |
| 526 | if ($res) { |
| 527 | if (file_exists($nfmon_snapshot) ) { |
| 528 | unlink($nfmon_snapshot); |
| 529 | } |
| 530 | return $res; |
| 531 | } |
| 532 | |
| 533 | // Save scan dir : |
| 534 | $nfw_options = nfw_get_option('nfw_options'); |
| 535 | $nfw_options['snapproc'] = nf_fc_metrics('stop', $snapproc ); |
| 536 | $nfw_options['snapexclude'] = $_POST['snapexclude']; |
| 537 | $nfw_options['snapdir'] = $_POST['snapdir']; |
| 538 | $nfw_options['snapnoslink'] = $snapnoslink; |
| 539 | nfw_update_option('nfw_options', $nfw_options); |
| 540 | |
| 541 | } else { |
| 542 | return sprintf( __('Cannot write to %s.', 'ninjafirewall'), '<code>'. $nfmon_snapshot .'</code>'); |
| 543 | } |
| 544 | } |
| 545 | |
| 546 | // --------------------------------------------------------------------- |
| 547 | |
| 548 | function scd($snapdir, $snapexclude, $fh, $snapnoslink) { |
| 549 | |
| 550 | if (is_readable($snapdir) ) { |
| 551 | if ($dh = opendir($snapdir) ) { |
| 552 | while ( FALSE !== ($file = readdir($dh)) ) { |
| 553 | if ( $file == '.' || $file == '..') { continue; } |
| 554 | $full_path = $snapdir . '/' . $file; |
| 555 | if ( $snapexclude ) { |
| 556 | if ( preg_match("/$snapexclude/", $full_path) ) { continue; } |
| 557 | } |
| 558 | if (is_readable($full_path)) { |
| 559 | if ( $snapnoslink && is_link($full_path)) { continue; } |
| 560 | if ( is_dir($full_path) ) { |
| 561 | scd($full_path, $snapexclude, $fh, $snapnoslink); |
| 562 | } elseif (is_file($full_path) ) { |
| 563 | $file_stat = stat($full_path); |
| 564 | fwrite($fh, $full_path . '::' . sprintf ("%04o", $file_stat['mode'] & 0777) . ':' . $file_stat['uid'] . ':' . |
| 565 | $file_stat['gid'] . ':' . $file_stat['size'] . ':' . $file_stat['mtime'] . ':' . |
| 566 | $file_stat['ctime'] . "\n"); |
| 567 | } |
| 568 | } |
| 569 | } |
| 570 | closedir($dh); |
| 571 | } else { |
| 572 | return sprintf(__('Error : cannot open %s directory.', 'ninjafirewall'), '<code>'. htmlspecialchars($snapdir) .'</code>'); |
| 573 | } |
| 574 | } else { |
| 575 | return sprintf(__('Error : %s directory is not readable.', 'ninjafirewall'), '<code>'. htmlspecialchars($snapdir) .'</code>'); |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | // --------------------------------------------------------------------- |
| 580 | |
| 581 | function nf_sub_monitoring_scan($nfmon_snapshot, $nfmon_diff) { |
| 582 | |
| 583 | $nfw_options = nfw_get_option('nfw_options'); |
| 584 | |
| 585 | if (empty($nfw_options['enabled']) ) { return; } |
| 586 | |
| 587 | @ini_set('max_execution_time', 0); |
| 588 | |
| 589 | if (! isset($nfw_options['snapexclude']) || ! isset($nfw_options['snapdir']) || ! isset($nfw_options['snapnoslink']) ) { |
| 590 | return sprintf( __('Missing options line %s, please try again.', 'ninjafirewall'), __LINE__ ); |
| 591 | } |
| 592 | $tmp = preg_quote($nfw_options['snapexclude'], '/'); |
| 593 | $snapexclude = str_replace(',', '|', $tmp); |
| 594 | |
| 595 | if ($fh = fopen($nfmon_snapshot . '_tmp', 'w') ) { |
| 596 | fwrite($fh, '<?php die("Forbidden"); ?>' . "\n"); |
| 597 | $res = scd($nfw_options['snapdir'], $snapexclude, $fh, $nfw_options['snapnoslink']); |
| 598 | fclose($fh); |
| 599 | } else { |
| 600 | return sprintf( __('Cannot create %s.', 'ninjafirewall'), '<code>'. $nfmon_snapshot . '_tmp</code>'); |
| 601 | } |
| 602 | |
| 603 | // Error ? |
| 604 | if ($res) { |
| 605 | if (file_exists($nfmon_snapshot . '_tmp') ) { |
| 606 | unlink($nfmon_snapshot . '_tmp'); |
| 607 | } |
| 608 | return $res; |
| 609 | } |
| 610 | |
| 611 | // Compare both snapshots : |
| 612 | |
| 613 | $old_files = $file = $new_files = array(); |
| 614 | $modified_files = $match = array(); |
| 615 | |
| 616 | if (! $fh = fopen($nfmon_snapshot, 'r') ) { |
| 617 | return __('Error reading old snapshot file.', 'ninjafirewall'); |
| 618 | } |
| 619 | while (! feof($fh) ) { |
| 620 | $match = explode('::', rtrim(fgets($fh)) . '::' ); |
| 621 | if (! empty($match[1]) ) { |
| 622 | $old_files[$match[0]] = $match[1]; |
| 623 | } |
| 624 | } |
| 625 | fclose($fh); |
| 626 | |
| 627 | if (! $fh = fopen($nfmon_snapshot . '_tmp', 'r') ) { |
| 628 | return __('Error reading new snapshot file.', 'ninjafirewall'); |
| 629 | } |
| 630 | while (! feof($fh) ) { |
| 631 | $match = explode('::', rtrim(fgets($fh)) . '::' ); |
| 632 | |
| 633 | if ( empty($match[1]) ) { |
| 634 | continue; |
| 635 | } |
| 636 | |
| 637 | // New file ? |
| 638 | if ( empty( $old_files[$match[0]] ) ) { |
| 639 | $new_files[$match[0]] = $match[1]; |
| 640 | continue; |
| 641 | } |
| 642 | |
| 643 | // Modified file ? |
| 644 | if ( $old_files[$match[0]] != $match[1] ) { |
| 645 | $modified_files[$match[0]] = $old_files[$match[0]] . '::' . $match[1]; |
| 646 | } |
| 647 | |
| 648 | // Delete it from old files list : |
| 649 | unset( $old_files[$match[0]] ); |
| 650 | } |
| 651 | fclose ($fh); |
| 652 | |
| 653 | // Write changes to file, if any : |
| 654 | if ($new_files || $modified_files || $old_files) { |
| 655 | |
| 656 | $fh = fopen($nfmon_diff, 'w'); |
| 657 | fwrite($fh, '<?php die("Forbidden"); ?>' . "\n"); |
| 658 | |
| 659 | if ( $new_files ) { |
| 660 | foreach ( $new_files as $fkey => $fvalue ) { |
| 661 | fwrite($fh, $fkey . '::N::' . $fvalue . "\n"); |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | if ( $modified_files ) { |
| 666 | foreach ( $modified_files as $fkey => $fvalue ) { |
| 667 | fwrite($fh, $fkey . '::M::' . $fvalue . "\n"); |
| 668 | } |
| 669 | } |
| 670 | |
| 671 | if ( $old_files ) { |
| 672 | foreach ( $old_files as $fkey => $fvalue ) { |
| 673 | fwrite($fh, $fkey . '::D::' . $fvalue . "\n"); |
| 674 | } |
| 675 | } |
| 676 | fclose($fh); |
| 677 | rename( $nfmon_snapshot . '_tmp', $nfmon_snapshot); |
| 678 | |
| 679 | } else { |
| 680 | if (file_exists($nfmon_diff) ) { |
| 681 | // Keep last changes : |
| 682 | rename($nfmon_diff, $nfmon_diff. '.php'); |
| 683 | } |
| 684 | unlink( $nfmon_snapshot . '_tmp'); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | // --------------------------------------------------------------------- |
| 689 | |
| 690 | function nf_scheduled_scan() { |
| 691 | |
| 692 | $nfw_options = nfw_get_option('nfw_options'); |
| 693 | |
| 694 | if (! isset($_POST['sched_scan']) || ! preg_match('/^[1-3]$/', $_POST['sched_scan']) ) { |
| 695 | $nfw_options['sched_scan'] = 0; |
| 696 | } else { |
| 697 | $nfw_options['sched_scan'] = $_POST['sched_scan']; |
| 698 | } |
| 699 | |
| 700 | if ( empty($_POST['report_scan']) ) { |
| 701 | $nfw_options['report_scan'] = 0; |
| 702 | } else { |
| 703 | $nfw_options['report_scan'] = 1; |
| 704 | } |
| 705 | nfw_update_option('nfw_options', $nfw_options); |
| 706 | |
| 707 | // Update cronjobs |
| 708 | nfw_create_scheduled_tasks('nfscanevent'); |
| 709 | |
| 710 | } |
| 711 | |
| 712 | // --------------------------------------------------------------------- |
| 713 | |
| 714 | function nf_scan_email( $nfmon_diff, $log_dir ) { |
| 715 | |
| 716 | if ( is_multisite() ) { |
| 717 | $url = network_home_url('/'); |
| 718 | } else { |
| 719 | $url = home_url('/'); |
| 720 | } |
| 721 | |
| 722 | /** |
| 723 | * Changes were detected. |
| 724 | */ |
| 725 | if ( $nfmon_diff ) { |
| 726 | $stat = stat( $nfmon_diff ); |
| 727 | $data = '== NinjaFirewall File Check (diff)'."\n"; |
| 728 | $data.= '== ' . site_url() ."\n"; |
| 729 | $data.= '== ' . date_i18n('M d, Y @ H:i:s O', $stat['ctime'] ) ."\n\n"; |
| 730 | $data.= '[+] = ' . __('New file', 'ninjafirewall') . |
| 731 | ' [!] = ' . __('Modified file', 'ninjafirewall') . |
| 732 | ' [-] = ' . __('Deleted file', 'ninjafirewall') . |
| 733 | "\n\n"; |
| 734 | $n = 0; |
| 735 | $m = 0; |
| 736 | $d = 0; |
| 737 | $fh = fopen( $nfmon_diff, 'r'); |
| 738 | while (! feof( $fh ) ) { |
| 739 | $res = explode('::', fgets( $fh ) ); |
| 740 | if ( empty( $res[1] ) ) { |
| 741 | continue; |
| 742 | } |
| 743 | /** |
| 744 | * New file. |
| 745 | */ |
| 746 | if ( $res[1] == 'N') { |
| 747 | $data .= "[+] {$res[0]}\n"; |
| 748 | ++$n; |
| 749 | /** |
| 750 | * Deleted file. |
| 751 | */ |
| 752 | } elseif ( $res[1] == 'D') { |
| 753 | $data .= "[-] {$res[0]}\n"; |
| 754 | ++$d; |
| 755 | /** |
| 756 | * Modified file. |
| 757 | */ |
| 758 | } elseif ( $res[1] == 'M') { |
| 759 | $data .= "[!] {$res[0]}\n"; |
| 760 | ++$m; |
| 761 | } |
| 762 | } |
| 763 | fclose( $fh ); |
| 764 | $data .= "\n== EOF\n"; |
| 765 | @file_put_contents( "{$log_dir}nf_filecheck.txt", $data, LOCK_EX ); |
| 766 | |
| 767 | /** |
| 768 | * Email notification. |
| 769 | */ |
| 770 | $subject = [ ]; |
| 771 | $content = [ $url, ucfirst( date_i18n('M d, Y @ H:i:s O') ), $n, $m, $d ]; |
| 772 | NinjaFirewall_mail::send( |
| 773 | 'fc_detection', $subject, $content, '', "{$log_dir}nf_filecheck.txt", 1 |
| 774 | ); |
| 775 | |
| 776 | /** |
| 777 | * User asked to always receive a report after a scheduled scan. |
| 778 | */ |
| 779 | } else { |
| 780 | /** |
| 781 | * Email notification. |
| 782 | */ |
| 783 | $subject = [ ]; |
| 784 | $content = [ $url, ucfirst( date_i18n('M d, Y @ H:i:s O') ) ]; |
| 785 | NinjaFirewall_mail::send('fc_report', $subject, $content, '', [], 1 ); |
| 786 | } |
| 787 | } |
| 788 | |
| 789 | // --------------------------------------------------------------------- |
| 790 | function nf_fc_metrics( $action = 'start', $starttime = 0 ) { |
| 791 | |
| 792 | if ( function_exists('hrtime') ) { |
| 793 | $metrics = 'hrtime'; |
| 794 | } else { |
| 795 | $metrics = 'microtime'; |
| 796 | } |
| 797 | |
| 798 | // Start chrono |
| 799 | if ( $action == 'start') { |
| 800 | return $metrics( true ); |
| 801 | } |
| 802 | |
| 803 | // Stop chrono and return elapsed time |
| 804 | if ( $metrics == 'hrtime') { |
| 805 | return number_format( ( $metrics( true ) - $starttime ) / 1000000000, 2 ); |
| 806 | } else { |
| 807 | return number_format( $metrics( true ) - $starttime, 2 ); |
| 808 | } |
| 809 | } |
| 810 | |
| 811 | // --------------------------------------------------------------------- |
| 812 | // EOF |
| 813 |