PluginProbe
WebTotem Security / 2.3.24
WebTotem Security v2.3.24
3.0.2 3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 All 110 releases
← All changes | library/App.php +151 -6 1.3.22.3.24 View file →
@@ -1,5 +1,5 @@
1 -<?php defined('ABSPATH') or die("Protected By Webtotem Wordpress Security!");
1 +<?php defined('ABSPATH') or die("Protected By WT!");
2 2
3 3
4 4 class WTSEC_LIBRARY_App
5 5 {
@@ -9,10 +9,10 @@
9 9 $this->auth();
10 10 }
11 11
12 12 public function auth(){
13 - if(self::getOption('authorized') === false){
14 - wp_safe_redirect(wtsec_getUrl('login'));
13 + if(self::getOption('authorized') === false && (defined('WTSEC_DEACTIVATED') && !WTSEC_DEACTIVATED)){
14 + wp_safe_redirect(admin_url('admin.php?page=' . WTSEC_PAGE_PREFIX . 'login'));
15 15 exit;
16 16 }
17 17 }
18 18
@@ -20,19 +20,29 @@
20 20 return (boolean) self::getOption('authorized');
21 21 }
22 22
23 23 public static function login($token){
24 + define("WTSEC_DEACTIVATED", false);
24 25 self::_set('authorized', true);
25 26 self::_set('authToken', $token);
26 27 }
27 28
28 29 public static function logout(){
29 - self::_set('authorized', false);
30 - self::_set('authToken', "");
30 + self::_delete(['authToken','authorized','api_key']);
31 + //self::_set('am_installed', false);
31 32 }
32 33
34 + public static function clearDB(){
35 + $options = ['api_key','authorized','authToken',
36 + 'waf_installed_file','am_installed_file','am_installed',
37 + 'color_scheme','check_login_attempt','time_zone',
38 + 'token_expired','deactivated', 'antivirus_event',
39 + 'antivirus_endCursor', 'antivirus_hasNextPage',
40 + 'firewall_endCursor', 'firewall_hasNextPage',
41 + 'reports_endCursor', 'reports_hasNextPage'];
42 + self::_delete($options);
43 + }
33 44
34 -
35 45 public function getLocalDomains(){
36 46 return [];
37 47 }
38 48
@@ -43,8 +53,20 @@
43 53 public static function _get($name){
44 54 return get_option(WTSEC_PLUGIN_PREFIX.$name);
45 55 }
46 56
57 + public static function _delete($options){
58 + if(is_array($options)){
59 + foreach ($options as $option) {
60 + if ( ! delete_option(WTSEC_PLUGIN_PREFIX.$option))
61 + return false;
62 + }
63 + } else{
64 + delete_option(WTSEC_PLUGIN_PREFIX.$options);
65 + }
66 + return true;
67 + }
68 +
47 69 public function set($name,$value){
48 70 return update_option(WTSEC_PLUGIN_PREFIX.$name,$value);
49 71 }
50 72
@@ -66,5 +88,128 @@
66 88
67 89 public static function getName(){
68 90 return self::getOption('username');
69 91 }
92 +
93 +
94 + // Limit login attempt
95 + public function wtsec_login_check($user, $username, $password){
96 +
97 + if( ! $this->wtsec_is_need_check() ){
98 + return $user;
99 + }
100 +
101 + require_once WTSEC_PLUGIN_PATH . 'library/Localization.php';
102 +
103 + function wtsec_locale($lmsg, $args = [])
104 + {
105 + return WTSEC_LIBRARY_Localization::lmsg($lmsg, $args);
106 + }
107 +
108 + $massage = wtsec_locale('login_attempt_message');
109 + global $msg;
110 +
111 + $options = (object) [
112 + // время снятия блокировки в секудах
113 + 'lock_time' => 1800, // 1800
114 + // Количество попыток авторизоваться
115 + 'lock_num' => 5,
116 + // Сообщение о блокировке
117 + 'massage' => $massage,
118 + // время полной очистки файла - 4 дня
119 + 'expire_time' => 3600 * 24 * 4,
120 + // добавить в названия файлов запрос REQUEST_URI - может пригодится для дебага
121 + 'add_uri' => false,
122 + // использовать ли мякгий метод получения IP?
123 + 'soft_get_ip' => false,
124 + ];
125 +
126 + // чтобы установить имя файла
127 + $action = @ $_GET['action'];
128 + if( ! in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) )
129 + $action = 'login';
130 +
131 + // создаем директорию кэша если надо
132 + $cache_dir = plugin_dir_path(__FILE__) . 'cache';
133 + if( ! file_exists($cache_dir) )
134 + mkdir( $cache_dir, 0777 );
135 +
136 + // оперделим название файла
137 + $REQUEST_URI = $options->add_uri ? ( '___'. preg_replace('/[^a-zA-Z0-9:=?_-]/', '-', $_SERVER['REQUEST_URI'] ) /*все на -*/ ) : '';
138 + $domen = str_replace('www.', '', $_SERVER['HTTP_HOST'] );
139 + $file_path = $cache_dir . "/{$domen}___{$action}{$REQUEST_URI}.ini";
140 +
141 + // оперделим ip
142 + if( ! $ip = $this->wtsec_get_ip( $options->soft_get_ip ) )
143 + die( 'No IP...' );
144 +
145 + // парсим данные
146 + $data = @ parse_ini_file( $file_path );
147 + $data = (!$data) ? [] : $data;
148 + $attempts = array_key_exists($ip,$data) ? count($data[$ip]) + 1 : 1;
149 + $last_access_time = array_key_exists($ip,$data) ? max( $data[$ip] ) : 0;
150 + $blocked_time = $last_access_time + ($options->lock_time * floor( $attempts / $options->lock_num) );
151 +
152 + if ( $data['status'][$ip] == 'blocked' && $blocked_time > time() ){
153 + $blocked_time = ($blocked_time - time()) / 60;
154 +
155 + // Вывод ошибки и блокировка
156 + $msg = sprintf($options->massage, $options->lock_num, $blocked_time);
157 + $error = new WP_Error();
158 + $error->add('wp_to_many_try', $msg);
159 + return $error;
160 + } else{
161 + file_put_contents( $file_path, sprintf("{$ip}[] = %d\n", time()), FILE_APPEND ); // добавляем ip и время
162 +
163 + if ($data['status'][$ip] == 'blocked'){
164 + $new_content = preg_replace("~status\[" . $ip . "\] = [a-z]+\n~", '', file_get_contents($file_path) );
165 + file_put_contents( $file_path, $new_content ); // снимает блокировку
166 + }
167 +
168 + if($attempts >= $options->lock_num && ( $attempts % $options->lock_num ) == 0)
169 + file_put_contents( $file_path, "status[{$ip}] = blocked\n", FILE_APPEND); // добавляем блокировку
170 + }
171 +
172 + // полная очистка файла
173 + if( empty($data['expire']) ){
174 + file_put_contents( $file_path, 'expire = ' . time() . "\n", FILE_APPEND );
175 + }
176 + elseif( $data['expire'] + $options->expire_time < time() ){
177 + $content = 'expire = '. time() . "\n";
178 + file_put_contents( $file_path, $content ); // очищаем файл полностью
179 + }
180 + return $user;
181 + }
182 +
183 + protected function wtsec_is_need_check(){
184 +
185 + // работает только для POST запросов.
186 + if( empty($_POST) )
187 + return false;
188 +
189 + $need_check = false;
190 + $settings_value = self::_get('check_login_attempt');
191 +
192 + // для страницы '/wp-login.php'
193 + if( false !== strpos($_SERVER['REQUEST_URI'], '/wp-login.php') && $settings_value )
194 + $need_check = true;
195 +
196 +
197 + return $need_check;
198 + }
199 +
200 + protected function wtsec_get_ip( $soft = false ){
201 +
202 + if( $soft ){
203 + $ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : ''; // cloudflare IP support
204 + if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : '';
205 + if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
206 + if( ! filter_var($ip, FILTER_VALIDATE_IP) ) $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
207 + }
208 + else {
209 + $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
210 + }
211 +
212 + return $ip;
213 + }
214 +
70 215 }