siteguard-admin-filter.php
11 years ago
siteguard-base.php
11 years ago
siteguard-captcha.php
11 years ago
siteguard-config.php
11 years ago
siteguard-disable-pingback.php
11 years ago
siteguard-htaccess.php
11 years ago
siteguard-login-history.php
11 years ago
siteguard-login-lock.php
11 years ago
siteguard-rename-login.php
11 years ago
siteguard-waf-exclude-rule.php
11 years ago
siteguard-login-lock.php
126 lines
| 1 | <?php |
| 2 | |
| 3 | class SiteGuard_LoginLock extends SiteGuard_Base { |
| 4 | var $status = SITEGUARD_LOGIN_FAILED; |
| 5 | function __construct( ) { |
| 6 | global $config; |
| 7 | if ( '1' == $config->get( 'loginlock_enable' ) ) { |
| 8 | add_action( 'wp_login_failed', array( $this, 'handler_wp_login_failed' ) ); |
| 9 | add_filter( 'authenticate', array( $this, 'handler_authenticate' ), 20, 3 ); |
| 10 | } |
| 11 | if ( $config->get( 'loginlock_fail_once' ) ) { |
| 12 | add_filter( 'wp_authenticate_user', array( $this, 'handler_wp_authenticate_user' ), 99, 2 ); |
| 13 | } |
| 14 | } |
| 15 | function init( ) { |
| 16 | global $config; |
| 17 | $config->set( 'loginlock_enable', '1' ); |
| 18 | $config->set( 'loginlock_interval', '5' ); |
| 19 | $config->set( 'loginlock_threshold', '3' ); |
| 20 | $config->set( 'loginlock_locksec', '60' ); |
| 21 | $config->set( 'loginlock_fail_once', '0' ); |
| 22 | $config->set( 'fail_once_admin_only', '1' ); |
| 23 | $config->update( ); |
| 24 | } |
| 25 | function get_status( ) { |
| 26 | return $this->status; |
| 27 | } |
| 28 | function handler_wp_login_failed( $username ) { |
| 29 | global $wpdb, $config, $login_history; |
| 30 | $table_name = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 31 | |
| 32 | $ip_address = $_SERVER['REMOTE_ADDR']; |
| 33 | |
| 34 | $wpdb->query( 'START TRANSACTION' ); |
| 35 | $wpdb->query( "DELETE FROM $table_name WHERE status <> 1 AND last_login_time < SYSDATE() - INTERVAL 1 HOUR;" ); |
| 36 | $result = $wpdb->get_row( $wpdb->prepare( "SELECT status, count, last_login_time from $table_name WHERE ip_address = %s", $ip_address ) ); |
| 37 | $data = array( |
| 38 | 'ip_address' => $ip_address, |
| 39 | 'status' => SITEGUARD_LOGIN_FAILED, |
| 40 | 'count' => 1, |
| 41 | 'last_login_time' => 0, |
| 42 | ); |
| 43 | $now_str = current_time( 'mysql' ); |
| 44 | $now_bin = strtotime( $now_str ); |
| 45 | if ( null == $result ) { |
| 46 | $data['last_login_time'] = $now_str; |
| 47 | $wpdb->insert( $table_name, $data ); |
| 48 | } else { |
| 49 | $data['last_login_time'] = $result->last_login_time; |
| 50 | $interval = intval( $config->get( 'loginlock_interval' ) ); |
| 51 | $limit = strtotime( $result->last_login_time ) + $interval; |
| 52 | if ( SITEGUARD_LOGIN_FAILED == $result->status ) { |
| 53 | if ( $now_bin <= $limit ) { |
| 54 | $data['count'] = $result->count + 1; |
| 55 | } else { |
| 56 | $data['count'] = 1; |
| 57 | $data['last_login_time'] = $now_str; |
| 58 | } |
| 59 | if ( $data['count'] >= intval( $config->get( 'loginlock_threshold' ) ) ) { |
| 60 | $data['status'] = SITEGUARD_LOGIN_LOCKED; |
| 61 | $data['last_login_time'] = $now_str; |
| 62 | $this->status = SITEGUARD_LOGIN_LOCKED; |
| 63 | } |
| 64 | $wpdb->update( $table_name, $data, array( 'ip_address' => $ip_address ) ); |
| 65 | } else if ( SITEGUARD_LOGIN_FAIL_ONCE == $result->status || ( SITEGUARD_LOGIN_LOCKED == $result->status && $now_bin > strtotime( $result->last_login_time ) + intval( $config->get( 'loginlock_locksec' ) ) ) ) { |
| 66 | $data['status'] = SITEGUARD_LOGIN_FAILED; |
| 67 | $data['count'] = 1; |
| 68 | $data['last_login_time'] = $now_str; |
| 69 | $wpdb->update( $table_name, $data, array( 'ip_address' => $ip_address ) ); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | $wpdb->query( 'COMMIT' ); |
| 74 | |
| 75 | return; |
| 76 | } |
| 77 | function is_locked( $ip_address ) { |
| 78 | global $wpdb, $config; |
| 79 | |
| 80 | $now_bin = strtotime( current_time( 'mysql' ) ); |
| 81 | $table_name = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 82 | $result = $wpdb->get_row( $wpdb->prepare( "SELECT status, last_login_time from $table_name WHERE ip_address = %s", $ip_address ) ); |
| 83 | if ( null != $result ) { |
| 84 | if ( SITEGUARD_LOGIN_LOCKED == $result->status && $now_bin <= strtotime( $result->last_login_time ) + intval( $config->get( 'loginlock_locksec' ) ) ) { |
| 85 | return true; |
| 86 | } |
| 87 | } |
| 88 | return false; |
| 89 | } |
| 90 | function handler_authenticate( $user, $username, $password ) { |
| 91 | if ( $this->is_locked( $_SERVER['REMOTE_ADDR'] ) ) { |
| 92 | $new_errors = new WP_Error( ); |
| 93 | $new_errors->add( 'siteguard-error', esc_html__( 'ERROR: LOGIN LOCKED', 'siteguard' ) ); |
| 94 | $this->status = SITEGUARD_LOGIN_LOCKED; |
| 95 | return $new_errors; |
| 96 | } |
| 97 | return $user; |
| 98 | } |
| 99 | function handler_wp_authenticate_user( $user, $password ) { |
| 100 | global $login_history, $config; |
| 101 | |
| 102 | // Login failed |
| 103 | if ( is_wp_error( $user ) ) { |
| 104 | return $user; |
| 105 | } |
| 106 | if ( '1' == $config->get( 'fail_once_admin_only' ) ) { |
| 107 | if ( ! $user->has_cap( 'administrator' ) ) { |
| 108 | return $user; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | $user_login = $user->user_login; |
| 113 | |
| 114 | if ( ! $login_history->is_exist( $user_login, SITEGUARD_LOGIN_FAIL_ONCE, 5/* secs after */, 60/* secs less */ ) ) { |
| 115 | $this->status = SITEGUARD_LOGIN_FAIL_ONCE; |
| 116 | |
| 117 | $new_error = new WP_Error( ); |
| 118 | $new_error->add( 'siteguard-error', esc_html__( 'ERROR: Please login entry again', 'siteguard' ) ); |
| 119 | return $new_error; |
| 120 | } |
| 121 | return $user; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | ?> |
| 126 |