diff options
Diffstat (limited to 'plugins/jetpack/modules/protect.php')
-rw-r--r-- | plugins/jetpack/modules/protect.php | 148 |
1 files changed, 96 insertions, 52 deletions
diff --git a/plugins/jetpack/modules/protect.php b/plugins/jetpack/modules/protect.php index 1677e2b9..a47a1af9 100644 --- a/plugins/jetpack/modules/protect.php +++ b/plugins/jetpack/modules/protect.php @@ -58,7 +58,7 @@ class Jetpack_Protect_Module { add_action( 'admin_init', array ( $this, 'maybe_display_security_warning' ) ); // This is a backup in case $pagenow fails for some reason - add_action( 'login_head', array ( $this, 'check_login_ability' ) ); + add_action( 'login_head', array ( $this, 'check_login_ability' ), 100, 3 ); // Runs a script every day to clean up expired transients so they don't // clog up our users' databases @@ -427,6 +427,47 @@ class Jetpack_Protect_Module { * @return bool Either returns true, fires $this->kill_login, or includes a math fallback and returns false */ function check_login_ability( $preauth = false ) { + + /** + * JETPACK_ALWAYS_PROTECT_LOGIN will always disable the login page, and use a page provided by Jetpack. + */ + if ( defined( 'JETPACK_ALWAYS_PROTECT_LOGIN' ) && JETPACK_ALWAYS_PROTECT_LOGIN ) { + $this->kill_login(); + } + + if ( $this->is_current_ip_whitelisted() ) { + return true; + } + + $status = $this->get_cached_status(); + + if ( empty( $status ) ) { + // If we've reached this point, this means that the IP isn't cached. + // Now we check with the Protect API to see if we should allow login + $response = $this->protect_call( $action = 'check_ip' ); + + if ( isset( $response['math'] ) && ! function_exists( 'brute_math_authenticate' ) ) { + include_once dirname( __FILE__ ) . '/protect/math-fallback.php'; + new Jetpack_Protect_Math_Authenticate; + + return false; + } + + $status = $response['status']; + } + + if ( 'blocked' == $status ) { + $this->block_with_math(); + } + + if ( 'blocked-hard' == $status ) { + $this->kill_login(); + } + + return true; + } + + function is_current_ip_whitelisted() { $ip = jetpack_protect_get_ip(); // Server is misconfigured and we can't get an IP @@ -455,11 +496,6 @@ class Jetpack_Protect_Module { return true; } - $headers = $this->get_headers(); - $header_hash = md5( json_encode( $headers ) ); - $transient_name = 'jpp_li_' . $header_hash; - $transient_value = $this->get_transient( $transient_name ); - if ( jetpack_protect_ip_is_private( $ip ) ) { return true; } @@ -467,40 +503,26 @@ class Jetpack_Protect_Module { if ( $this->ip_is_whitelisted( $ip ) ) { return true; } + } - // Check out our transients - if ( isset( $transient_value ) && 'ok' == $transient_value['status'] ) { - return true; - } - - if ( isset( $transient_value ) && 'blocked' == $transient_value['status'] ) { - $this->block_with_math(); - } - - if ( isset( $transient_value ) && 'blocked-hard' == $transient_value['status'] ) { - $this->kill_login(); - } - - // If we've reached this point, this means that the IP isn't cached. - // Now we check with the Protect API to see if we should allow login - $response = $this->protect_call( $action = 'check_ip' ); + function has_login_ability() { + if ( $this->is_current_ip_whitelisted() ) { + return true; + } + $status = $this->get_cached_status(); + if ( empty( $status ) || $status === 'ok' ) { + return true; + } + return false; + } - if ( isset( $response['math'] ) && ! function_exists( 'brute_math_authenticate' ) ) { - include_once dirname( __FILE__ ) . '/protect/math-fallback.php'; - new Jetpack_Protect_Math_Authenticate; - - return false; - } - - if ( 'blocked' == $response['status'] ) { - $this->block_with_math(); - } - - if ( 'blocked-hard' == $response['status'] ) { - $this->kill_login(); - } - - return true; + function get_cached_status() { + $transient_name = $this->get_transient_name(); + $value = $this->get_transient( $transient_name ); + if ( isset( $value['status'] ) ) { + return $value['status']; + } + return ''; } function block_with_math() { @@ -541,6 +563,17 @@ class Jetpack_Protect_Module { * Kill a login attempt */ function kill_login() { + if ( + isset( $_GET['action'], $_GET['_wpnonce'] ) && + 'logout' === $_GET['action'] && + wp_verify_nonce( $_GET['_wpnonce'], 'log-out' ) && + wp_get_current_user() + + ) { + // Allow users to logout + return; + } + $ip = jetpack_protect_get_ip(); /** * Fires before every killed login. @@ -552,19 +585,24 @@ class Jetpack_Protect_Module { * @param string $ip IP flagged by Protect. */ do_action( 'jpp_kill_login', $ip ); - $help_url = 'https://jetpack.com/support/security-features/#unblock'; - - $die_string = sprintf( __( 'Your IP (%1$s) has been flagged for potential security violations. <a href="%2$s">Find out more...</a>', 'jetpack' ), str_replace( 'http://', '', esc_url( 'http://' . $ip ) ), esc_url( $help_url ) ); if( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) { $die_string = sprintf( __( 'Your IP (%1$s) has been flagged for potential security violations.', 'jetpack' ), str_replace( 'http://', '', esc_url( 'http://' . $ip ) ) ); + wp_die( + $die_string, + __( 'Login Blocked by Jetpack', 'jetpack' ), + array ( 'response' => 403 ) + ); } - wp_die( - $die_string, - __( 'Login Blocked by Jetpack', 'jetpack' ), - array ( 'response' => 403 ) - ); + require_once dirname( __FILE__ ) . '/protect/blocked-login-page.php'; + $blocked_login_page = Jetpack_Protect_Blocked_Login_Page::instance( $ip ); + + if ( $blocked_login_page->is_blocked_user_valid() ) { + return; + } + + $blocked_login_page->render_and_die(); } /* @@ -681,7 +719,7 @@ class Jetpack_Protect_Module { * @return array */ function protect_call( $action = 'check_ip', $request = array () ) { - global $wp_version, $wpdb, $current_user; + global $wp_version; $api_key = $this->maybe_get_protect_key(); @@ -721,9 +759,8 @@ class Jetpack_Protect_Module { $response_json = wp_remote_post( $this->get_api_host(), $args ); $this->last_response_raw = $response_json; - $headers = $this->get_headers(); - $header_hash = md5( json_encode( $headers ) ); - $transient_name = 'jpp_li_' . $header_hash; + + $transient_name = $this->get_transient_name(); $this->delete_transient( $transient_name ); if ( is_array( $response_json ) ) { @@ -753,6 +790,12 @@ class Jetpack_Protect_Module { return $response; } + function get_transient_name() { + $headers = $this->get_headers(); + $header_hash = md5( json_encode( $headers ) ); + + return 'jpp_li_' . $header_hash; + } /** * Wrapper for WordPress set_transient function, our version sets @@ -862,8 +905,9 @@ class Jetpack_Protect_Module { } -Jetpack_Protect_Module::instance(); +$jetpack_protect = Jetpack_Protect_Module::instance(); +global $pagenow; if ( isset( $pagenow ) && 'wp-login.php' == $pagenow ) { - Jetpack_Protect_Module::check_login_ability(); + $jetpack_protect->check_login_ability(); } |