auth(); } public function auth(){ if(self::getOption('authorized') === false && is_user_logged_in() ){ wp_safe_redirect(admin_url('admin.php?page=' . WTSEC_PAGE_PREFIX . 'login')); exit; } } public static function authorized(){ return (boolean) self::getOption('authorized'); } public static function login($token){ self::_set('authorized', true); self::_set('authToken', $token); } public static function logout(){ $options = [ 'api_key', 'api_key_safe', 'api_key_activated', 'authorized', 'authToken', 'waf_installed_file','am_installed_file','am_installed', 'av_installed', 'waf_installed', 'agents_installed', 'color_scheme','check_login_attempt','time_zone', 'token_expired','deactivated', 'antivirus_event', 'antivirus_permissions_changed', 'antivirus_endCursor', 'antivirus_hasNextPage', 'firewall_endCursor', 'firewall_hasNextPage', 'reports_endCursor', 'reports_hasNextPage']; self::_delete($options); self::_set('logout', true); //self::_set('am_installed', false); } public function getLocalDomains(){ return []; } public static function _set($name,$value){ return update_option(WTSEC_PLUGIN_PREFIX.$name,$value); } public static function _get($name){ return get_option(WTSEC_PLUGIN_PREFIX.$name); } public static function _delete($options){ if(is_array($options)){ foreach ($options as $option) { delete_option(WTSEC_PLUGIN_PREFIX.$option); } } else{ delete_option(WTSEC_PLUGIN_PREFIX.$options); } return true; } public function set($name,$value){ return update_option(WTSEC_PLUGIN_PREFIX.$name,$value); } public function get($name){ return get_option(WTSEC_PLUGIN_PREFIX.$name); } public static function getOption($name){ return get_option(WTSEC_PLUGIN_PREFIX.$name); } public static function deleteOption($name){ return delete_option(WTSEC_PLUGIN_PREFIX.$name); } public static function getToken(){ return self::getOption('authToken'); } public static function getName(){ return self::getOption('username'); } // Limit login attempt public function wtsec_login_check($user, $username, $password){ if( ! $this->wtsec_is_need_check() ){ return $user; } $massage = __( 'The maximum number of login attempts has been reached. Please try again in %d minutes.', 'wtotem' ); global $msg; $options = (object) [ // время снятия блокировки в секудах 'lock_time' => 1800, // 1800 // Количество попыток авторизоваться 'lock_num' => 5, // Сообщение о блокировке 'massage' => $massage, // время полной очистки файла - 4 дня 'expire_time' => 3600 * 24 * 4, // добавить в названия файлов запрос REQUEST_URI - может пригодится для дебага 'add_uri' => false, // использовать ли мякгий метод получения IP? 'soft_get_ip' => false, ]; // чтобы установить имя файла $action = @ $_GET['action']; if( ! in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) ) $action = 'login'; // создаем директорию кэша если надо $cache_dir = plugin_dir_path(__FILE__) . 'cache'; if( ! file_exists($cache_dir) ) mkdir( $cache_dir, 0777 ); // оперделим название файла $REQUEST_URI = $options->add_uri ? ( '___'. preg_replace('/[^a-zA-Z0-9:=?_-]/', '-', $_SERVER['REQUEST_URI'] ) /*все на -*/ ) : ''; $domen = str_replace('www.', '', $_SERVER['HTTP_HOST'] ); $file_path = $cache_dir . "/{$domen}___{$action}{$REQUEST_URI}.ini"; // оперделим ip if( ! $ip = $this->wtsec_get_ip( $options->soft_get_ip ) ) die( 'No IP...' ); // парсим данные $data = @ parse_ini_file( $file_path ); $data = (!$data) ? [] : $data; $attempts = array_key_exists($ip,$data) ? count($data[$ip]) + 1 : 1; $last_access_time = array_key_exists($ip,$data) ? max( $data[$ip] ) : 0; $blocked_time = $last_access_time + ($options->lock_time * floor( $attempts / $options->lock_num) ); if ( $data['status'][$ip] == 'blocked' && $blocked_time > time() ){ $blocked_time = ($blocked_time - time()) / 60; // Вывод ошибки и блокировка $msg = sprintf($options->massage, $options->lock_num, $blocked_time); $error = new WP_Error(); $error->add('wp_to_many_try', $msg); return $error; } else{ file_put_contents( $file_path, sprintf("{$ip}[] = %d\n", time()), FILE_APPEND ); // добавляем ip и время if ($data['status'][$ip] == 'blocked'){ $new_content = preg_replace("~status\[" . $ip . "\] = [a-z]+\n~", '', file_get_contents($file_path) ); file_put_contents( $file_path, $new_content ); // снимает блокировку } if($attempts >= $options->lock_num && ( $attempts % $options->lock_num ) == 0) file_put_contents( $file_path, "status[{$ip}] = blocked\n", FILE_APPEND); // добавляем блокировку } // полная очистка файла if( empty($data['expire']) ){ file_put_contents( $file_path, 'expire = ' . time() . "\n", FILE_APPEND ); } elseif( $data['expire'] + $options->expire_time < time() ){ $content = 'expire = '. time() . "\n"; file_put_contents( $file_path, $content ); // очищаем файл полностью } return $user; } protected function wtsec_is_need_check(){ // работает только для POST запросов. if( empty($_POST) ) return false; $need_check = false; $settings_value = self::_get('check_login_attempt'); // для страницы '/wp-login.php' if( false !== strpos($_SERVER['REQUEST_URI'], '/wp-login.php') && $settings_value ) $need_check = true; return $need_check; } protected function wtsec_get_ip( $soft = false ){ if( $soft ){ $ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : ''; // cloudflare IP support if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : ''; if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; } else { $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; } return $ip; } }