先创建个loginlockdown.php文件,然后你可以选择把此文件放到主题根目录或者创建个login文件夹把此PHP文件扔进去。
首先这个插件是非常简单的就一个PHP文件,我们直接在我们的函数文件引用它即可打开你的主题functions.php文件:
//如果你放置不是主题根目录修改'/这里是具体目录/loginlockdown.php'
require get_stylesheet_directory() . '/loginlockdown.php';
因为之前我们只做了一个PHP文件以及配置好了引用,但是PHP的loginlockdown.php文件还是空的,我们需要把以下代码丢入其原英文我瑞课已经给翻译成中文了不要担心翻译。
$loginlockdown_db_version = "1.0";
$loginlockdownOptions = get_loginlockdownOptions();
function loginLockdown_install() {
global $wpdb;
global $loginlockdown_db_version;
$table_name = $wpdb->prefix . "login_fails";
if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name ) {
$sql = "CREATE TABLE " . $table_name . " (
`login_attempt_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`login_attempt_date` datetime NOT NULL default '0000-00-00 00:00:00',
`login_attempt_IP` varchar(100) NOT NULL default '',
PRIMARY KEY (`login_attempt_ID`)
);";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
$table_name = $wpdb->prefix . "lockdowns";
if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name ) {
$sql = "CREATE TABLE " . $table_name . " (
`lockdown_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`lockdown_date` datetime NOT NULL default '0000-00-00 00:00:00',
`release_date` datetime NOT NULL default '0000-00-00 00:00:00',
`lockdown_IP` varchar(100) NOT NULL default '',
PRIMARY KEY (`lockdown_ID`)
);";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
add_option("loginlockdown_db_version", "1.0", "", "no");
// added in 1.6, cleanup from previously improperly set db versions
delete_option( "loginlockdown_db1_version" );
delete_option( "loginlockdown_db2_version" );
}
function countFails($username = "") {
global $wpdb;
global $loginlockdownOptions;
$table_name = $wpdb->prefix . "login_fails";
$subnet = calc_subnet($_SERVER['REMOTE_ADDR']);
$numFailsquery = "SELECT COUNT(login_attempt_ID) FROM $table_name " .
"WHERE login_attempt_date + INTERVAL " .
$loginlockdownOptions['retries_within'] . " MINUTE > now() AND " .
"login_attempt_IP LIKE '%s'";
$numFailsquery = $wpdb->prepare( $numFailsquery, $subnet[1] . "%");
$numFails = $wpdb->get_var($numFailsquery);
return $numFails;
}
function incrementFails($username = "") {
global $wpdb;
global $loginlockdownOptions;
$table_name = $wpdb->prefix . "login_fails";
$subnet = calc_subnet($_SERVER['REMOTE_ADDR']);
$username = sanitize_user($username);
$user = get_user_by('login',$username);
if ( $user || "yes" == $loginlockdownOptions['lockout_invalid_usernames'] ) {
if ( $user === false ) {
$user_id = -1;
} else {
$user_id = $user->ID;
}
$insert = "INSERT INTO " . $table_name . " (user_id, login_attempt_date, login_attempt_IP) " .
"VALUES ('" . $user_id . "', now(), '%s')";
$insert = $wpdb->prepare( $insert, $subnet[0] );
$results = $wpdb->query($insert);
}
}
function lockDown($username = "") {
global $wpdb;
global $loginlockdownOptions;
$table_name = $wpdb->prefix . "lockdowns";
$subnet = calc_subnet($_SERVER['REMOTE_ADDR']);
$username = sanitize_user($username);
$user = get_user_by('login',$username);
if ( $user || "yes" == $loginlockdownOptions['lockout_invalid_usernames'] ) {
if ( $user === false ) {
$user_id = -1;
} else {
$user_id = $user->ID;
}
$insert = "INSERT INTO " . $table_name . " (user_id, lockdown_date, release_date, lockdown_IP) " .
"VALUES ('" . $user_id . "', now(), date_add(now(), INTERVAL " .
$loginlockdownOptions['lockout_length'] . " MINUTE), '%s')";
$insert = $wpdb->prepare( $insert, $subnet[0] );
$results = $wpdb->query($insert);
}
}
function isLockedDown() {
global $wpdb;
$table_name = $wpdb->prefix . "lockdowns";
$subnet = calc_subnet($_SERVER['REMOTE_ADDR']);
$stillLockedquery = "SELECT user_id FROM $table_name " .
"WHERE release_date > now() AND " .
"lockdown_IP LIKE %s";
$stillLockedquery = $wpdb->prepare($stillLockedquery,$subnet[1] . "%");
$stillLocked = $wpdb->get_var($stillLockedquery);
return $stillLocked;
}
function listLockedDown() {
global $wpdb;
$table_name = $wpdb->prefix . "lockdowns";
$listLocked = $wpdb->get_results("SELECT lockdown_ID, floor((UNIX_TIMESTAMP(release_date)-UNIX_TIMESTAMP(now()))/60) AS minutes_left, ".
"lockdown_IP FROM $table_name WHERE release_date > now()", ARRAY_A);
return $listLocked;
}
function get_loginlockdownOptions() {
$loginlockdownAdminOptions = array(
'max_login_retries' => 3,
'retries_within' => 5,
'lockout_length' => 60,
'lockout_invalid_usernames' => 'no',
'mask_login_errors' => 'no',
'show_credit_link' => 'yes'
);
$loginlockdownOptions = get_option("loginlockdownAdminOptions");
if ( !empty($loginlockdownOptions) ) {
foreach ( $loginlockdownOptions as $key => $option ) {
$loginlockdownAdminOptions[$key] = $option;
}
}
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
return $loginlockdownAdminOptions;
}
function calc_subnet($ip) {
$subnet[0] = $ip;
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$ip = expandipv6($ip);
preg_match("/^([0-9abcdef]{1,4}:){4}/", $ip, $matches);
$subnet[0] = $ip;
$subnet[1] = $matches[0];
} else {
$subnet[1] = substr ($ip, 0 , strrpos ( $ip, "." ) + 1);
}
return $subnet;
}
function expandipv6($ip){
$hex = unpack("H*hex", inet_pton($ip));
$ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1);
return $ip;
}
function print_loginlockdownAdminPage() {
global $wpdb;
$table_name = $wpdb->prefix . "lockdowns";
$loginlockdownAdminOptions = get_loginlockdownOptions();
if (isset($_POST['update_loginlockdownSettings'])) {
//wp_nonce check
check_admin_referer('login-lockdown_update-options');
if (isset($_POST['ll_max_login_retries'])) {
$loginlockdownAdminOptions['max_login_retries'] = $_POST['ll_max_login_retries'];
}
if (isset($_POST['ll_retries_within'])) {
$loginlockdownAdminOptions['retries_within'] = $_POST['ll_retries_within'];
}
if (isset($_POST['ll_lockout_length'])) {
$loginlockdownAdminOptions['lockout_length'] = $_POST['ll_lockout_length'];
}
if (isset($_POST['ll_lockout_invalid_usernames'])) {
$loginlockdownAdminOptions['lockout_invalid_usernames'] = $_POST['ll_lockout_invalid_usernames'];
}
if (isset($_POST['ll_mask_login_errors'])) {
$loginlockdownAdminOptions['mask_login_errors'] = $_POST['ll_mask_login_errors'];
}
if (isset($_POST['ll_show_credit_link'])) {
$loginlockdownAdminOptions['show_credit_link'] = $_POST['ll_show_credit_link'];
}
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
?>
<div class="updated"><p><strong><?php _e("设置更新.", "loginlockdown");?></strong></p></div>
<?php
}
if (isset($_POST['release_lockdowns'])) {
//wp_nonce check
check_admin_referer('login-lockdown_release-lockdowns');
if (isset($_POST['releaseme'])) {
$released = $_POST['releaseme'];
foreach ( $released as $release_id ) {
$releasequery = "UPDATE $table_name SET release_date = now() " .
"WHERE lockdown_ID = '%d'";
$releasequery = $wpdb->prepare($releasequery,$release_id);
$results = $wpdb->query($releasequery);
}
}
update_option("loginlockdownAdminOptions", $loginlockdownAdminOptions);
?>
<div class="updated"><p><strong><?php _e("锁定发布.", "loginlockdown");?></strong></p></div>
<?php
}
$dalist = listLockedDown();
?>
<div class="wrap">
<?php
$active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'settings';
?>
<h2><?php _e('登录LockDown选项', 'loginlockdown') ?></h2>
<h2 class="nav-tab-wrapper">
<a href="?page=loginlockdown.php&tab=settings" class="nav-tab <?php echo $active_tab == 'settings' ? 'nav-tab-active' : ''; ?>">设置</a>
<a href="?page=loginlockdown.php&tab=activity" class="nav-tab <?php echo $active_tab == 'activity' ? 'nav-tab-active' : ''; ?>">活动 (<?php echo count($dalist); ?>)</a>
</h2>
<?php if ( $active_tab == 'settings' ) { ?>
<form method="post" action="<?php echo esc_attr($_SERVER["REQUEST_URI"]); ?>">
<?php
if ( function_exists('wp_nonce_field') )
wp_nonce_field('login-lockdown_update-options');
?>
<h3><?php _e('最大登录重试次数', 'loginlockdown') ?></h3>
<p>触发LockDown所需的“重试时间段限制”(定义如下)中失败的登录尝试次数.</p>
<p><input type="text" name="ll_max_login_retries" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['max_login_retries']); ?>"></p>
<h3><?php _e('重试时间限制(分钟)', 'loginlockdown') ?></h3>
<p>确定在发生LockDown之前允许登录尝试失败的速率的时间量。</p>
<p><input type="text" name="ll_retries_within" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['retries_within']); ?>"></p>
<h3><?php _e('锁定长度(分钟)', 'loginlockdown') ?></h3>
<p>LockDown被触发后,特定IP块将被锁定多久。</p>
<p><input type="text" name="ll_lockout_length" size="8" value="<?php echo esc_attr($loginlockdownAdminOptions['lockout_length']); ?>"></p>
<h3><?php _e('锁定无效的用户名?', 'loginlockdown') ?></h3>
<p>默认情况下,如果尝试使用不存在的用户名登录,登录锁定将不会触发。 您可以在此覆盖此行为。</p>
<p><input type="radio" name="ll_lockout_invalid_usernames" value="yes" <?php if( $loginlockdownAdminOptions['lockout_invalid_usernames'] == "yes" ) echo "checked"; ?>> Yes <input type="radio" name="ll_lockout_invalid_usernames" value="no" <?php if( $loginlockdownAdminOptions['lockout_invalid_usernames'] == "no" ) echo "checked"; ?>> No</p>
<h3><?php _e('隐藏登录错误?', 'loginlockdown') ?></h3>
<p>WordPress通常会向用户显示不同的消息,具体取决于他们是否尝试使用无效的用户名登录,或者使用
有效的用户名,但密码不正确。 切换此选项将会隐藏登录失败的原因.</p>
<p><input type="radio" name="ll_mask_login_errors" value="yes" <?php if( $loginlockdownAdminOptions['mask_login_errors'] == "yes" ) echo "checked"; ?>> Yes <input type="radio" name="ll_mask_login_errors" value="no" <?php if( $loginlockdownAdminOptions['mask_login_errors'] == "no" ) echo "checked"; ?>> No</p>
<h3><?php _e('显示信任链接?', 'loginlockdown') ?></h3>
<p>默认情况下,登录锁定将在登录表单上显示以下消息:<br />
<blockquote>登录表单受保护.</blockquote>
这有助于其他人了解插件,以便他们可以保护他们的博客,如果他们喜欢。 但是,如果您愿意,您可以禁用此消息.</p>
<input type="radio" name="ll_show_credit_link" value="yes" <?php if( $loginlockdownAdminOptions['show_credit_link'] == "yes" || $loginlockdownAdminOptions['show_credit_link'] == "" ) echo "checked"; ?>> 是的,显示信任链接.<br />
<input type="radio" name="ll_show_credit_link" value="shownofollow" <?php if( $loginlockdownAdminOptions['show_credit_link'] == "shownofollow" ) echo "checked"; ?>> 显示信任链接,但添加nofollow.<br />
<input type="radio" name="ll_show_credit_link" value="no" <?php if( $loginlockdownAdminOptions['show_credit_link'] == "no" ) echo "checked"; ?>> 不,不显示信任链接.<br />
<div class="submit">
<input type="submit" class="button button-primary" name="update_loginlockdownSettings" value="<?php _e('更新设置', 'loginlockdown') ?>" /></div>
</form>
<?php } else { ?>
<form method="post" action="<?php echo esc_attr($_SERVER["REQUEST_URI"]); ?>">
<?php
if ( function_exists('wp_nonce_field') )
wp_nonce_field('login-lockdown_release-lockdowns');
?>
<h3><?php
if( count($dalist) == 1 ) {
printf( esc_html__( '目前有 %d锁定IP地址.', 'loginlockdown' ), count($dalist) );
} else {
printf( esc_html__( '目前有 %d个锁定的IP地址.', 'loginlockdown' ), count($dalist) );
} ?></h3>
<?php
$num_lockedout = count($dalist);
if( 0 == $num_lockedout ) {
echo "<p>当前没有IP块被锁定.</p>";
} else {
foreach ( $dalist as $key => $option ) {
?>
<li><input type="checkbox" name="releaseme[]" value="<?php echo esc_attr($option['lockdown_ID']); ?>"> <?php echo esc_attr($option['lockdown_IP']); ?> (<?php echo esc_attr($option['minutes_left']); ?> 分钟)</li>
<?php
}
}
?>
<div class="submit">
<input type="submit" class="button button-primary" name="release_lockdowns" value="<?php _e('发布选定', 'loginlockdown') ?>" /></div>
</form>
<?php } ?>
</div>
<?php
}//结束函数print_loginlockdownAdminPage()
function loginlockdown_ap() {
if ( function_exists('add_options_page') ) {
add_options_page('Login LockDown', '登录限制管理', 'manage_options', basename(__FILE__), 'print_loginlockdownAdminPage');
}
}
function ll_credit_link(){
global $loginlockdownOptions;
$thispage = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$homepage = get_option( "home" );
$showcreditlink = $loginlockdownOptions['show_credit_link'];
$relnofollow = "rel='nofollow'";
if ( $showcreditlink != "shownofollow" && ($thispage == $homepage || $thispage == $homepage . "/" || substr($_SERVER["REQUEST_URI"], strlen($_SERVER["REQUEST_URI"]) - 12) == "wp-login.php") ) {
$relnofollow = "";
}
if ( $showcreditlink != "no" ) {
echo "<p>登录表单受保护.<br /><br /><br /></p>";
}
}
//动作和过滤器
if ( isset($loginlockdown_db_version) ) {
//Actions
add_action('admin_menu', 'loginlockdown_ap');
if(!defined('WP_PLUGIN_DIR')){
define('WP_PLUGIN_DIR', get_template_directory());
}
$activatestr = str_replace(WP_PLUGIN_DIR . "/", "activate_", __FILE__);
add_action($activatestr, 'loginLockdown_install');
add_action('login_form', 'll_credit_link');
remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
add_filter('authenticate', 'll_wp_authenticate_username_password', 20, 3);
//Filters
//Functions
function ll_wp_authenticate_username_password($user, $username, $password) {
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) ) {
$error = new WP_Error();
if ( empty($username) )
$error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));
if ( empty($password) )
$error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
return $error;
}
$userdata = get_user_by('login',$username);
if ( !$userdata ) {
return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), site_url('wp-login.php?action=lostpassword', 'login')));
}
$userdata = apply_filters('wp_authenticate_user', $userdata, $password);
if ( is_wp_error($userdata) ) {
return $userdata;
}
if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) {
return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: Incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), site_url('wp-login.php?action=lostpassword', 'login')));
}
$user = new WP_User($userdata->ID);
return $user;
}
if ( !function_exists('wp_authenticate') ) :
function wp_authenticate($username, $password) {
global $wpdb, $error;
global $loginlockdownOptions;
$username = sanitize_user($username);
$password = trim($password);
if ( "" != isLockedDown() ) {
return new WP_Error('incorrect_password', "<strong>ERROR</strong>: We're sorry, but this IP range has been blocked due to too many recent " .
"failed login attempts.<br /><br />Please try again later.");
}
$user = apply_filters('authenticate', null, $username, $password);
if ( $user == null ) {
// TODO what should the error message be? (Or would these even happen?)
// Only needed if all authentication handlers fail to return anything.
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
}
$ignore_codes = array('empty_username', 'empty_password');
if (is_wp_error($user) && !in_array($user->get_error_code(), $ignore_codes) ) {
incrementFails($username);
if ( $loginlockdownOptions['max_login_retries'] <= countFails($username) ) {
lockDown($username);
return new WP_Error('incorrect_password', __("<strong>ERROR</strong>: We're sorry, but this IP range has been blocked due to too many recent " .
"failed login attempts.<br /><br />Please try again later."));
}
if ( 'yes' == $loginlockdownOptions['mask_login_errors'] ) {
return new WP_Error('authentication_failed', sprintf(__('<strong>ERROR</strong>: Invalid username or incorrect password. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), site_url('wp-login.php?action=lostpassword', 'login')));
} else {
do_action('wp_login_failed', $username);
}
}
return $user;
}
endif;
// 多站点全网激活
register_activation_hook( __FILE__, 'loginlockdown_multisite_activate' );
function loginlockdown_multisite_activate($networkwide) {
global $wpdb;
if (function_exists('is_multisite') && is_multisite()) {
// check if it is a network activation - if so, run the activation function for each blog id
if ($networkwide) {
$old_blog = $wpdb->blogid;
// Get all blog ids
$blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach ($blogids as $blog_id) {
switch_to_blog($blog_id);
loginLockdown_install();
}
switch_to_blog($old_blog);
return;
}
}
}
// 多站点新站点激活
add_action( 'wpmu_new_blog', 'loginlockdown_multisite_newsite', 10, 6);
function loginlockdown_multisite_newsite($blog_id, $user_id, $domain, $path, $site_id, $meta ) {
global $wpdb;
if (is_plugin_active_for_network('loginlockdown/loginlockdown.php')) {
$old_blog = $wpdb->blogid;
switch_to_blog($blog_id);
loginLockdown_install();
switch_to_blog($old_blog);
}
}
// 多站点旧站点检查
add_action('admin_init','loginlockdown_multisite_legacy');
function loginlockdown_multisite_legacy() {
$loginlockdownMSRunOnce = get_option("loginlockdownmsrunonce");
if ( empty($loginlockdownMSRunOnce) ) {
global $wpdb;
if (function_exists('is_multisite') && is_multisite()) {
$old_blog = $wpdb->blogid;
// Get all blog ids
$blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
foreach ($blogids as $blog_id) {
// check if already exists
$bed_check = $wpdb->query("SHOW TABLES LIKE '{$wpdb->base_prefix}{$blog_id}_login_fails'");
if (!$bed_check) {
switch_to_blog($blog_id);
loginLockdown_install();
}
}
switch_to_blog($old_blog);
}
add_option("loginlockdownmsrunonce", "done", "", "no");
return;
}
}
}
1 2

