share
9 years ago
.htaccess
11 years ago
anti_malware.php
5 years ago
class-api.php
3 weeks ago
class-centralised-logging.php
3 weeks ago
class-coupon.php
7 months ago
class-email-sodium.php
2 months ago
class-firewall-log.php
3 weeks ago
class-helpers.php
9 months ago
class-import-export.php
4 months ago
class-ip.php
5 months ago
class-nfw-database.php
7 months ago
class-plugin-upgrade.php
3 weeks ago
class-security-updates.php
3 weeks ago
class-session.php
3 weeks ago
class_mail.php
2 months ago
firewall.php
3 weeks ago
fw_fileguard.php
5 months ago
fw_livelog.php
1 year ago
help.php
3 weeks ago
helpers.php
3 weeks ago
i18n-extra.php
3 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
3 weeks ago
loader.php
7 months ago
mail_template_firewall.php
1 year ago
mail_template_plugin.php
3 weeks ago
scheduled_tasks.php
3 years ago
settings_dashboard.php
3 weeks ago
settings_dashboard_about.php
2 months ago
settings_dashboard_statistics.php
2 months ago
settings_event_notifications.php
3 weeks ago
settings_events.php
2 months ago
settings_firewall_options.php
2 months ago
settings_firewall_policies.php
3 weeks ago
settings_login_protection.php
2 months ago
settings_logs.php
3 weeks ago
settings_logs_firewall_log.php
3 weeks ago
settings_logs_live_log.php
2 months ago
settings_monitoring.php
2 months 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
3 weeks ago
settings_security_rules_update.php
3 weeks ago
sign.pub
7 years ago
thickbox.php
4 years ago
widget.php
3 years ago
wpplus.php
4 months ago
settings_security_rules_update.php
602 lines
| 1 | <?php |
| 2 | /* |
| 3 | +---------------------------------------------------------------------+ |
| 4 | | NinjaFirewall (WP Edition) | |
| 5 | | | |
| 6 | | (c) NinTechNet - https://nintechnet.com/ | |
| 7 | +---------------------------------------------------------------------+ |
| 8 | | This program is free software: you can redistribute it and/or | |
| 9 | | modify it under the terms of the GNU General Public License as | |
| 10 | | published by the Free Software Foundation, either version 3 of | |
| 11 | | the License, or (at your option) any later version. | |
| 12 | | | |
| 13 | | This program is distributed in the hope that it will be useful, | |
| 14 | | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | | GNU General Public License for more details. | |
| 17 | +---------------------------------------------------------------------+ i18n+ / sa / 2 |
| 18 | */ |
| 19 | |
| 20 | if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); } |
| 21 | |
| 22 | // If your server can't remotely connect to a SSL port, add this |
| 23 | // to your wp-config.php script: `define('NFW_DONT_USE_SSL', 1);` |
| 24 | if ( defined( 'NFW_DONT_USE_SSL' ) ) { |
| 25 | $proto = "http"; |
| 26 | } else { |
| 27 | $proto = "https"; |
| 28 | } |
| 29 | $update_log = NFW_LOG_DIR . '/nfwlog/updates.php'; |
| 30 | |
| 31 | // Check which rules should be returned |
| 32 | if ( defined('NFW_WPWAF') ) { |
| 33 | $rules_type = 0; |
| 34 | } else { |
| 35 | $rules_type = 1; |
| 36 | } |
| 37 | |
| 38 | $nfw_options = nfw_get_option('nfw_options'); |
| 39 | |
| 40 | if ( empty( $nfw_options['sched_updates'] ) || empty( $nfw_options['enable_updates'] ) ) { |
| 41 | $sched_updates = 0; |
| 42 | } else { |
| 43 | $sched_updates = (int) $nfw_options['sched_updates']; |
| 44 | } |
| 45 | |
| 46 | if ( defined( 'NFUPDATESDO' ) && NFUPDATESDO == 2 ) { |
| 47 | // Installation |
| 48 | $update_url = array( |
| 49 | $proto . '://plugins.svn.wordpress.org/ninjafirewall/updates/', |
| 50 | 'version3.txt', |
| 51 | 'rules4.txt' |
| 52 | ); |
| 53 | } else { |
| 54 | // Scheduled updates or plugin update |
| 55 | $caching_id = sha1( home_url() ); |
| 56 | $update_url = array( |
| 57 | 'https://api.nintechnet.com/ninjafirewall/rules-update', |
| 58 | "?version=4&cid={$caching_id}&edn=wp&rt={$rules_type}&su={$sched_updates}", |
| 59 | "?rules=4&cid={$caching_id}&edn=wp&rt={$rules_type}&su={$sched_updates}" |
| 60 | ); |
| 61 | } |
| 62 | |
| 63 | // NFUPDATESDO: scheduled update (1), installation (2) or plugin update (3 - deprecated since v3.8) |
| 64 | if (defined('NFUPDATESDO') ) { |
| 65 | |
| 66 | $rules_lock = NFW_LOG_DIR .'/nfwlog/cache/rules'; |
| 67 | |
| 68 | if ( NFUPDATESDO != 2 ) { // Shouldn't apply to (re)installation |
| 69 | if ( $nfw_options['sched_updates'] == 1 ) { |
| 70 | $interval = 3000; // 50mn |
| 71 | } elseif ( $nfw_options['sched_updates'] == 2 ) { |
| 72 | $interval = 39600; // 11h |
| 73 | } else { |
| 74 | $interval = 82800; // 23h |
| 75 | } |
| 76 | |
| 77 | if ( file_exists( $rules_lock ) ) { |
| 78 | $rules_lock_mtime = filemtime( $rules_lock ); |
| 79 | if ( time() - $interval < $rules_lock_mtime ) { |
| 80 | return; |
| 81 | } |
| 82 | unlink( $rules_lock ); |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | touch( $rules_lock ); |
| 87 | |
| 88 | define('NFW_RULES', nf_sub_do_updates( $update_url, $update_log, NFUPDATESDO ) ); |
| 89 | return; |
| 90 | } |
| 91 | |
| 92 | // Block immediately if user is not allowed |
| 93 | nf_not_allowed( 'block', __LINE__ ); |
| 94 | |
| 95 | // We stop and warn the user if the firewall is disabled |
| 96 | if (! defined('NF_DISABLED') ) { |
| 97 | is_nfw_enabled(); |
| 98 | } |
| 99 | if (NF_DISABLED) { |
| 100 | echo '<div class="error notice is-dismissible"><p>' . __('Security rules cannot be updated when NinjaFirewall is disabled.', 'ninjafirewall') . '</p></div>'; |
| 101 | return; |
| 102 | } |
| 103 | |
| 104 | //Saved options |
| 105 | if (! empty( $_POST['nfw_act'] ) ) { |
| 106 | if ( empty( $_POST['nfwnonce'] ) || ! wp_verify_nonce( $_POST['nfwnonce'], 'updates_save' ) ) { |
| 107 | wp_nonce_ays('updates_save'); |
| 108 | } |
| 109 | // Check updates now |
| 110 | if ( isset( $_POST['check_updates'] ) ) { |
| 111 | if ( $res = nf_sub_do_updates($update_url, $update_log, 0) ) { |
| 112 | echo '<div class="updated notice is-dismissible"><p>' . __('Security rules have been updated.', 'ninjafirewall') . '</p></div>'; |
| 113 | } else { |
| 114 | echo '<div class="updated notice is-dismissible"><p>' . __('No security rules update available.', 'ninjafirewall') . '</p></div>'; |
| 115 | } |
| 116 | // Enable flag to display log |
| 117 | $tmp_showlog = 1; |
| 118 | } else { |
| 119 | if ( isset( $_POST['save_options'] ) ) { |
| 120 | nf_sub_updates_save(); |
| 121 | } elseif ( isset( $_POST['clear_log'] ) ) { |
| 122 | nf_sub_updates_clearlog($update_log); |
| 123 | } |
| 124 | echo '<div class="updated notice is-dismissible"><p>' . __('Your changes have been saved.', 'ninjafirewall') . '</p></div>'; |
| 125 | } |
| 126 | // Reload options: |
| 127 | $nfw_options = nfw_get_option('nfw_options'); |
| 128 | } |
| 129 | |
| 130 | // If WP cron is disabled, we simply warn the user |
| 131 | if ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON == true ) { |
| 132 | echo '<div class="notice-warning notice is-dismissible"><p>' . sprintf( __('It seems that %s is set. Ensure you have another way to run WP-Cron, otherwise NinjaFirewall automatic updates will not work.', 'ninjafirewall'), '<code>DISABLE_WP_CRON</code>' ) . '</p></div>'; |
| 133 | $cron_disabled = 1; |
| 134 | } |
| 135 | |
| 136 | if ( empty($nfw_options['enable_updates']) ) { |
| 137 | $enable_updates = 0; |
| 138 | } else { |
| 139 | $enable_updates = 1; |
| 140 | } |
| 141 | if ( empty($nfw_options['sched_updates']) || ! preg_match('/^[2-3]$/', $nfw_options['sched_updates']) ) { |
| 142 | $sched_updates = 1; |
| 143 | } else { |
| 144 | $sched_updates = $nfw_options['sched_updates']; |
| 145 | } |
| 146 | if ( empty($nfw_options['notify_updates']) && isset($nfw_options['notify_updates']) ) { |
| 147 | $notify_updates = 0; |
| 148 | } else { |
| 149 | // Defaut if not set yet |
| 150 | $notify_updates = 1; |
| 151 | } |
| 152 | ?> |
| 153 | <form method="post" name="fupdates"> |
| 154 | |
| 155 | <?php wp_nonce_field('updates_save', 'nfwnonce', 0); ?> |
| 156 | |
| 157 | <table class="form-table nfw-table"> |
| 158 | <tr style="background-color:#F9F9F9;border: solid 1px #DFDFDF;"> |
| 159 | <th scope="row" class="row-med"><?php _e('Automatically update NinjaFirewall security rules', 'ninjafirewall') ?></th> |
| 160 | <td> |
| 161 | <?php nfw_toggle_switch( 'danger', 'enable_updates', __('Enabled', 'ninjafirewall'), __('Disabled', 'ninjafirewall'), 'large', $enable_updates, false, 'onclick="nfwjs_up_down(\'upd_table\');"' ) ?> |
| 162 | </td> |
| 163 | </tr> |
| 164 | </table> |
| 165 | |
| 166 | <br /> |
| 167 | |
| 168 | <div id="upd_table"<?php echo $enable_updates == 1 ? '' : ' style="display:none"' ?>> |
| 169 | <table class="form-table nfw-table"> |
| 170 | <tr> |
| 171 | <th scope="row" class="row-med"><?php _e('Check for updates', 'ninjafirewall') ?> <span class="ninjafirewall-tip" data-tip="<?php esc_attr_e('In the Premium version of NinjaFirewall, you can check for security rules updates as often as every 15 minutes, versus one hour for the free WP Edition.', 'ninjafirewall' ) ?>"></span></th> |
| 172 | <td> |
| 173 | <select name="sched_updates"> |
| 174 | <option disabled><?php _e('Every 15 minutes', 'ninjafirewall') ?> (Premium)</option> |
| 175 | <option disabled><?php _e('Every 30 minutes', 'ninjafirewall') ?> (Premium)</option> |
| 176 | <option value="1"<?php selected($sched_updates, 1) ?>><?php _e('Hourly', 'ninjafirewall') ?></option> |
| 177 | <option value="2"<?php selected($sched_updates, 2) ?>><?php _e('Twicedaily', 'ninjafirewall') ?></option> |
| 178 | <option value="3"<?php selected($sched_updates, 3) ?>><?php _e('Daily', 'ninjafirewall') ?></option> |
| 179 | </select> |
| 180 | <?php |
| 181 | if ( $nextcron = wp_next_scheduled('nfsecupdates') ) { |
| 182 | $sched = new DateTime( date('M d, Y H:i:s', $nextcron) ); |
| 183 | $now = new DateTime( date('M d, Y H:i:s', time() ) ); |
| 184 | $diff = $now->diff($sched); |
| 185 | // Ensure that the scheduled scan time is in the future, |
| 186 | // not in the past, otherwise send a warning because wp-cron |
| 187 | // is obviously not working as expected |
| 188 | if ( $nextcron < time() ) { |
| 189 | // Don't display any message if WP-CRON is disabled |
| 190 | if ( empty( $cron_disabled ) ) { |
| 191 | ?> |
| 192 | <p class="description" style="color:red"><?php _e('The next scheduled date is in the past! WordPress wp-cron may not be working, may have been disabled or is currently running. Try to reload this page in a few seconds.', 'ninjafirewall'); ?></p> |
| 193 | <?php |
| 194 | } |
| 195 | } else { |
| 196 | ?> |
| 197 | <p class="description"><?php printf( __('Next scheduled update will start in approximately %s day, %s hour(s), %s minute(s) and %s seconds.', 'ninjafirewall'), $diff->format('%a') % 7, $diff->format('%h'), $diff->format('%i'), $diff->format('%s') ) ?></p> |
| 198 | <?php |
| 199 | } |
| 200 | } |
| 201 | ?> |
| 202 | </td> |
| 203 | </tr> |
| 204 | <tr> |
| 205 | <th scope="row" class="row-med"><?php _e('Notification', 'ninjafirewall') ?></th> |
| 206 | <td> |
| 207 | <p><label><input type="checkbox" name="notify_updates" value="1"<?php checked($notify_updates, 1) ?> /><?php _e('Send me a report by email when security rules have been updated.', 'ninjafirewall') ?></label></p> |
| 208 | <p class="description"><?php _e('Reports will be sent to the contact email address defined in the Event Notifications menu.', 'ninjafirewall') ?></p> |
| 209 | </td> |
| 210 | </tr> |
| 211 | |
| 212 | <?php |
| 213 | if (! empty($nfw_options['enable_updates']) || ! empty($tmp_showlog) ) { |
| 214 | $log_data = array(); |
| 215 | if ( file_exists($update_log) ) { |
| 216 | $log_data = file($update_log); |
| 217 | } else { |
| 218 | $log_data[] = __('The updates log is currently empty.', 'ninjafirewall'); |
| 219 | } |
| 220 | ?> |
| 221 | <tr> |
| 222 | <th scope="row" class="row-med"><?php _e('Updates Log', 'ninjafirewall') ?></th> |
| 223 | <td> |
| 224 | <textarea class="large-text code" style="height:200px;" wrap="off" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"><?php |
| 225 | $reversed = array_reverse($log_data); |
| 226 | $count = 0; |
| 227 | foreach ($reversed as $key) { |
| 228 | if ( $key[0] == '<' ) { continue; } |
| 229 | echo htmlentities($key); |
| 230 | ++$count; |
| 231 | } |
| 232 | if ( $count == 0 ) { |
| 233 | _e('The updates log is currently empty.', 'ninjafirewall'); |
| 234 | } |
| 235 | ?></textarea> |
| 236 | <p class="description"><?php _e('The log is deleted automatically.', 'ninjafirewall') ?></p> |
| 237 | </td> |
| 238 | </tr> |
| 239 | <?php |
| 240 | } |
| 241 | ?> |
| 242 | </table> |
| 243 | |
| 244 | </div> |
| 245 | <p> |
| 246 | <input name="nfw_act" type="hidden" value="1" /> |
| 247 | <input name="save_options" type="submit" class="button-primary" value="<?php _e('Save Updates Options', 'ninjafirewall') ?>" /> |
| 248 | <input name="check_updates" type="submit" class="button-secondary" value="<?php _e('Check For Updates Now!', 'ninjafirewall') ?>" /> |
| 249 | <?php |
| 250 | if ( empty( $enable_updates ) || ! file_exists( $update_log ) ) { |
| 251 | $style = ' style="display:none;"'; |
| 252 | } else { |
| 253 | $style = ' style="color:#ba0000;border-color:#ba0000;"'; |
| 254 | } |
| 255 | ?> |
| 256 | <input name="clear_log" type="submit" value="<?php _e('Delete Log', 'ninjafirewall') ?>" class="button-secondary"<?php echo $style ?> /> |
| 257 | </p> |
| 258 | </form> |
| 259 | <?php |
| 260 | |
| 261 | // --------------------------------------------------------------------- |
| 262 | |
| 263 | function nf_sub_updates_save() { |
| 264 | |
| 265 | $nfw_options = nfw_get_option('nfw_options'); |
| 266 | |
| 267 | if ( empty($_POST['sched_updates']) || ! preg_match('/^[2-3]$/', $_POST['sched_updates']) ) { |
| 268 | $nfw_options['sched_updates'] = 1; |
| 269 | $schedtype = 'hourly'; |
| 270 | } else { |
| 271 | $nfw_options['sched_updates'] = $_POST['sched_updates']; |
| 272 | if ($nfw_options['sched_updates'] == 2) { |
| 273 | $schedtype = 'twicedaily'; |
| 274 | } else { |
| 275 | $schedtype = 'daily'; |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | if ( empty($_POST['enable_updates']) ) { |
| 280 | $nfw_options['enable_updates'] = 0; |
| 281 | } else { |
| 282 | $nfw_options['enable_updates'] = 1; |
| 283 | } |
| 284 | |
| 285 | if ( empty($_POST['notify_updates']) ) { |
| 286 | $nfw_options['notify_updates'] = 0; |
| 287 | } else { |
| 288 | $nfw_options['notify_updates'] = 1; |
| 289 | } |
| 290 | |
| 291 | nfw_update_option('nfw_options', $nfw_options); |
| 292 | |
| 293 | // Recreate cronjobs if needed |
| 294 | nfw_create_scheduled_tasks('nfsecupdates'); |
| 295 | |
| 296 | } |
| 297 | |
| 298 | // --------------------------------------------------------------------- |
| 299 | |
| 300 | function nf_sub_updates_clearlog($update_log) { |
| 301 | |
| 302 | if (file_exists($update_log) ) { |
| 303 | @file_put_contents( $update_log, "<?php exit; ?>\n", LOCK_EX ); |
| 304 | } |
| 305 | |
| 306 | } |
| 307 | |
| 308 | // --------------------------------------------------------------------- |
| 309 | |
| 310 | function nf_sub_do_updates($update_url, $update_log, $NFUPDATESDO = 1) { |
| 311 | |
| 312 | // Are we installing (2) or updating (3 - deprecated since v3.8) NinjaFirewall ? |
| 313 | if ( $NFUPDATESDO > 1 ) { |
| 314 | return nf_sub_updates_download($update_url, $update_log, 0); |
| 315 | } |
| 316 | |
| 317 | $nfw_options = nfw_get_option('nfw_options'); |
| 318 | |
| 319 | // Don't do anything if NinjaFirewall is disabled : |
| 320 | if ( empty( $nfw_options['enabled'] ) ) { return 0; } |
| 321 | |
| 322 | if (! $new_rules_version = nf_sub_updates_getversion($update_url, $nfw_options['rules_version'], $update_log) ) { |
| 323 | // Error or nothing to update : |
| 324 | return; |
| 325 | } |
| 326 | |
| 327 | // There is a new version, let's fetch it: |
| 328 | if (! $data = nf_sub_updates_download($update_url, $update_log, $new_rules_version) ) { |
| 329 | // Error : |
| 330 | return; |
| 331 | } |
| 332 | |
| 333 | // Make sure we received the right format: |
| 334 | if (! preg_match('/^a:\d+:{i:\d/', $data ) ) { |
| 335 | nf_sub_updates_log( |
| 336 | $update_log, |
| 337 | __('Error: Wrong rules format.', 'ninjafirewall') |
| 338 | ); |
| 339 | return 0; |
| 340 | } |
| 341 | |
| 342 | // Unserialize the new rules : |
| 343 | if (! $new_rules = @unserialize($data) ) { |
| 344 | nf_sub_updates_log( |
| 345 | $update_log, |
| 346 | __('Error: Unable to unserialize the new rules.', 'ninjafirewall') |
| 347 | ); |
| 348 | return 0; |
| 349 | } |
| 350 | // One more check...: |
| 351 | if (! is_array($new_rules) || empty($new_rules[1]['cha'][1]['whe']) ) { |
| 352 | nf_sub_updates_log( |
| 353 | $update_log, |
| 354 | __('Error: Unserialized rules seem corrupted.', 'ninjafirewall') |
| 355 | ); |
| 356 | return 0; |
| 357 | } |
| 358 | |
| 359 | // dropins code: |
| 360 | if ( isset( $new_rules['dropins'] ) ) { |
| 361 | if ( $new_rules['dropins'] == 'delete' ) { |
| 362 | if ( file_exists( NFW_LOG_DIR .'/nfwlog/dropins.php' ) ) { |
| 363 | @unlink( NFW_LOG_DIR .'/nfwlog/dropins.php' ); |
| 364 | } |
| 365 | } else { |
| 366 | $dropins = base64_decode( $new_rules['dropins'], true ); |
| 367 | if ( $dropins !== false ) { |
| 368 | @file_put_contents( NFW_LOG_DIR .'/nfwlog/dropins.php', $dropins, LOCK_EX ); |
| 369 | } |
| 370 | } |
| 371 | unset( $new_rules['dropins'] ); |
| 372 | } |
| 373 | |
| 374 | $nfw_rules = nfw_get_option('nfw_rules'); |
| 375 | |
| 376 | foreach ( $new_rules as $new_key => $new_value ) { |
| 377 | foreach ( $new_value as $key => $value ) { |
| 378 | // If that rule exists already, we keep its 'ena' flag value |
| 379 | // as it may have been changed by the user with the rules editor: |
| 380 | // v3.x: |
| 381 | if ( ( isset( $nfw_rules[$new_key]['ena'] ) ) && ( $key == 'ena' ) ) { |
| 382 | $new_rules[$new_key]['ena'] = $nfw_rules[$new_key]['ena']; |
| 383 | } |
| 384 | // v1.x: |
| 385 | if ( ( isset( $nfw_rules[$new_key]['on'] ) ) && ( $key == 'ena' ) ) { |
| 386 | $new_rules[$new_key]['ena'] = $nfw_rules[$new_key]['on']; |
| 387 | } |
| 388 | } |
| 389 | } |
| 390 | // v1.x: |
| 391 | if ( isset( $nfw_rules[NFW_DOC_ROOT]['what'] ) ) { |
| 392 | $new_rules[NFW_DOC_ROOT]['cha'][1]['wha']= str_replace( '/', '/[./]*', $nfw_rules[NFW_DOC_ROOT]['what'] ); |
| 393 | $new_rules[NFW_DOC_ROOT]['ena'] = $nfw_rules[NFW_DOC_ROOT]['on']; |
| 394 | // v3.x: |
| 395 | } else { |
| 396 | $new_rules[NFW_DOC_ROOT]['cha'][1]['wha']= $nfw_rules[NFW_DOC_ROOT]['cha'][1]['wha']; |
| 397 | $new_rules[NFW_DOC_ROOT]['ena'] = $nfw_rules[NFW_DOC_ROOT]['ena']; |
| 398 | } |
| 399 | |
| 400 | // NFW_OBJECTS (Block serialized PHP objects): we must keep the |
| 401 | // value defined by the user in the Firewall Policies page: |
| 402 | $new_rules[NFW_OBJECTS]['cha'][1]['whe'] = $nfw_rules[NFW_OBJECTS]['cha'][1]['whe']; |
| 403 | |
| 404 | // Update rules in the DB : |
| 405 | nfw_update_option('nfw_rules', $new_rules); |
| 406 | |
| 407 | // Update rules version in the options table : |
| 408 | $nfw_options['rules_version'] = $new_rules_version; |
| 409 | nfw_update_option('nfw_options', $nfw_options); |
| 410 | |
| 411 | nf_sub_updates_log( |
| 412 | $update_log, |
| 413 | sprintf( __('Security rules updated to version %s.', 'ninjafirewall'), |
| 414 | preg_replace('/(\d{4})(\d\d)(\d\d)/', '$1-$2-$3', $new_rules_version) ) |
| 415 | ); |
| 416 | |
| 417 | // Email the admin ? |
| 418 | if (! empty($nfw_options['notify_updates']) ) { |
| 419 | nf_sub_updates_notification($new_rules_version); |
| 420 | } |
| 421 | return 1; |
| 422 | } |
| 423 | |
| 424 | // --------------------------------------------------------------------- |
| 425 | |
| 426 | function nf_sub_updates_getversion($update_url, $rules_version, $update_log) { |
| 427 | |
| 428 | global $wp_version; |
| 429 | $res = wp_remote_get( |
| 430 | $update_url[0] . $update_url[1], |
| 431 | array( |
| 432 | 'timeout' => 20, |
| 433 | 'httpversion' => '1.1' , |
| 434 | 'user-agent' => 'Mozilla/5.0 (compatible; NinjaFirewall/'. |
| 435 | NFW_ENGINE_VERSION .'; WordPress/'. $wp_version . ')', |
| 436 | 'sslverify' => true |
| 437 | ) |
| 438 | ); |
| 439 | if (! is_wp_error($res) ) { |
| 440 | if ( $res['response']['code'] == 200 ) { |
| 441 | // Get the rules version: |
| 442 | $new_version = explode('|', rtrim($res['body']), 2); |
| 443 | |
| 444 | // Ensure that the rules are compatible : |
| 445 | if ( $new_version[0] != 3 ) { |
| 446 | if (! isset( $new_version[1] ) ) { $new_version[1] = '004'; } |
| 447 | // This version of NinjaFirewall may be too old : |
| 448 | nf_sub_updates_log( |
| 449 | $update_log, |
| 450 | sprintf( __('Error: %s', 'ninjafirewall'), $new_version[1] ) |
| 451 | ); |
| 452 | return 0; |
| 453 | } |
| 454 | |
| 455 | if (! preg_match('/^\d{8}\.\d+$/', $new_version[1]) ) { |
| 456 | // Not what we were expecting: |
| 457 | nf_sub_updates_log( |
| 458 | $update_log, |
| 459 | __('Error: Unable to retrieve the new rules version.', 'ninjafirewall') |
| 460 | ); |
| 461 | return 0; |
| 462 | } |
| 463 | // Compare versions: |
| 464 | if ( version_compare($rules_version, $new_version[1], '<') ) { |
| 465 | return $new_version[1]; |
| 466 | |
| 467 | } else { |
| 468 | nf_sub_updates_log( |
| 469 | $update_log, |
| 470 | __('No security rules update available.', 'ninjafirewall') |
| 471 | ); |
| 472 | } |
| 473 | // Not a 200 OK ret code : |
| 474 | } else { |
| 475 | nf_sub_updates_log( |
| 476 | $update_log, |
| 477 | sprintf( __('Error: Server returned a %s HTTP error code (#1).', 'ninjafirewall'), htmlspecialchars($res['response']['code'])) |
| 478 | ); |
| 479 | } |
| 480 | // Connection error : |
| 481 | } else { |
| 482 | nf_sub_updates_log( |
| 483 | $update_log, |
| 484 | __('Error: Unable to connect to the remote server', 'ninjafirewall') . htmlspecialchars(" ({$res->get_error_message()})") |
| 485 | ); |
| 486 | } |
| 487 | return 0; |
| 488 | } |
| 489 | |
| 490 | // --------------------------------------------------------------------- |
| 491 | |
| 492 | function nf_sub_updates_download($update_url, $update_log, $new_rules_version) { |
| 493 | |
| 494 | global $wp_version; |
| 495 | $res = wp_remote_get( |
| 496 | $update_url[0] . $update_url[2], |
| 497 | array( |
| 498 | 'timeout' => 20, |
| 499 | 'httpversion' => '1.1' , |
| 500 | 'user-agent' => 'Mozilla/5.0 (compatible; NinjaFirewall/'. |
| 501 | NFW_ENGINE_VERSION .'; WordPress/'. $wp_version . ')', |
| 502 | 'sslverify' => true |
| 503 | ) |
| 504 | ); |
| 505 | if (! is_wp_error($res) ) { |
| 506 | if ( $res['response']['code'] == 200 ) { |
| 507 | $data = explode('|', rtrim($res['body']), 3); |
| 508 | |
| 509 | // Rules version should match the one we just fetched |
| 510 | // unless we are intalling NinjaFirewall ($new_rules_version==0) : |
| 511 | if ( $new_rules_version && $new_rules_version != $data[0]) { |
| 512 | nf_sub_updates_log( |
| 513 | $update_log, |
| 514 | sprintf( __('Error: The new rules versions do not match (%s != %s).', 'ninjafirewall'), $new_rules_version, htmlspecialchars($data[0])) |
| 515 | ); |
| 516 | return 0; |
| 517 | } |
| 518 | |
| 519 | /** |
| 520 | * Verify rules digital signature. |
| 521 | */ |
| 522 | if (! function_exists('openssl_verify') || ! defined('OPENSSL_ALGO_SHA256') ) { |
| 523 | nf_sub_updates_log( |
| 524 | $update_log, |
| 525 | __('Error: OpenSSL is required for rules verification.', 'ninjafirewall') |
| 526 | ); |
| 527 | return 0; |
| 528 | } |
| 529 | $public_key = rtrim( file_get_contents( __DIR__ .'/sign.pub' ) ); |
| 530 | $pubkeyid = openssl_pkey_get_public( $public_key ); |
| 531 | $verify = openssl_verify( $data[2], base64_decode( $data[1] ), $pubkeyid, OPENSSL_ALGO_SHA256); |
| 532 | if ( $verify != 1 ) { |
| 533 | nf_sub_updates_log( |
| 534 | $update_log, |
| 535 | sprintf( __('Error: The new rules %s digital signature is not correct. Aborting update, rules may have been tampered with.', 'ninjafirewall'), |
| 536 | htmlspecialchars($data[0]) ) |
| 537 | ); |
| 538 | return 0; |
| 539 | } |
| 540 | |
| 541 | // Save new rules version for install/upgrade: |
| 542 | define('NFW_NEWRULES_VERSION', $data[0]); |
| 543 | // Return the rules: |
| 544 | return @$data[2]; |
| 545 | |
| 546 | // Not a 200 OK ret code : |
| 547 | } else { |
| 548 | nf_sub_updates_log( |
| 549 | $update_log, |
| 550 | sprintf( __('Error: Server returned a %s HTTP error code (#2).', 'ninjafirewall'), htmlspecialchars($res['response']['code'])) |
| 551 | ); |
| 552 | } |
| 553 | // Connection error : |
| 554 | } else { |
| 555 | nf_sub_updates_log( |
| 556 | $update_log, |
| 557 | __('Error: Unable to connect to the remote server', 'ninjafirewall') . htmlspecialchars(" ({$res->get_error_message()})") |
| 558 | ); |
| 559 | } |
| 560 | return 0; |
| 561 | } |
| 562 | |
| 563 | // --------------------------------------------------------------------- |
| 564 | |
| 565 | function nf_sub_updates_log($update_log, $msg) { |
| 566 | |
| 567 | // If the log is bigger than 50Kb (+/- one month old), we flush it : |
| 568 | if ( file_exists($update_log) ) { |
| 569 | $log_stat = stat($update_log); |
| 570 | if ( $log_stat['size'] > 51200 ) { |
| 571 | @file_put_contents( $update_log, "<?php exit; ?>\n", LOCK_EX ); |
| 572 | } |
| 573 | } else { |
| 574 | @file_put_contents( $update_log, "<?php exit; ?>\n", LOCK_EX ); |
| 575 | } |
| 576 | @file_put_contents($update_log, date_i18n('[d/M/y:H:i:s O]') . " $msg\n", FILE_APPEND | LOCK_EX); |
| 577 | |
| 578 | } |
| 579 | |
| 580 | // --------------------------------------------------------------------- |
| 581 | |
| 582 | function nf_sub_updates_notification( $new_rules_version ) { |
| 583 | |
| 584 | if ( is_multisite() ) { |
| 585 | $url = network_home_url('/'); |
| 586 | } else { |
| 587 | $url = home_url('/'); |
| 588 | } |
| 589 | |
| 590 | $rules = preg_replace('/(\d{4})(\d\d)(\d\d)/', '$1-$2-$3', $new_rules_version ); |
| 591 | |
| 592 | /** |
| 593 | * Email notification. |
| 594 | */ |
| 595 | $subject = [ ]; |
| 596 | $content = [ $url, $rules, ucfirst( date_i18n('M d, Y @ H:i:s O') ) ]; |
| 597 | NinjaFirewall_mail::send('rules_update', $subject, $content, '', [], 1 ); |
| 598 | } |
| 599 | |
| 600 | // --------------------------------------------------------------------- |
| 601 | // EOF |
| 602 |