golden hour
/home/doctorbruno/public_html/pgmed.org/wp-content/plugins/block-wp-login
⬆️ Go Up
Upload
File/Folder
Size
Actions
assets
-
Del
OK
block-wp-login.php
42.87 KB
Del
OK
includes
-
Del
OK
readme.txt
8.75 KB
Del
OK
Edit: block-wp-login.php
<?php /* * Plugin Name: Block wp-login * Version: 1.5.8 * Requires at least: 5.0 * Requires PHP: 7.0 * Plugin URI: https://webd.uk/support/ * Description: Blocks direct access to wp-login.php and replaces it with a secret login URL to reduce brute-force traffic on Apache servers. * Author: Webd Ltd * Author URI: https://webd.uk * License: GPLv2 or later * License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html * Text Domain: block-wp-login */ if (!defined('ABSPATH')) { exit(esc_html(__('This isn\'t the page you\'re looking for. Move along, move along.', 'block-wp-login'))); } if (!class_exists('bwpl_class')) { class bwpl_class { const VERSION = '1.5.8'; private $bwpl_new_slug = ''; public function bwpl_load() { add_action('admin_menu', array($this, 'bwpl_add_settings_page')); add_action('admin_post_bwpl_save_settings', array($this, 'bwpl_configure_slug')); register_activation_hook(__FILE__, array(__CLASS__, 'bwpl_activate')); register_deactivation_hook(__FILE__, array($this, 'bwpl_uninstall')); if (get_option('bwpl_slug')) { if (is_admin() && self::installed_wordpress_version() !== get_bloginfo('version')) { add_action('admin_init', array($this, 'bwpl_new_wordpress_version')); } add_filter('login_url', array($this, 'bwpl_change_login_url'), 10, 3); add_filter('logout_url', array($this, 'bwpl_change_logout_url'), 10, 2); add_filter('wp_redirect', array($this, 'bwpl_change_login_redirect'), 10, 2); add_filter('logout_redirect', array($this, 'bwpl_change_logout_redirect'), 10, 3); add_filter('lostpassword_url', array($this, 'bwpl_change_lostpassword_url'), 10, 2); add_filter('register_url', array($this, 'bwpl_change_register_url')); add_filter('site_url', array($this, 'bwpl_change_password_reset_url'), 10, 3); add_filter('network_site_url', array($this, 'bwpl_change_password_reset_url'), 10, 3); } else { add_action('admin_notices', array($this, 'bwpl_setup_admin_notice')); } if (is_admin()) { add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'bwpl_add_plugin_action_links')); add_action('admin_notices', 'bwplCommon::admin_notices'); add_action('admin_notices', array($this, 'bwpl_daf_upgrade_notice')); add_action('wp_ajax_dismiss_bwpl_notice_handler', 'bwplCommon::ajax_notice_handler'); add_filter('bwpl_admin_notice_pages', array($this, 'bwpl_admin_notice_pages')); } add_action('wp_login', 'bwpl_class::wp_login', 10, 2); } function bwpl_add_plugin_action_links($links) { $settings_links = bwplCommon::plugin_action_links(admin_url('options-general.php?page=block-wp-login')); return array_merge($settings_links, $links); } public function bwpl_add_settings_page() { add_options_page( _x('Block wp-login', 'UI Strings', 'block-wp-login'), _x('Block wp-login', 'UI Strings', 'block-wp-login'), 'manage_options', 'block-wp-login', array($this, 'bwpl_settings_page') ); } public function bwpl_settings_page() { if (!current_user_can('manage_options')) { return; } ?> <div class="wrap"> <h1><?php echo esc_html(get_admin_page_title()); ?></h1> <?php if (isset($_GET['settings-updated']) && 'true' === sanitize_text_field(wp_unslash($_GET['settings-updated']))) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only status flag. ?> <div class="notice notice-success is-dismissible"><p><?php esc_html_e('Settings saved.', 'block-wp-login'); ?></p></div> <?php } ?> <?php if (isset($_GET['bwpl-error'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only error flag. ?> <div class="notice notice-error"><?php $error = sanitize_key(wp_unslash($_GET['bwpl-error'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only error flag. if ('requirements' === $error) { $requirements = self::bwpl_requirements_check(); echo is_wp_error($requirements) ? wp_kses_post(self::bwpl_requirements_message($requirements)) : '<p>' . esc_html__('The server requirements could not be confirmed. Please try again.', 'block-wp-login') . '</p>'; } elseif ('locked' === $error) { echo '<p>' . esc_html__('The settings could not be saved because another Block wp-login update is in progress. Please try again.', 'block-wp-login') . '</p>'; } ?></div> <?php } ?> <?php $this->bwpl_settings_title(); ?> <form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="post"> <input type="hidden" name="action" value="bwpl_save_settings" /> <table class="form-table" role="presentation"> <tr> <th scope="row"><label for="bwpl_slug"><?php esc_html_e('Private login address', 'block-wp-login'); ?></label></th> <td><?php $this->bwpl_settings_html(); ?></td> </tr> </table> <?php submit_button(); ?> </form> <?php if (!class_exists('Deny_All_Firewall') && !class_exists('daf_class')) { ?> <h2><?php esc_html_e('Protect more than your login page', 'block-wp-login'); ?></h2> <p><?php echo wp_kses( sprintf( /* translators: link to the Deny All Firewall plugin installation search */ __('Block wp-login helps reduce unwanted login attempts. For broader protection against unwanted requests, take a look at %s.', 'block-wp-login'), '<a href="' . esc_url(add_query_arg(array('s' => 'domainsupport%20deny%20all%20firewall', 'tab' => 'search', 'type' => 'term'), self_admin_url('plugin-install.php'))) . '">' . esc_html__('Deny All Firewall', 'block-wp-login') . '</a>' ), array('a' => array('href' => array())) ); ?></p> <p> <a href="<?php echo esc_url(add_query_arg(array('s' => 'domainsupport%20deny%20all%20firewall', 'tab' => 'search', 'type' => 'term'), self_admin_url('plugin-install.php'))); ?>" title="<?php esc_attr_e('For broader protection against unwanted requests, take a look at Deny All Firewall.', 'block-wp-login'); ?>"> <img src="<?php echo esc_url(plugin_dir_url(__FILE__) . 'assets/deny-all-firewall-banner.jpg'); ?>" alt="<?php esc_attr_e('For broader protection against unwanted requests, take a look at Deny All Firewall.', 'block-wp-login'); ?>" title="<?php esc_attr_e('For broader protection against unwanted requests, take a look at Deny All Firewall.', 'block-wp-login'); ?>" style="width: 100%; max-width: 772px; height: auto;" /> </a> </p> <?php } ?> </div> <?php } function bwpl_configure_slug() { if (!current_user_can('manage_options')) { wp_die(esc_html__('You are not allowed to manage these settings.', 'block-wp-login')); } check_admin_referer('bwpl_slug_change', 'bwpl_nonce'); $requirements = self::bwpl_requirements_check(); if (is_wp_error($requirements)) { wp_safe_redirect(add_query_arg('bwpl-error', 'requirements', admin_url('options-general.php?page=block-wp-login'))); exit; } if (isset($_POST['bwpl_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['bwpl_nonce'])), 'bwpl_slug_change') && isset($_POST['bwpl_slug']) && current_user_can('manage_options')) { $version_lock = self::acquire_version_lock(); if (!$version_lock) { wp_safe_redirect(add_query_arg('bwpl-error', 'locked', admin_url('options-general.php?page=block-wp-login'))); exit; } try { $this->bwpl_new_slug = trim(sanitize_key(wp_strip_all_tags(wp_unslash($_POST['bwpl_slug'])))); if ($this->bwpl_new_slug) { $notify = (isset($_POST['bwpl_notify']) && 'true' === $_POST['bwpl_notify']); $this->bwpl_uninstall(); $this->bwpl_install(false, $notify, $version_lock); } else { if (isset($_POST['bwpl_notify']) && 'true' === $_POST['bwpl_notify']) { $this->bwpl_send_emails(false); } $this->bwpl_uninstall(); } update_option('bwpl_slug', $this->bwpl_new_slug); add_filter('login_url', array($this, 'bwpl_change_login_url'), 10, 3); add_filter('logout_url', array($this, 'bwpl_change_logout_url'), 10, 2); add_filter('logout_redirect', array($this, 'bwpl_change_logout_redirect'), 10, 3); add_filter('lostpassword_url', array($this, 'bwpl_change_lostpassword_url'), 10, 2); add_filter('register_url', array($this, 'bwpl_change_register_url')); add_filter('site_url', array($this, 'bwpl_change_password_reset_url'), 10, 3); add_filter('network_site_url', array($this, 'bwpl_change_password_reset_url'), 10, 3); $this->bwpl_refresh_daf_rules(); if ( isset($_POST['bwpl_unknown_admin']) && sanitize_text_field(wp_unslash($_POST['bwpl_unknown_admin'])) && isset($_POST['bwpl_known_ips']) && sanitize_textarea_field(wp_unslash($_POST['bwpl_known_ips'])) ) { $known_ips = preg_split('/\r\n|[\r\n]/', sanitize_textarea_field(wp_unslash($_POST['bwpl_known_ips']))); foreach ($known_ips AS $key => $known_ip) { if (!( filter_var($known_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || filter_var($known_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) )) { unset($known_ips[$key]); } } if ($known_ips) { update_option('bwpl_known_ips', implode(PHP_EOL, $known_ips)); } else { delete_option('bwpl_known_ips'); } } else { delete_option('bwpl_known_ips'); } } finally { self::release_version_lock($version_lock); } } wp_safe_redirect(add_query_arg('settings-updated', 'true', admin_url('options-general.php?page=block-wp-login'))); exit; } public static function bwpl_activate() { $requirements = self::bwpl_requirements_check(); if (is_wp_error($requirements)) { wp_die( wp_kses_post(self::bwpl_requirements_message($requirements)), esc_html__('Block wp-login could not be activated', 'block-wp-login'), array('back_link' => true) ); } } private static function bwpl_requirements_check() { if (!function_exists('got_mod_rewrite')) { require_once ABSPATH . 'wp-admin/includes/misc.php'; } $server_software = isset($_SERVER['SERVER_SOFTWARE']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_SOFTWARE'])) : ''; $supports_htaccess = got_mod_rewrite() || false !== stripos($server_software, 'litespeed'); /** * Filters whether the web server supports Apache-style .htaccess rewrite rules. * * @param bool $supports_htaccess Whether compatible rewrite support was detected. */ $supports_htaccess = (bool) apply_filters('bwpl_server_supports_htaccess', $supports_htaccess); $errors = new WP_Error(); if (!$supports_htaccess) { $errors->add('rewrite_support', __('An Apache-compatible web server with .htaccess and mod_rewrite support is required.', 'block-wp-login')); } $home_path = bwplCommon::get_home_path(); $htaccess_file = $home_path . '.htaccess'; $login_file = $home_path . 'wp-login.php'; if (!is_dir($home_path) || !wp_is_writable($home_path)) { $errors->add('home_not_writable', __('The WordPress home directory must be writable so the private login file can be created.', 'block-wp-login')); } if (!is_file($login_file) || !is_readable($login_file)) { $errors->add('login_not_readable', __('The standard WordPress wp-login.php file could not be found or read.', 'block-wp-login')); } if (file_exists($htaccess_file) && (!is_file($htaccess_file) || !wp_is_writable($htaccess_file))) { $errors->add('htaccess_not_writable', __('The WordPress .htaccess file must be writable.', 'block-wp-login')); } return $errors->has_errors() ? $errors : true; } private static function bwpl_requirements_message($requirements) { $message = '<p>' . esc_html__('Block wp-login cannot run on this website for the following reason(s):', 'block-wp-login') . '</p><ul>'; foreach ($requirements->get_error_messages() as $error_message) { $message .= '<li>' . esc_html($error_message) . '</li>'; } return $message . '</ul>'; } function bwpl_settings_title() { ?> <p><?php esc_html_e('Choose a private login address to block direct access to wp-login.php and reduce unwanted login attempts.', 'block-wp-login'); ?></p> <?php } function bwpl_settings_html() { wp_nonce_field('bwpl_slug_change', 'bwpl_nonce'); $characters = 'abcdefghijklmnopqrstuvwxyz'; $randomString = ''; for ($i = 0; $i < 8; $i++) { $randomString .= $characters[wp_rand(0, strlen($characters) - 1)]; } ?> <input id="bwpl_slug" name="bwpl_slug" type="text" class="regular-text code" value="<?php echo esc_attr(get_option('bwpl_slug')); ?>" /> <script type="text/javascript"> jQuery('#bwpl_slug').change(function() { jQuery(this).val(jQuery(this).val().toLowerCase().replace(/[^a-z0-9]+/g,'')); if (jQuery(this).val().length !== 0) { alert(<?php echo wp_json_encode(__('Your new login address will be:', 'block-wp-login') . "\n\n" . get_site_url() . '/'); ?> + jQuery(this).val() + <?php echo wp_json_encode('/' . "\n\n" . __('Save your changes, then bookmark the new address so you can find it again.', 'block-wp-login')); ?>); } jQuery('#bwpl_notify').prop('checked', true); }); </script> <p class="description"><?php esc_html_e('Enter the final part of the address using letters and numbers only. Leave this blank to use the standard wp-login.php address.', 'block-wp-login'); ?></p> <p><a href="javascript:void(0)" class="randomlogin"><?php esc_html_e('Generate a random login address', 'block-wp-login'); ?></a></p> <script type="text/javascript"> jQuery('.randomlogin').on('click',function() { var result = '', characters = 'abcdefghijklmnopqrstuvwxyz'; for (var i = 0; i < 8; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } jQuery('#bwpl_slug').val(result); alert(<?php echo wp_json_encode(__('Your new login address will be:', 'block-wp-login') . "\n\n" . get_site_url() . '/'); ?> + result + <?php echo wp_json_encode('/' . "\n\n" . __('Save your changes, then bookmark the new address so you can find it again.', 'block-wp-login')); ?>); jQuery('#bwpl_notify').prop('checked', true); }); </script> <p><strong><?php esc_html_e('Current login address: ', 'block-wp-login'); ?></strong><?php if (get_option('bwpl_slug')) { echo esc_url(get_site_url(null, (get_option('bwpl_slug') . '/'))); } else { echo esc_url(get_site_url(null, 'wp-login.php')); } ?></p> <p><input id="bwpl_notify" name="bwpl_notify" type="checkbox" value="true"> <?php esc_html_e('Email all administrators when the login address changes.', 'block-wp-login'); ?></p> <?php $known_ips = get_option('bwpl_known_ips'); if (!$known_ips) { $known_ips = false; } ?> <p><input id="bwpl_unknown_admin" name="bwpl_unknown_admin" type="checkbox" value="true"<?php if ($known_ips) { echo ' checked'; } ?>> <?php esc_html_e('Email the site owner when an administrator signs in from an unrecognised IP address.', 'block-wp-login'); ?></p> <p id="bwpl_known_ips_wrapper"<?php if (!$known_ips) { echo ' style="display: none;"'; } ?>><label for="bwpl_known_ips"><strong><?php esc_html_e('Recognised IP addresses', 'block-wp-login'); ?></strong></label><br> <textarea name="bwpl_known_ips" id="bwpl_known_ips" class="large-text code" rows="5"><?php echo ($known_ips ? esc_html($known_ips) : esc_html(self::get_current_ip())); ?></textarea><br> <span class="description"><?php esc_html_e('Enter one IP address per line. The site owner will not be notified when an administrator signs in from one of these addresses.', 'block-wp-login'); ?></span></p> <script type="text/javascript"> jQuery('#bwpl_unknown_admin').on('change',function() { jQuery('#bwpl_known_ips_wrapper').toggle(); }); </script> <?php } function bwpl_send_emails($new_version) { $blogusers = get_users('role=Administrator'); $admin_emails = array(); foreach ($blogusers as $user) { if ($user->user_email) { $this->bwpl_send_email($user->user_email, $new_version); array_push($admin_emails, $user->user_email); } } if (get_bloginfo('admin_email') && !in_array(get_bloginfo('admin_email'),$admin_emails)) { $this->bwpl_send_email(get_bloginfo('admin_email'), $new_version); } } function bwpl_install($new_version = false, $notify = true, $version_lock = false) { global $wp_filesystem; if (!$wp_filesystem) { require_once ABSPATH . 'wp-admin/includes/file.php'; if (!WP_Filesystem()) { return false; } } if (!is_object($wp_filesystem)) { return false; } $home_path = bwplCommon::get_home_path(); $login_file = $home_path . 'wp-login.php'; if ($wp_filesystem->exists($login_file)) { $content = $wp_filesystem->get_contents($login_file); if (false === $content) { return false; } $content_chunks = explode('wp-login.php', $content); $content = implode($this->bwpl_new_slug . '-wp-login.php', $content_chunks); $new_login_file = $home_path . $this->bwpl_new_slug . '-wp-login.php'; if ((!$wp_filesystem->exists($new_login_file) && $wp_filesystem->is_writable($home_path)) || $wp_filesystem->is_writable($new_login_file)) { if (!$wp_filesystem->put_contents($new_login_file, $content, FS_CHMOD_FILE)) { return false; } } else { return false; } } else { return false; } $htaccess_file = $home_path . '.htaccess'; if ((!$wp_filesystem->exists($htaccess_file) && $wp_filesystem->is_writable($home_path)) || $wp_filesystem->is_writable($htaccess_file)) { $markerdata = $wp_filesystem->exists($htaccess_file) ? $wp_filesystem->get_contents($htaccess_file) : ''; if (false !== $markerdata) { $markerdata = explode("\n", $markerdata); $found = false; $newdata = ''; foreach ($markerdata as $line) { if (!$found) { $newdata .= "# BEGIN BlockWPLogin\n"; $newdata .= "<IfModule mod_rewrite.c>\n"; $newdata .= "RewriteEngine On\n"; $newdata .= "RewriteCond %{QUERY_STRING} \"^action=postpass$\" RewriteRule \"^" . str_replace('.', '\.', substr(site_url('wp-login.php', 'relative'), 1)) . "$\" " . str_replace('.', '\.', site_url($this->bwpl_new_slug . '-wp-login.php', 'relative')) . " [QSA,L] "; $newdata .= "RewriteRule \"^" . str_replace('.', '\.', substr(site_url('wp-login.php', 'relative'), 1)) . "\" - [F]\n"; $newdata .= "RewriteRule \"^$this->bwpl_new_slug\\/?$\" " . str_replace('.', '\.', site_url($this->bwpl_new_slug . '-wp-login.php', 'relative')) . " [R=301,QSA,L]\n"; $newdata .= "</IfModule>\n"; $newdata .= "# END BlockWPLogin\n\n"; $newdata .= "$line\n"; $found = true; } else { $newdata .= "$line\n"; } } if (!$wp_filesystem->put_contents($htaccess_file, $newdata, FS_CHMOD_FILE)) { return false; } } else { return false; } } else { return false; } if (!self::record_installed_wordpress_version(get_bloginfo('version'), $version_lock)) { return false; } if ($new_version || $notify) { $this->bwpl_send_emails($new_version); } return true; } function bwpl_setup_admin_notice() { $screen = get_current_screen(); if ($screen && 'settings_page_block-wp-login' === $screen->id) { return; } ?> <div class="notice notice-success"> <p><?php /* translators: <strong> HTML tags */ echo wp_kses(sprintf(__('%1$sBlock wp-login%2$s activated. ', 'block-wp-login'),'<strong>','</strong>'), 'post'); ?><a href="<?php echo esc_url(admin_url('options-general.php?page=block-wp-login')); ?>"><?php esc_html_e('Configure the plugin here.', 'block-wp-login'); ?></a></p> </div> <?php } /** * Allow common plugin notices on this plugin's settings screen. */ public function bwpl_admin_notice_pages($allowed_pages) { $screen = get_current_screen(); if ($screen && 'settings_page_block-wp-login' === $screen->id) { $allowed_pages[] = 'options-general.php'; } return array_unique($allowed_pages); } function bwpl_uninstall() { global $wp_filesystem; if (!$wp_filesystem) { require_once ABSPATH . 'wp-admin/includes/file.php'; if (!WP_Filesystem()) { return false; } } if (!is_object($wp_filesystem)) { return false; } $home_path = bwplCommon::get_home_path(); $htaccess_file = $home_path . '.htaccess'; if ($wp_filesystem->exists($htaccess_file)) { if (!$wp_filesystem->is_writable($htaccess_file)) { return false; } $markerdata = $wp_filesystem->get_contents($htaccess_file); if (false === $markerdata) { return false; } $markerdata = explode("\n", $markerdata); $found = false; $blank_line = false; $newdata = ''; foreach ($markerdata as $line) { if ($blank_line && !$line) { $found = true; } if ($blank_line && $line) { $found = false; } if ($line) { $blank_line = false; } else { $blank_line = true; } if ('# BEGIN BlockWPLogin' === $line) { $found = true; } if (!$found) { $newdata .= "$line\n"; } if ('# END BlockWPLogin' === $line) { $found = false; } } if (!$wp_filesystem->put_contents($htaccess_file, $newdata, FS_CHMOD_FILE)) { return false; } } add_filter('logout_url', array($this, 'bwpl_reset_logout_url')); add_filter('logout_redirect', array($this, 'bwpl_reset_logout_url')); add_filter('lostpassword_url', array($this, 'bwpl_reset_logout_url')); $slug = get_option('bwpl_slug'); $login_file = $home_path . $slug . '-wp-login.php'; if ($slug && $wp_filesystem->exists($login_file)) { if (!$wp_filesystem->is_writable($login_file) || !$wp_filesystem->delete($login_file)) { return false; } } update_option('bwpl_slug', ''); $this->bwpl_refresh_daf_rules(); return true; } function bwpl_change_login_url($login_url, $redirect, $force_reauth) { if ( function_exists('is_user_logged_in') && ( is_user_logged_in() || did_action('password_reset') || $this->bwpl_is_secret_login_request() ) ) { $login_url = str_replace('/wp-login.php', '/' . get_option('bwpl_slug') . '-wp-login.php', $login_url); } return $login_url; } function bwpl_change_logout_url($logout_url, $redirect) { if ( (function_exists('is_user_logged_in') && is_user_logged_in()) || $this->bwpl_is_secret_login_request() ) { $logout_url = str_replace('/wp-login.php', '/' . get_option('bwpl_slug') . '-wp-login.php', $logout_url); } return $logout_url; } function bwpl_change_lostpassword_url($lostpassword_url, $redirect) { if ($this->bwpl_is_secret_login_request()) { $lostpassword_url = str_replace('/wp-login.php', '/' . get_option('bwpl_slug') . '-wp-login.php', $lostpassword_url); } return $lostpassword_url; } function bwpl_change_register_url($register_url) { if ($this->bwpl_is_secret_login_request()) { $register_url = str_replace('/wp-login.php', '/' . get_option('bwpl_slug') . '-wp-login.php', $register_url); } return $register_url; } function bwpl_change_password_reset_url($url, $path, $scheme) { if ( !is_string($path) || 1 !== preg_match('/\Awp-login\.php\?login=[^&]+&key=[^&]+&action=rp\z/D', $path) ) { return $url; } return preg_replace( '/\/wp-login\.php(?=\?|$)/', '/' . get_option('bwpl_slug') . '-wp-login.php', $url, 1 ); } function bwpl_change_login_redirect($location, $status) { $path = wp_parse_url($location, PHP_URL_PATH); $query = wp_parse_url($location, PHP_URL_QUERY); if ( !did_action('wp_login') || !is_string($path) || '/wp-login.php' !== substr($path, -13) || !is_string($query) ) { return $location; } preg_match_all('/(?:^|&)action=([^&]*)/', $query, $action_matches); if ( 1 === count($action_matches[1]) && 'confirm_admin_email' === rawurldecode($action_matches[1][0]) ) { $location = preg_replace( '/\/wp-login\.php(?=\?|$)/', '/' . get_option('bwpl_slug') . '-wp-login.php', $location, 1 ); } return $location; } function bwpl_change_logout_redirect($redirect_to, $requested_redirect_to, $user) { if ($user->ID) { $redirect_to = str_replace('/wp-login.php', '/' . get_option('bwpl_slug') . '-wp-login.php', $redirect_to); } return $redirect_to; } private function bwpl_is_secret_login_request() { if (empty($_SERVER['SCRIPT_FILENAME']) || !is_string($_SERVER['SCRIPT_FILENAME'])) { return false; } $script_filename = sanitize_text_field(wp_unslash($_SERVER['SCRIPT_FILENAME'])); $slug = get_option('bwpl_slug'); return $slug && $slug . '-wp-login.php' === basename($script_filename); } function bwpl_reset_logout_url($logout_url) { $logout_url = str_replace('/' . get_option('bwpl_slug') . '-wp-login.php', '/wp-login.php', $logout_url); return $logout_url; } function bwpl_send_email($recipient, $new_version) { if ($new_version) { $message = __('A recent WordPress core update has been detected and “Block wp-login” has been re-installed. Here is a reminder of your login address:', 'block-wp-login'); } else { $message = __('Your WordPress login address has been changed:', 'block-wp-login'); } $message .= "\r\n\r\n"; if ($this->bwpl_new_slug) { $message .= get_site_url(null, ($this->bwpl_new_slug . '/')) . "\r\n\r\n"; } else { $message .= get_site_url(null, 'wp-login.php') . "\r\n\r\n"; } $message .= __('Keep this link handy! Bookmarking it is the best way to ensure you never get locked out.', 'block-wp-login'); $message .= "\r\n\r\n---\r\n\r\n"; $message .= __('Does your site need a glow-up?', 'block-wp-login'); $message .= "\r\n"; $message .= __('Running slowly?', 'block-wp-login'); $message .= "\r\n"; $message .= __('Want new features?', 'block-wp-login'); $message .= "\r\n\r\n"; $message .= __('See how we can help', 'block-wp-login'); $message .= ' https://webd.uk'; if (is_multisite()) { $blogname = get_network()->site_name; } else { $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); } if ($new_version) { /* translators: website title */ $title = sprintf(__('[%s] WordPress Login Reminder', 'block-wp-login'), $blogname); } else { /* translators: website title */ $title = sprintf(__('[%s] WordPress Login Changed', 'block-wp-login'), $blogname); } if (!wp_mail($recipient, wp_specialchars_decode($title), $message)) { add_action('admin_notices', array($this, 'bwpl_admin_notice_email_html')); } } function bwpl_admin_notice_email_html() { ?> <div class="notice notice-error"> <p><?php /* translators: <strong> HTML tags */ echo wp_kses(sprintf(__('%1$sBlock wp-login%2$s activated email could not be sent.', 'block-wp-login'),'<strong>','</strong>'), 'post'); ?></p> </div> <?php } function bwpl_new_wordpress_version() { if (self::is_server_overloaded()) { return; } $version_lock = self::acquire_version_lock(); if ($version_lock) { try { $installed_version = self::read_locked_wordpress_version($version_lock); if (!$installed_version) { $installed_version = self::legacy_wordpress_version(); if ($installed_version === get_bloginfo('version')) { self::record_installed_wordpress_version($installed_version, $version_lock); } } if ($installed_version !== get_bloginfo('version')) { $bwpl_old_slug = get_option('bwpl_slug'); if ($this->bwpl_uninstall()) { $this->bwpl_new_slug = $bwpl_old_slug; if ($this->bwpl_install(true, true, $version_lock)) { update_option('bwpl_slug', $bwpl_old_slug); } $this->bwpl_refresh_daf_rules(); } } } finally { self::release_version_lock($version_lock); } } } public static function wp_login($user_login, $user) { if (user_can($user->ID, 'manage_options')) { $ip = self::get_current_ip(); if ($ip) { $known_ips = get_option('bwpl_known_ips'); if ($known_ips) { $known_ips = preg_split('/\r\n|[\r\n]/', $known_ips); if (!in_array($ip, $known_ips, true)) { if (is_multisite()) { $blogname = get_network()->site_name; } else { $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); } /* translators: website title */ $title = sprintf(__('[%s] WordPress Login Alert', 'block-wp-login'), $blogname); $message = __('An administrator with an un-recognised IP address has signed in:', 'block-wp-login') . "\r\n\r\n"; $message .= __('User: ', 'block-wp-login') . $user_login . "\r\n\r\n"; $message .= __('IP: ', 'block-wp-login') . $ip . "\r\n\r\n"; $message .= __('Contact us if you are having trouble with WordPress https://webd.uk', 'block-wp-login') . "\r\n\r\n"; $message .= __('If you like our plugin please leave a short review: https://wordpress.org/support/plugin/block-wp-login/reviews/#new-post', 'block-wp-login') . "\r\n\r\n"; wp_mail(get_bloginfo('admin_email'), wp_specialchars_decode($title), $message); } } } } } /** * Ask Deny All Firewall to rebuild its rules. * * Deny All Firewall 2.0 provides a public action for integrations. Keep * the legacy calls as a compatibility fallback for older releases. */ private function bwpl_refresh_daf_rules() { $daf_options = get_option('daf_options'); if (empty($daf_options['enable_firewall'])) { return; } if (has_action('deny_all_firewall_refresh_rules')) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound do_action('deny_all_firewall_refresh_rules'); return; } global $daf; if ( is_object($daf) && is_callable(array($daf, 'daf_create_htaccess')) && is_callable(array($daf, 'daf_remove_rules')) && is_callable(array($daf, 'daf_inject_rules')) ) { $daf_htaccess = $daf->daf_create_htaccess(); if ($daf_htaccess && $daf->daf_remove_rules()) { $daf->daf_inject_rules($daf_htaccess); } } } /** * Prompt administrators to install the available Deny All Firewall 2.0 update. */ public function bwpl_daf_upgrade_notice() { $screen = get_current_screen(); $notice_screens = array('plugins', 'update-core', 'settings_page_block-wp-login'); if ( !$screen || !in_array($screen->id, $notice_screens, true) || !current_user_can('update_plugins') || !class_exists('daf_class') || has_action('deny_all_firewall_refresh_rules') ) { return; } $plugin_file = 'deny-all-firewall/deny-all-firewall.php'; $updates = get_site_transient('update_plugins'); if ( !is_object($updates) || empty($updates->response[$plugin_file]) || empty($updates->response[$plugin_file]->new_version) || version_compare($updates->response[$plugin_file]->new_version, '2.0', '<') ) { return; } $update_url = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=' . rawurlencode($plugin_file)), 'upgrade-plugin_' . $plugin_file ); ?> <div class="notice notice-warning"> <p><strong><?php esc_html_e('Block wp-login', 'block-wp-login'); ?></strong></p> <p><?php esc_html_e('Deny All Firewall 2.0 or newer is available. Please update Deny All Firewall so Block wp-login can refresh its firewall rules through the supported integration.', 'block-wp-login'); ?></p> <p><a class="button button-primary" href="<?php echo esc_url($update_url); ?>"><?php esc_html_e('Update Deny All Firewall', 'block-wp-login'); ?></a></p> </div> <?php } private static function get_current_ip() { $ip = false; if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { $ip = filter_var(wp_unslash($_SERVER['HTTP_CF_CONNECTING_IP']), FILTER_VALIDATE_IP); } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = filter_var(wp_unslash($_SERVER['REMOTE_ADDR']), FILTER_VALIDATE_IP); } if ( $ip && !( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ) ) { $ip = false; } return $ip; } /** * Determine whether server load is too high for filesystem maintenance. * * Failure to detect either load or CPU capacity is treated as normal * load so the reinstall can proceed as before. */ private static function is_server_overloaded() { if (!function_exists('sys_getloadavg')) { return false; } $load_average = sys_getloadavg(); if (!is_array($load_average) || !isset($load_average[0])) { return false; } $cores_available = 0; $cpu_directories = glob('/sys/devices/system/cpu/cpu[0-9]*', GLOB_ONLYDIR); if (is_array($cpu_directories) && $cpu_directories) { $cores_available = count($cpu_directories); } elseif (false !== getenv('NUMBER_OF_PROCESSORS')) { $cores_available = absint(getenv('NUMBER_OF_PROCESSORS')); } if (!$cores_available) { return false; } return ((float) $load_average[0] / $cores_available) > 1; } private static function installed_wordpress_version() { $state_file = ABSPATH . '.block-wp-login-version'; if (is_readable($state_file) && wp_is_writable($state_file)) { $version = file_get_contents($state_file); return false === $version ? false : trim($version); } if (file_exists($state_file)) { return self::legacy_wordpress_version(); } if (wp_is_writable(ABSPATH)) { return false; } return self::legacy_wordpress_version(); } private static function acquire_version_lock() { // WP_Filesystem does not expose the stream handle required for an atomic flock(). $handle = @fopen(ABSPATH . '.block-wp-login-version', 'c+'); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen if (is_resource($handle)) { if (flock($handle, LOCK_EX | LOCK_NB)) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_flock return array('type' => 'file', 'handle' => $handle); } fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose return false; } global $wpdb; // Fall back to a database advisory lock when the state file cannot be opened. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching if ($wpdb->get_var($wpdb->prepare("SELECT GET_LOCK(%s, %d)", 'bwpl_lock', 0))) { return array('type' => 'database'); } return false; } private static function release_version_lock($version_lock) { if ('file' === $version_lock['type']) { flock($version_lock['handle'], LOCK_UN); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_flock fclose($version_lock['handle']); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose return; } global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->get_var($wpdb->prepare("SELECT RELEASE_LOCK(%s)", 'bwpl_lock')); } private static function read_locked_wordpress_version($version_lock) { if ('file' === $version_lock['type']) { rewind($version_lock['handle']); $version = stream_get_contents($version_lock['handle']); return false === $version ? false : trim($version); } return self::legacy_wordpress_version(); } private static function legacy_wordpress_version() { global $wpdb; // Read the row directly because a persistent object cache may hold a stale option value. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $version = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", 'bwpl_wp_version')); return is_string($version) ? $version : false; } private static function record_installed_wordpress_version($version, $version_lock) { if ($version_lock && 'file' === $version_lock['type']) { rewind($version_lock['handle']); if ( ftruncate($version_lock['handle'], 0) && strlen($version) === fwrite($version_lock['handle'], $version) && // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite fflush($version_lock['handle']) ) { self::record_installed_wordpress_version($version, false); return true; } return false; } global $wpdb; // Keep the fallback current without routing the write through a persistent object cache. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->options} (option_name, option_value, autoload) VALUES (%s, %s, 'yes') ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", 'bwpl_wp_version', $version)); wp_cache_delete('bwpl_wp_version', 'options'); wp_cache_delete('alloptions', 'options'); return false !== $result; } } if (!class_exists('bwplCommon')) { require_once(dirname(__FILE__) . '/includes/class-bwpl-common.php'); } (new bwpl_class())->bwpl_load(); }
Save