get_option( 'patchstack_license_free', 0 ) == 1 ) { return; } add_action( 'init', [ $this, 'ip_ban' ], ~PHP_INT_MAX + 1 ); } /** * Determine if the IP address of the user is blocked. * * @return void */ public function ip_ban() { if ( ! is_user_logged_in() && $this->is_ip_blocked( $this->get_ip() ) ) { $this->plugin->firewall_base->display_error_page( 22 ); } } /** * Check IP ban. * * @param string $ip The IP address of the user. * @return boolean Whether or not the user is blocked. */ public function is_ip_blocked( $ip ) { $ip_rules = $this->get_option( 'patchstack_ip_block_list', '' ); if ( empty( $ip_rules ) ) { return false; } $blocked = false; $ip_rules = explode( "\n", $ip_rules ); foreach ( $ip_rules as $blocked_ip ) { $blocked_ip = trim( $blocked_ip ); if ( strpos( $blocked_ip, '*' ) !== false ) { $blocked = $this->check_wildcard_rule( $ip, $blocked_ip ); } elseif ( strpos( $blocked_ip, '-' ) !== false ) { $blocked = $this->check_range_rule( $ip, $blocked_ip ); } elseif ( strpos( $blocked_ip, '/' ) !== false ) { $blocked = $this->check_subnet_mask_rule( $ip, $blocked_ip ); } elseif ( $ip == $blocked_ip ) { return true; } if ( $blocked ) { return true; } } return $blocked; } /** * Check IP whitelist for login protection. * * @param string $ip The IP address of the user. * @return boolean Whether or not the user is whitelisted. */ public function is_ip_whitelisted( $ip ) { $ipRules = explode( "\n", $this->get_option( 'patchstack_login_whitelist', '' ) ); if ( empty( $ipRules ) ) { return true; } $whitelisted = false; foreach ( $ipRules as $ipRule ) { if ( strpos( $ipRule, '*' ) !== false ) { $whitelisted = $this->check_wildcard_rule( $ip, $ipRule ); } elseif ( strpos( $ipRule, '-' ) !== false ) { $whitelisted = $this->check_range_rule( $ip, $ipRule ); } elseif ( strpos( $ipRule, '/' ) !== false ) { $whitelisted = $this->check_subnet_mask_rule( $ip, $ipRule ); } elseif ( $ip == $ipRule ) { return true; } if ( $whitelisted ) { return true; } } return $whitelisted; } /** * CIDR notation IP block check. * * @param string $ip The IP address of the user. * @param string $range The range to check. * @return boolean Whether or not the IP is in the range. */ public function check_subnet_mask_rule( $ip, $range ) { list($range, $netmask) = explode( '/', $range, 2 ); $range_decimal = ip2long( $range ); $ip_decimal = ip2long( $ip ); $wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1; $netmask_decimal = ~ $wildcard_decimal; return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) ); } /** * Wildcard IP block check. * * @param string $ip The IP address of the user. * @param string $rule The wildcard range to check against. * @return boolean Whether or not the IP is in the wilcard range. */ public function check_wildcard_rule( $ip, $rule ) { $match = explode( '*', $rule ); $match = $match[0]; return ( substr( $ip, 0, strlen( $match ) ) == $match ); } /** * IP range block check. * * @param string|array $ip The IP address of the user. * @param string $rule The range to check against. * @return boolean Whether or not the IP is in the range. */ public function check_range_rule( $ip, $rule ) { // Check if client has multiple IPs if ( is_array( $ip ) ) { $ip = $ip[0]; } $first_ip = explode( '-', $rule ); $second_ip = explode( '-', $rule ); $start_ip = ip2long( $first_ip[0] ); $end_ip = ip2long( $second_ip[1] ); $request_ip = ip2long( $ip ); return ( $request_ip >= $start_ip && $request_ip <= $end_ip ); } }