PluginProbe
Loginizer / trunk
Loginizer vtrunk
2.1.0 2.0.9 2.0.8 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 All 74 releases
← All changes | init.php +587 -1088 1.1.1 → trunk View file →
@@ -4,14 +4,16 @@
4 4 echo 'You are not allowed to access this page directly.';
5 5 exit;
6 6 }
7 7
8 -define('LOGINIZER_VERSION', '1.1.1');
9 -define('LOGINIZER_DIR', WP_PLUGIN_DIR.'/'.basename(dirname(LOGINIZER_FILE)));
8 +define('LOGINIZER_VERSION', '2.1.0');
9 +define('LOGINIZER_DIR', dirname(LOGINIZER_FILE));
10 10 define('LOGINIZER_URL', plugins_url('', LOGINIZER_FILE));
11 11 define('LOGINIZER_PRO_URL', 'https://loginizer.com/features#compare');
12 +define('LOGINIZER_PRICING_URL', 'https://loginizer.com/pricing');
13 +define('LOGINIZER_DOCS', 'https://loginizer.com/docs/');
12 14
13 -include_once('functions.php');
15 +include_once(LOGINIZER_DIR.'/functions.php');
14 16
15 17 // Ok so we are now ready to go
16 18 register_activation_hook(LOGINIZER_FILE, 'loginizer_activation');
17 19
@@ -21,8 +23,10 @@
21 23 global $wpdb;
22 24
23 25 $sql = array();
24 26
27 + $sql[] = "DROP TABLE IF EXISTS `".$wpdb->prefix."loginizer_logs`";
28 +
25 29 $sql[] = "CREATE TABLE `".$wpdb->prefix."loginizer_logs` (
26 30 `username` varchar(255) NOT NULL DEFAULT '',
27 31 `time` int(10) NOT NULL DEFAULT '0',
28 32 `count` int(10) NOT NULL DEFAULT '0',
@@ -27,10 +31,11 @@
27 31 `time` int(10) NOT NULL DEFAULT '0',
28 32 `count` int(10) NOT NULL DEFAULT '0',
29 33 `lockout` int(10) NOT NULL DEFAULT '0',
30 34 `ip` varchar(255) NOT NULL DEFAULT '',
35 + `url` varchar(255) NOT NULL DEFAULT '',
31 36 UNIQUE KEY `ip` (`ip`)
32 - ) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
37 + ) DEFAULT CHARSET=utf8;";
33 38
34 39 foreach($sql as $sk => $sv){
35 40 $wpdb->query($sv);
36 41 }
@@ -39,12 +44,24 @@
39 44 add_option('loginizer_options', array());
40 45 add_option('loginizer_last_reset', 0);
41 46 add_option('loginizer_whitelist', array());
42 47 add_option('loginizer_blacklist', array());
43 -
48 + add_option('loginizer_2fa_whitelist', array());
49 +
50 + // TODO:: REMOVE THIS AFTER MARCH 2025
51 + $softwp_upgrade = get_option('loginizer_softwp_upgrade', 0);
52 + if(!defined('SITEPAD') && empty($softwp_upgrade)){
53 + loginizer_check_softaculous();
54 + }
44 55 }
45 56
46 -// Checks if we are to update ?
57 +/**
58 + * Updates the database structure for Loginizer
59 + *
60 + * If the plugin files are updated but database structure is not updated
61 + * this function will update the database structure as per the plugin version
62 + * NOTE: This does not update plugin files it just updates the database structure
63 + */
47 64 function loginizer_update_check(){
48 65
49 66 global $wpdb;
50 67
@@ -72,9 +89,9 @@
72 89 // Trick the following if conditions to not run
73 90 $version = (int) str_replace('.', '', LOGINIZER_VERSION);
74 91
75 92 }
76 -
93 +
77 94 // Is it less than 1.0.1 ?
78 95 if($version < 101){
79 96
80 97 // TODO : GET the existing settings
@@ -104,9 +121,17 @@
104 121
105 122 // Update the existing failed logs to new table
106 123 if(is_array($lz_failed_logs)){
107 124 foreach($lz_failed_logs as $fk => $fv){
108 - $wpdb->query("INSERT INTO ".$wpdb->prefix."loginizer_logs SET `username` = '".$fv['username']."', `time` = '".$fv['time']."', `count` = '".$fv['count']."', `lockout` = '".$fv['lockout']."', `ip` = '".$fv['ip']."';");
125 + $insert_data = array('username' => $fv['username'],
126 + 'time' => $fv['time'],
127 + 'count' => $fv['count'],
128 + 'lockout' => $fv['lockout'],
129 + 'ip' => $fv['ip']);
130 +
131 + $format = array('%s','%d','%d','%d','%s');
132 +
133 + $wpdb->insert($wpdb->prefix.'loginizer_logs', $insert_data, $format);
109 134 }
110 135 }
111 136
112 137 // Update the existing options to new structure
@@ -155,11 +180,51 @@
155 180 }
156 181
157 182 }
158 183
184 + // Is it less than 1.3.9 ?
185 + if($version < 139){
186 +
187 + $wpdb->query("ALTER TABLE ".$wpdb->prefix."loginizer_logs ADD `url` VARCHAR(255) NOT NULL DEFAULT '' AFTER `ip`;");
188 +
189 + }
190 +
191 + // Setting alignment to left in social login ?
192 + if($version < 201){
193 + $social_settings = get_option('loginizer_social_settings', []);
194 +
195 + if(!empty($social_settings)){
196 + if(!empty($social_settings['login']) && (!empty($social_settings['login']['login_form']) || !empty($social_settings['login']['registration_form']))){
197 + $social_settings['login']['button_alignment'] = 'left';
198 + }
199 +
200 + if(!empty($social_settings['woocommerce']) && (!empty($social_settings['woocommmerce']['login_form']) || !empty($social_settings['woocommerce']['registration_form']))){
201 + $social_settings['woocommerce']['button_alignment'] = 'left';
202 + }
203 +
204 + if(!empty($social_settings['comment']) && !empty($social_settings['comment']['enable_buttons'])){
205 + $social_settings['comment']['button_alignment'] = 'left';
206 + }
207 +
208 + update_option('loginizer_social_settings', $social_settings);
209 + }
210 + }
211 +
159 212 // Save the new Version
160 213 update_option('loginizer_version', LOGINIZER_VERSION);
161 214
215 + // TODO:: REMOVE THIS AFTER MARCH 2025
216 + $softwp_upgrade = get_option('loginizer_softwp_upgrade', 0);
217 + if(!defined('SITEPAD') && empty($softwp_upgrade)){
218 + loginizer_check_softaculous();
219 + }
220 +
221 + // In Sitepad Math Captcha is enabled by default
222 + if(defined('SITEPAD') && get_option('loginizer_captcha') === false){
223 + $option['captcha_no_google'] = 1;
224 + add_option('loginizer_captcha', $option);
225 + }
226 +
162 227 }
163 228
164 229 // Add the action to load the plugin
165 230 add_action('plugins_loaded', 'loginizer_load_plugin');
@@ -170,12 +235,27 @@
170 235 global $loginizer;
171 236
172 237 // Check if the installed version is outdated
173 238 loginizer_update_check();
239 +
240 + // Set the array
241 + if(empty($loginizer)){
242 + $loginizer = array();
243 + }
174 244
245 + $loginizer['prefix'] = !defined('SITEPAD') ? 'Loginizer ' : 'SitePad ';
246 + $loginizer['app'] = !defined('SITEPAD') ? 'WordPress' : 'SitePad';
247 + $loginizer['login_basename'] = !defined('SITEPAD') ? 'wp-login.php' : 'login.php';
248 + $loginizer['wp-includes'] = !defined('SITEPAD') ? 'wp-includes' : 'site-inc';
249 +
250 + // The IP Method to use
251 + $loginizer['ip_method'] = get_option('loginizer_ip_method');
252 + if($loginizer['ip_method'] == 3){
253 + $loginizer['custom_ip_method'] = get_option('loginizer_custom_ip_method');
254 + }
255 +
256 + // Load settings
175 257 $options = get_option('loginizer_options');
176 -
177 - $loginizer = array();
178 258 $loginizer['max_retries'] = empty($options['max_retries']) ? 3 : $options['max_retries'];
179 259 $loginizer['lockout_time'] = empty($options['lockout_time']) ? 900 : $options['lockout_time']; // 15 minutes
180 260 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
181 261 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
@@ -180,15 +260,43 @@
180 260 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
181 261 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
182 262 $loginizer['reset_retries'] = empty($options['reset_retries']) ? 86400 : $options['reset_retries']; // 24 hours
183 263 $loginizer['notify_email'] = empty($options['notify_email']) ? 0 : $options['notify_email'];
184 -
264 + $loginizer['notify_email_address'] = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email');
265 + $loginizer['trusted_ips'] = empty($options['trusted_ips']) ? false : true;
266 + $loginizer['blocked_screen'] = empty($options['blocked_screen']) ? false : true;
267 + $loginizer['social_settings'] = get_option('loginizer_social_settings', []);
268 +
269 + if(!empty($options['notify_email_address'])){
270 + $loginizer['notify_email_address'] = $options['notify_email_address'];
271 + $loginizer['custom_notify_email'] = 1;
272 + }
273 +
274 + // Login Success Email Notification.
275 + $loginizer['login_mail'] = get_option('loginizer_login_mail', []);
276 + add_action('init', 'loginizer_load_translation_vars', 0);
277 +
278 + $loginizer['login_mail_subject'] = empty($loginizer['login_mail']['subject']) ? '' : $loginizer['login_mail']['subject'];
279 + $loginizer['login_mail_body'] = empty($loginizer['login_mail']['body']) ? '' : $loginizer['login_mail']['body'];
280 +
185 281 // Load the blacklist and whitelist
186 - $loginizer['blacklist'] = get_option('loginizer_blacklist');
187 - $loginizer['whitelist'] = get_option('loginizer_whitelist');
282 + $loginizer['blacklist'] = get_option('loginizer_blacklist', []);
283 + $loginizer['whitelist'] = get_option('loginizer_whitelist', []);
284 + $loginizer['2fa_whitelist'] = get_option('loginizer_2fa_whitelist');
188 285
286 + // It should not be false
287 + if(empty($loginizer['2fa_whitelist'])){
288 + $loginizer['2fa_whitelist'] = array();
289 + }
290 +
189 291 // When was the database cleared last time
190 292 $loginizer['last_reset'] = get_option('loginizer_last_reset');
293 +
294 + if(!isset($loginizer['ultimate-member-active'])){
295 + $um_is_active = in_array('ultimate-member/ultimate-member.php', apply_filters('active_plugins', get_option('active_plugins', [])));
296 +
297 + $loginizer['ultimate-member-active'] = !empty($um_is_active) ? true : false;
298 + }
191 299
192 300 //print_r($loginizer);
193 301
194 302 // Clear retries
@@ -204,34 +312,64 @@
204 312 $loginizer['ins_time'] = $ins_time;
205 313
206 314 // Set the current IP
207 315 $loginizer['current_ip'] = lz_getip();
316 +
317 + // Is Brute Force Disabled ?
318 + $loginizer['disable_brute'] = get_option('loginizer_disable_brute');
208 319
209 - /* Filters and actions */
320 + // Filters and actions
321 + if(empty($loginizer['disable_brute'])){
210 322
211 - // Use this to verify before WP tries to login
212 - // Is always called and is the first function to be called
213 - //add_action('wp_authenticate', 'loginizer_wp_authenticate', 10, 2);// Not called by XML-RPC
214 - add_filter('authenticate', 'loginizer_wp_authenticate', 10001, 3);// This one is called by xmlrpc as well as GUI
215 -
216 - // Is called when a login attempt fails
217 - // Hence Update our records that the login failed
218 - add_action('wp_login_failed', 'loginizer_login_failed');
219 -
220 - // Is called before displaying the error message so that we dont show that the username is wrong or the password
221 - // Update Error message
222 - add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2);
223 -
224 - // Is the premium features there ?
225 - if(file_exists(LOGINIZER_DIR.'/premium.php')){
323 + // Use this to verify before WP tries to login
324 + // Is always called and is the first function to be called
325 + //add_action('wp_authenticate', 'loginizer_wp_authenticate', 10, 2);// Not called by XML-RPC
326 + add_filter('authenticate', 'loginizer_wp_authenticate', 10001, 3);// This one is called by xmlrpc as well as GUI
226 327
227 - // Include the file
228 - include_once(LOGINIZER_DIR.'/premium.php');
328 + // Is called when a login attempt fails
329 + // Hence Update our records that the login failed
330 + add_action('wp_login_failed', 'loginizer_login_failed');
229 331
230 - loginizer_security_init();
332 + // Is called before displaying the error message so that we dont show that the username is wrong or the password
333 + // Update Error message
334 + add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2);
335 + add_action('woocommerce_login_failed', 'loginizer_woocommerce_error_handler', 10001);
336 + add_action('wp_login', 'loginizer_login_success', 11, 2);
337 + add_action('rsssl_two_factor_user_authenticated', 'loginizer_rsssl_2fa_success');
231 338
339 + if(!empty($loginizer['ultimate-member-active'])){
340 + add_action('wp_login_failed', 'loginizer_ultimatemember_error_handler', 10001);
341 + }
342 +
343 + if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings'])){
344 + add_filter('wp_login_errors', 'loginizer_social_login_error_handler', 10000, 2);
345 + }
232 346 }
347 +
348 + // Social Login Form Actions
349 + if(!empty($loginizer['social_settings'])){
350 + if(!empty($loginizer['social_settings']['login']['login_form'])){
351 + add_action('login_form', 'loginizer_social_btn_login');
352 + }
353 + }
233 354
355 + if((function_exists('wp_doing_ajax') && wp_doing_ajax()) || (defined( 'DOING_AJAX' ) && DOING_AJAX)){
356 + include_once LOGINIZER_DIR . '/main/ajax.php';
357 + }
358 +
359 + if(is_admin()){
360 + include_once LOGINIZER_DIR . '/main/admin.php';
361 + }
362 +
363 + // ----------------
364 + // PRO INIT END
365 + // ----------------
366 +
367 + // Secuity checks for social login.
368 + if(!empty($_GET['lz_social_provider']) && loginizer_can_login() && empty($_GET['lz_api'])){
369 + add_action('init', 'loginizer_social_login_load');
370 + return;
371 + }
234 372 }
235 373
236 374 // Should return NULL if everything is fine
237 375 function loginizer_wp_authenticate($user, $username, $password){
@@ -245,24 +383,67 @@
245 383 // Are you whitelisted ?
246 384 if(loginizer_is_whitelisted()){
247 385 $loginizer['ip_is_whitelisted'] = 1;
248 386 return $user;
387 +
388 + } else if (!empty($loginizer['trusted_ips'])){
389 + $lz_cannot_login = 1;
390 +
391 + // This is used by WP Activity Log
392 + apply_filters( 'wp_login_blocked', $username );
393 +
394 + // Shows a blocked screen
395 + if(!empty($loginizer['blocked_screen'])){
396 + $lz_error['trusted_ip'] = __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer');
397 + loginizer_blocked_page($lz_error);
398 + }
399 +
400 + return new WP_Error('ip_blacklisted', __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer'));
249 401 }
250 402
251 403 // Are you blacklisted ?
252 404 if(loginizer_is_blacklisted()){
253 405 $lz_cannot_login = 1;
406 +
407 + // This is used by WP Activity Log
408 + apply_filters( 'wp_login_blocked', $username );
409 +
410 + // Shows a blocked screen
411 + if(!empty($loginizer['blocked_screen'])){
412 + loginizer_blocked_page($lz_error);
413 + }
414 +
254 415 return new WP_Error('ip_blacklisted', implode('', $lz_error), 'loginizer');
255 416 }
256 417
418 + // Is the username blacklisted ?
419 + if(function_exists('loginizer_user_blacklisted')){
420 + if(loginizer_user_blacklisted($username)){
421 + $lz_cannot_login = 1;
422 +
423 + // This is used by WP Activity Log
424 + apply_filters( 'wp_login_blocked', $username );
425 +
426 + return new WP_Error('user_blacklisted', implode('', $lz_error), 'loginizer');
427 + }
428 + }
429 +
257 430 if(loginizer_can_login()){
258 431 return $user;
259 432 }
260 433
261 434 $lz_cannot_login = 1;
435 +
436 + // This is used by WP Activity Log
437 + apply_filters( 'wp_login_blocked', $username );
262 438
439 + // Shows a blocked screen
440 + if(!empty($loginizer['blocked_screen'])){
441 + loginizer_blocked_page($lz_error);
442 + }
443 +
263 444 return new WP_Error('ip_blocked', implode('', $lz_error), 'loginizer');
264 -
445 +
265 446 }
266 447
267 448 function loginizer_can_login(){
268 449
@@ -268,12 +449,13 @@
268 449
269 450 global $wpdb, $loginizer, $lz_error;
270 451
271 452 // Get the logs
272 - $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
453 + $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
454 + $result = lz_selectquery($sel_query);
273 455
274 456 if(!empty($result['count']) && ($result['count'] % $loginizer['max_retries']) == 0){
275 -
457 +
276 458 // Has he reached max lockouts ?
277 459 if($result['lockout'] >= $loginizer['max_lockouts']){
278 460 $loginizer['lockout_time'] = $loginizer['lockouts_extend'];
279 461 }
@@ -281,21 +463,24 @@
281 463 // Is he in the lockout time ?
282 464 if($result['time'] >= (time() - $loginizer['lockout_time'])){
283 465 $banlift = ceil((($result['time'] + $loginizer['lockout_time']) - time()) / 60);
284 466
285 - //echo 'Current Time '.date('m/d/Y H:i:s', time()).'<br />';
286 - //echo 'Last attempt '.date('m/d/Y H:i:s', $result['time']).'<br />';
287 - //echo 'Unlock Time '.date('m/d/Y H:i:s', $result['time'] + $loginizer['lockout_time']).'<br />';
467 + //echo 'Current Time '.date('d/M/Y H:i:s P', time()).'<br />';
468 + //echo 'Last attempt '.date('d/M/Y H:i:s P', $result['time']).'<br />';
469 + //echo 'Unlock Time '.date('d/M/Y H:i:s P', $result['time'] + $loginizer['lockout_time']).'<br />';
288 470
289 - $_time = $banlift.' minute(s)';
471 + $_time = $banlift.' '.$loginizer['msg']['minutes_err'];
290 472
291 473 if($banlift > 60){
292 474 $banlift = ceil($banlift / 60);
293 - $_time = $banlift.' hour(s)';
475 + $_time = $banlift.' '.$loginizer['msg']['hours_err'];
294 476 }
295 477
296 - $lz_error['ip_blocked'] = 'You have exceeded maximum login retries<br /> Please try after '.$_time;
478 + $lz_error['ip_blocked'] = $loginizer['msg']['lockout_err'].' '.$_time;
297 479
480 + if(!empty($loginizer['ultimate-member-active']) && class_exists('UM')){
481 + \UM()->form()->add_error('blocked_msg', $lz_error['ip_blocked']);
482 + }
298 483 return false;
299 484 }
300 485 }
301 486
@@ -305,27 +490,36 @@
305 490 function loginizer_is_blacklisted(){
306 491
307 492 global $wpdb, $loginizer, $lz_error;
308 493
309 - $blacklist = $loginizer['blacklist'];
310 -
494 + $blacklist = isset($loginizer['blacklist']) ? $loginizer['blacklist'] : [];
495 +
496 + if(empty($blacklist)){
497 + return false;
498 + }
499 +
500 + $current_ip_inet = inet_ptoi($loginizer['current_ip']);
501 +
311 502 foreach($blacklist as $k => $v){
312 -
503 +
504 + $start_inet = inet_ptoi($v['start']);
505 + $end_inet = inet_ptoi($v['end']);
506 +
313 507 // Is the IP in the blacklist ?
314 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip']) && ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
508 + if($start_inet <= $current_ip_inet && $current_ip_inet <= $end_inet){
315 509 $result = 1;
316 510 break;
317 511 }
318 -
512 +
319 513 // Is it in a wider range ?
320 - if(ip2long($v['start']) >= 0 && ip2long($v['end']) < 0){
514 + if($start_inet >= 0 && $end_inet < 0){
321 515
322 - // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of ip2long,
516 + // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
323 517 // if the current IP is <= than the start of the range, it is within the range
324 518 // OR
325 519 // if the current IP is <= than the end of the range, it is within the range
326 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip'])
327 - || ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
520 + if($start_inet <= $current_ip_inet
521 + || $current_ip_inet <= $end_inet){
328 522 $result = 1;
329 523 break;
330 524 }
331 525
@@ -331,12 +525,12 @@
331 525
332 526 }
333 527
334 528 }
335 -
529 +
336 530 // You are blacklisted
337 531 if(!empty($result)){
338 - $lz_error['ip_blacklisted'] = 'Your IP has been blacklisted';
532 + $lz_error['ip_blacklisted'] = $loginizer['msg']['ip_blacklisted'];
339 533 return true;
340 534 }
341 535
342 536 return false;
@@ -342,93 +536,224 @@
342 536 return false;
343 537
344 538 }
345 539
346 -function loginizer_is_whitelisted(){
540 +// When the login fails, then this is called
541 +// We need to update the database
542 +function loginizer_login_failed($username, $is_2fa = ''){
347 543
348 - global $wpdb, $loginizer, $lz_error;
544 + global $wpdb, $loginizer, $lz_cannot_login;
349 545
350 - $whitelist = $loginizer['whitelist'];
351 -
352 - foreach($whitelist as $k => $v){
546 + // Some plugins are changing the value for username as null so we need to handle it before using it for the INSERT OR UPDATE query
547 + if(empty($username) || is_null($username)){
548 + $username = '';
549 + }
550 +
551 + $fail_type = 'Login';
552 +
553 + if(!empty($is_2fa)){
554 + $fail_type = '2FA';
555 + }
556 +
557 + if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
353 558
354 - // Is the IP in the blacklist ?
355 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip']) && ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
356 - $result = 1;
357 - break;
559 + // The params which comes when social login returns an error, have some characters, which WordPress could not save.
560 + // REQUEST_URI / HTTP_HOST are not always set (WP-CLI, some CGI and XML-RPC setups)
561 + $server_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
562 + $http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
563 +
564 + if(!empty($server_uri) && strpos($server_uri, 'lz_social_provider') !== FALSE){
565 + $request_uri = explode('=', $server_uri);
566 + $server_uri = $request_uri[0];
358 567 }
568 +
569 + // No addslashes() here, $wpdb->prepare() below does the escaping
570 + $url = esc_url((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$http_host.$server_uri);
359 571
360 - // Is it in a wider range ?
361 - if(ip2long($v['start']) >= 0 && ip2long($v['end']) < 0){
362 -
363 - // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of ip2long,
364 - // if the current IP is <= than the start of the range, it is within the range
365 - // OR
366 - // if the current IP is <= than the end of the range, it is within the range
367 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip'])
368 - || ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
369 - $result = 1;
370 - break;
572 + // Must never be 0, we divide by it below
573 + $max_retries = (int) $loginizer['max_retries'] < 1 ? 1 : (int) $loginizer['max_retries'];
574 +
575 + // This way is atomic now, the earlier one were causing race condition.
576 + // NOTE : In the UPDATE part `count` is already the new value, as MySQL / MariaDB
577 + // evaluate the assignments from left to right, so lockout must NOT add 1 again
578 + $upsert = $wpdb->prepare(
579 + "INSERT INTO `".$wpdb->prefix."loginizer_logs`
580 + (username, time, count, ip, lockout, url)
581 + VALUES
582 + (%s, %d, 1, %s, FLOOR(1 / %d), %s)
583 + ON DUPLICATE KEY UPDATE
584 + username = VALUES(username),
585 + time = VALUES(time),
586 + count = count + 1,
587 + lockout = FLOOR(count / %d),
588 + url = VALUES(url)",
589 + $username,
590 + time(),
591 + $loginizer['current_ip'],
592 + $max_retries,
593 + $url,
594 + $max_retries
595 + );
596 + $wpdb->query($upsert);
597 +
598 + // Re-read the persisted row so email/retries-left reflect the actual count
599 + $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
600 + $result = lz_selectquery($sel_query);
601 +
602 + if(empty($result)){
603 + $result = array('count' => 0);
604 + }
605 +
606 + $count = (int) $result['count'];
607 + $lockout = !empty($result['lockout']) ? (int) $result['lockout'] : 0;
608 +
609 + // The lockout goes up only on every max_retries'th failure, which is the
610 + // attempt that actually locks the IP out. On the failures in between there
611 + // is nothing new to report, so we must not email on each one of them
612 + $is_new_lockout = !empty($count) && ($count % $max_retries) == 0;
613 +
614 + // Do we need to email admin ?
615 + if(!empty($loginizer['notify_email']) && !empty($is_new_lockout) && $lockout >= $loginizer['notify_email']){
616 +
617 + $lockout_time = $loginizer['lockout_time'];
618 +
619 + if($lockout >= $loginizer['max_lockouts']){
620 + $lockout_time = $loginizer['lockouts_extend'];
371 621 }
372 -
622 +
623 + $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
624 + $mail = array();
625 + $mail['to'] = $loginizer['notify_email_address'];
626 + $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
627 + $mail['message'] = 'Hi,
628 +
629 +'.(int) $result['count'].' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
630 +'.home_url().'
631 +
632 +Last '.$fail_type.' Attempt : '.date('d/M/Y H:i:s P', time()).'
633 +Last User Attempt : '.$username.'
634 +IP has been blocked until : '.date('d/M/Y H:i:s P', time() + $lockout_time).'
635 +
636 +Regards,
637 +Loginizer';
638 +
639 + @wp_mail($mail['to'], $mail['subject'], $mail['message']);
373 640 }
641 +
642 + loginizer_update_attempt_stats(0);
643 + $loginizer['retries_left'] = $max_retries - ($count % $max_retries);
644 + $loginizer['retries_left'] = $loginizer['retries_left'] == $max_retries ? 0 : $loginizer['retries_left'];
374 645
375 646 }
376 -
377 - // You are whitelisted
378 - if(!empty($result)){
379 - return true;
380 - }
381 -
382 - return false;
383 -
384 647 }
385 648
649 +function loginizer_rsssl_2fa_success($user){
650 + loginizer_login_success('', $user);
651 +}
386 652
387 -// When the login fails, then this is called
388 -// We need to update the database
389 -function loginizer_login_failed($username){
653 +function loginizer_login_success($user_login, $user) {
654 + global $wp_version, $loginizer;
655 +
656 + loginizer_update_attempt_stats(1);
390 657
391 - global $wpdb, $loginizer, $lz_cannot_login;
658 + if(empty($loginizer['login_mail'])){
659 + return;
660 + }
392 661
393 - if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
394 -
395 - $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
396 -
397 - if(!empty($result)){
398 - $lockout = floor((($result['count']+1) / $loginizer['max_retries']));
399 - $sresult = $wpdb->query("UPDATE `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = `count`+1, `lockout` = '".$lockout."' WHERE `ip` = '".$loginizer['current_ip']."';");
400 -
401 - // Do we need to email admin ?
402 - if(!empty($loginizer['notify_email']) && $lockout >= $loginizer['notify_email']){
403 -
404 - $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
405 - $mail = array();
406 - $mail['to'] = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email');
407 - $mail['subject'] = 'Failed Login Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
408 - $mail['message'] = 'Hi,
662 + if(empty($loginizer['login_mail']['enable'])){
663 + return;
664 + }
409 665
410 -'.($result['count']+1).' failed login attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].'
666 + if(!empty($loginizer['login_mail']['disable_whitelist'])){
667 + // Check its whitelist ip
668 + if(loginizer_is_whitelisted()){
669 + return;
670 + }
671 + }
411 672
412 -Last Login Attempt : '.date('d/m/Y H:i:s', time()).'
413 -Last User Attempt : '.$username.'
414 -IP has been blocked until : '.date('d/m/Y H:i:s', time() + $loginizer['lockout_time']).'
673 + if(empty($user_login) && empty($user)){
674 + error_log('Loginizer: No user information to send email');
675 + return;
676 + }
415 677
416 -Regards,
417 -Loginizer';
678 + if(empty($user)){
679 + $user = get_user_by('login', $user_login);
680 + }
418 681
419 - @wp_mail($mail['to'], $mail['subject'], $mail['message']);
420 - }
682 + if(empty($user)){
683 + error_log('Loginizer: Unable to get the user');
684 + return;
685 + }
686 +
687 + if(empty($loginizer['login_mail']['roles']) || !is_array($loginizer['login_mail']['roles'])){
688 + return;
689 + }
690 +
691 + // Check if the user role is enabled for email notification.
692 + if(!array_intersect($user->roles, $loginizer['login_mail']['roles'])){
693 + return;
694 + }
695 +
696 + // current_datetime & wp_timezone_string were introduced in WordPress 5.3
697 + if(!empty($wp_version) && version_compare($wp_version, '5.3', '>') && function_exists('current_datetime')){
698 + $time_zone = wp_timezone_string();
699 +
700 + if(!empty($time_zone) && isset($time_zone[1]) && is_numeric($time_zone[1])){
701 + $time_zone = 'UTC'.$time_zone;
702 + }
703 +
704 + // Setting up data variables.
705 + $date = current_datetime()->format('Y-m-d H:i:s') .' '. $time_zone;
706 + } else {
707 + $date = date("Y-m-d H:i:s", time()) . ' ' . date_default_timezone_get();
708 + }
709 +
710 + $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
711 + $email = $user->data->user_email;
712 +
713 + $vars = array(
714 + 'date' => $date,
715 + 'ip' => esc_html($loginizer['current_ip']),
716 + 'sitename' => $sitename,
717 + 'user_login' => $user_login
718 + );
719 +
720 + $message = lz_lang_vars_name($loginizer['login_mail_body'], $vars);
721 + $subject = lz_lang_vars_name($loginizer['login_mail_subject'], $vars);
722 +
723 + $headers = [];
724 +
725 + // Do we need to send the email as HTML ?
726 + if(!empty($loginizer['login_mail']['html_mail'])){
727 + $headers[] = 'Content-Type: text/html; charset=UTF-8';
728 +
729 + if(!empty($loginizer['login_mail']['body'])){
730 + $message = html_entity_decode($message);
421 731 }else{
422 - $insert = $wpdb->query("INSERT INTO `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = '1', `ip` = '".$loginizer['current_ip']."', `lockout` = '0';");
732 + $message = preg_replace("/\<br\s*\/\>/i", "<br/>", $message);
733 + $message = preg_replace('/(?<!<br\/>)\n/i', "<br/>\n", $message);
423 734 }
735 + }
736 +
737 + // Sending notification
738 + if(empty(wp_mail($email, $subject, $message, $headers))){
739 + error_log(__('There was a problem sending your email.', 'loginizer'));
740 + return;
741 + }
742 +}
743 +
744 +function loginizer_update_attempt_stats($type){
745 +
746 + $stats = get_option('loginizer_login_attempt_stats', []);
747 + $time = strtotime(date('Y-m-d H:00:00'));
424 748
425 - // We need to add one as this is a failed attempt as well
426 - $result['count'] = $result['count'] + 1;
427 - $loginizer['retries_left'] = ($loginizer['max_retries'] - ($result['count'] % $loginizer['max_retries']));
428 - $loginizer['retries_left'] = $loginizer['retries_left'] == $loginizer['max_retries'] ? 0 : $loginizer['retries_left'];
429 -
749 + if(empty($stats[$time][$type])){
750 + $stats[$time][$type] = 0;
430 751 }
752 +
753 + $stats[$time][$type] += 1;
754 +
755 + update_option('loginizer_login_attempt_stats', $stats, false);
431 756 }
432 757
433 758 // Handles the error of the password not being there
434 759 function loginizer_error_handler($errors, $redirect_to){
@@ -433,11 +758,14 @@
433 758 // Handles the error of the password not being there
434 759 function loginizer_error_handler($errors, $redirect_to){
435 760
436 761 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
437 -
762 +
438 763 //echo 'loginizer_error_handler :';print_r($errors->errors);echo '<br>';
439 -
764 + if(is_null($errors) || empty($errors)){
765 + return true;
766 + }
767 +
440 768 // Remove the empty password error
441 769 if(is_wp_error($errors)){
442 770
443 771 $codes = $errors->get_error_codes();
@@ -449,1045 +777,201 @@
449 777 }
450 778
451 779 $errors->remove('invalid_username');
452 780 $errors->remove('incorrect_password');
781 +
782 + // Add the error
783 + if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
784 + $errors->add('invalid_userpass', '<b>ERROR:</b> ' . $loginizer['msg']['inv_userpass']);
785 + }
453 786
787 + // Add the number of retires left as well
788 + if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
789 + $errors->add('retries_left', loginizer_retries_left());
790 + }
791 +
454 792 }
455 793
456 - // Add the error
457 - if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
458 - $errors->add('invalid_userpass', '<b>ERROR:</b> Incorrect Username or Password');
459 - }
460 -
461 - // Add the number of retires left as well
462 - if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
463 - $errors->add('retries_left', loginizer_retries_left());
464 - }
465 -
466 794 return $errors;
467 795
468 796 }
469 797
470 -// Returns a string with the number of retries left
471 -function loginizer_retries_left(){
472 -
798 +// Handles the error of the password not being there
799 +function loginizer_woocommerce_error_handler(){
800 +
473 801 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
474 802
475 - // If we are to show the number of retries left
476 - if(isset($loginizer['retries_left'])){
477 - return '<b>'.$loginizer['retries_left'].'</b> attempt(s) left';
803 + if(function_exists('wc_add_notice')){
804 + wc_add_notice( loginizer_retries_left(), 'error' );
478 805 }
479 -
480 806 }
481 807
482 -function loginizer_reset_retries(){
808 +function loginizer_ultimatemember_error_handler(){
483 809
484 - global $wpdb, $loginizer;
485 -
486 - $deltime = time() - $loginizer['reset_retries'];
487 - $result = $wpdb->query("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= '".$deltime."';");
488 -
489 - update_option('loginizer_last_reset', time());
490 -
810 + if(class_exists('UM')){
811 + \UM()->form()->add_error('remaining_tries', loginizer_retries_left());
812 + }
491 813 }
492 814
493 -add_filter("plugin_action_links_$plugin_loginizer", 'loginizer_plugin_action_links');
494 -
495 -// Add settings link on plugin page
496 -function loginizer_plugin_action_links($links) {
815 +// Handles social login URL
816 +function loginizer_social_login_error_handler($errors = '', $redirect_to = ''){
817 + global $loginizer;
497 818
498 - if(!defined('LOGINIZER_PREMIUM')){
499 - $links[] = '<a href="'.LOGINIZER_PRO_URL.'" style="color:#3db634;" target="_blank">'._x('Upgrade', 'Plugin action link label.', 'loginizer').'</a>';
819 + if(loginizer_is_blacklisted()){
820 + return $errors;
500 821 }
501 822
502 - $settings_link = '<a href="admin.php?page=loginizer">Settings</a>';
503 - array_unshift($links, $settings_link);
504 -
505 - return $links;
506 -}
823 + loginizer_get_social_error();
507 824
508 -add_action('admin_menu', 'loginizer_admin_menu');
825 + if(empty($loginizer['social_errors'])){
826 + return $errors;
827 + }
509 828
510 -// Shows the admin menu of Loginizer
511 -function loginizer_admin_menu() {
512 -
513 - global $wp_version, $loginizer;
514 -
515 - // Add the menu page
516 - add_menu_page(__('Loginizer Dashboard'), __('Loginizer Security'), 'activate_plugins', 'loginizer', 'loginizer_page_dashboard');
517 -
518 - // Dashboard
519 - add_submenu_page('loginizer', __('Loginizer Dashboard'), __('Dashboard'), 'activate_plugins', 'loginizer', 'loginizer_page_dashboard');
520 -
521 - // Brute Force
522 - add_submenu_page('loginizer', __('Loginizer Brute Force Settings'), __('Brute Force'), 'activate_plugins', 'loginizer_brute_force', 'loginizer_page_brute_force');
523 -
524 - if(defined('LOGINIZER_PREMIUM')){
525 -
526 - // PasswordLess
527 - add_submenu_page('loginizer', __('Loginizer PasswordLess Settings'), __('PasswordLess'), 'activate_plugins', 'loginizer_passwordless', 'loginizer_page_passwordless');
528 -
529 - // Two Factor Auth
530 - add_submenu_page('loginizer', __('Loginizer Two Factor Authentication'), __('Two Factor Auth'), 'activate_plugins', 'loginizer_2fa', 'loginizer_page_2fa');
531 -
532 - // reCaptcha
533 - add_submenu_page('loginizer', __('Loginizer reCAPTCHA Settings'), __('reCAPTCHA'), 'activate_plugins', 'loginizer_recaptcha', 'loginizer_page_recaptcha');
534 -
535 - // Security Settings
536 - add_submenu_page('loginizer', __('Loginizer Security Settings'), __('Security Settings'), 'activate_plugins', 'loginizer_security', 'loginizer_page_security');
537 -
538 - }elseif(!defined('LOGINIZER_PREMIUM') && !empty($loginizer['ins_time']) && $loginizer['ins_time'] < (time() - (30*24*3600))){
539 -
540 - // Go Pro link
541 - add_submenu_page('loginizer', __('Loginizer Go Pro'), __('Go Pro'), 'activate_plugins', LOGINIZER_PRO_URL);
542 -
829 + if(is_null($errors) || empty($errors) || !is_wp_error($errors)){
830 + $errors = new WP_Error();
543 831 }
544 -
545 -}
546 832
547 -// The Loginizer Admin Options Page
548 -function loginizer_page_header($title = 'Loginizer'){
549 - /*wp_enqueue_script('common');
550 - wp_enqueue_script('wp-lists');
551 - wp_enqueue_script('postbox');
552 - wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
553 -
554 - echo '
555 -<script>
556 -jQuery(document).ready( function() {
557 - //add_postbox_toggles("loginizer");
558 -});
559 -</script>';*/
833 + foreach($loginizer['social_errors'] as $key => $text){
834 + $errors->add($key, $text);
835 + }
560 836
561 -?>
562 -<style>
563 -.lz-right-ul{
564 - padding-left: 10px !important;
837 + return $errors;
565 838 }
566 839
567 -.lz-right-ul li{
568 - list-style: circle !important;
569 -}
570 -</style>
571 -<?php
840 +// Returns a string with the number of retries left
841 +function loginizer_retries_left(){
572 842
573 - echo '<div style="margin: 10px 20px 0 2px;">
574 -<div class="metabox-holder columns-2">
575 -<div class="postbox-container">
576 -<div id="top-sortables" class="meta-box-sortables ui-sortable">
843 + global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
577 844
578 - <table cellpadding="2" cellspacing="1" width="100%" class="fixed" border="0">
579 - <tr>
580 - <td valign="top"><h3>'.$title.'</h3></td>
581 - <td align="right"><a target="_blank" class="button button-primary" href="https://wordpress.org/support/view/plugin-reviews/loginizer">Review Loginizer</a></td>
582 - </tr>
583 - </table>
584 - <hr />
845 + // If we are to show the number of retries left
846 + if(isset($loginizer['retries_left'])){
847 + $retries_left = apply_filters('loginizer_retries_left_num', $loginizer['retries_left']);
848 +
849 + return '<b>'.esc_html($retries_left).'</b> '.$loginizer['msg']['attempts_left'];
850 + }
585 851
586 - <!--Main Table-->
587 - <table cellpadding="8" cellspacing="1" width="100%" class="fixed">
588 - <tr>
589 - <td valign="top">';
590 -
591 852 }
592 853
593 -// The Loginizer Theme footer
594 -function loginizer_page_footer(){
595 -
596 - echo '</td>
597 - <td width="200" valign="top" id="loginizer-right-bar">';
598 -
599 - if(!defined('LOGINIZER_PREMIUM')){
600 -
601 - echo '
602 - <div class="postbox" style="min-width:0px !important;">
603 - <h2 class="hndle ui-sortable-handle">
604 - <span>Premium Version</span>
605 - </h2>
606 - <div class="inside">
607 - <i>Upgrade to the premium version and get the following features </i>:<br>
608 - <ul class="lz-right-ul">
609 - <li>PasswordLess Login</li>
610 - <li>Two Factor Auth - Email</li>
611 - <li>Two Factor Auth - App</li>
612 - <li>Login Challenge Question</li>
613 - <li>reCAPTCHA</li>
614 - <li>Rename Login Page</li>
615 - <li>Disable XML-RPC</li>
616 - <li>And many more ...</li>
617 - </ul>
618 - <center><a class="button button-primary" href="https://loginizer.com/members/cart.php">Upgrade</a></center>
619 - </div>
620 - </div>';
621 -
622 - }else{
623 -
624 - echo '
625 - <div class="postbox" style="min-width:0px !important;">
626 - <h2 class="hndle ui-sortable-handle">
627 - <span>Recommedations</span>
628 - </h2>
629 - <div class="inside">
630 - <i>We recommed that you enable atleast one of the following security features</i>:<br>
631 - <ul class="lz-right-ul">
632 - <li>Rename Login Page</li>
633 - <li>Login Challenge Question</li>
634 - <li>reCAPTCHA</li>
635 - <li>Two Factor Auth - Email</li>
636 - <li>Two Factor Auth - App</li>
637 - </ul>
638 - </div>
639 - </div>';
640 - }
641 -
642 - echo '</td>
643 - </tr>
644 - </table>
645 - <br />
646 - <div style="width:45%;background:#FFF;padding:15px; margin:auto">
647 - <b>Let your friends know that you have secured your website :</b>
648 - <form method="get" action="http://twitter.com/intent/tweet" id="tweet" onsubmit="return dotweet(this);">
649 - <textarea name="text" cols="45" row="3" style="resize:none;">I just secured my @WordPress site against #bruteforce using @loginizer</textarea>
650 - &nbsp; &nbsp; <input type="submit" value="Tweet!" class="button button-primary" onsubmit="return false;" id="twitter-btn" style="margin-top:20px;"/>
651 - </form>
652 -
653 - </div>
654 - <br />
655 -
656 - <script>
657 - function dotweet(ele){
658 - window.open(jQuery("#"+ele.id).attr("action")+"?"+jQuery("#"+ele.id).serialize(), "_blank", "scrollbars=no, menubar=no, height=400, width=500, resizable=yes, toolbar=no, status=no");
659 - return false;
660 - }
661 - </script>
662 -
663 - <hr />
664 - <a href="http://loginizer.com" target="_blank">Loginizer</a> v'.LOGINIZER_VERSION.'. You can report any bugs <a href="http://wordpress.org/support/plugin/loginizer" target="_blank">here</a>.
854 +function loginizer_reset_retries(){
665 855
666 -</div>
667 -</div>
668 -</div>
669 -</div>';
856 + global $wpdb, $loginizer;
670 857
671 -}
858 + $deltime = time() - $loginizer['reset_retries'];
672 859
673 -// The Loginizer Admin Options Page
674 -function loginizer_page_dashboard(){
675 -
676 - global $loginizer, $lz_error, $lz_env;
677 -
678 - // Is there a license key ?
679 - if(isset($_POST['save_lz'])){
680 -
681 - $license = lz_optpost('lz_license');
682 -
683 - // Check if its a valid license
684 - if(empty($license)){
685 - $lz_error['lic_invalid'] = __('The license key was not submitted', 'loginizer');
686 - return loginizer_page_dashboard_T();
687 - }
688 -
689 - $resp = wp_remote_get(LOGINIZER_API.'license.php?license='.$license);
690 -
691 - if(is_array($resp)){
692 - $json = json_decode($resp['body'], true);
693 - //print_r($json);
694 - }
695 -
696 - // Save the License
697 - if(empty($json)){
698 -
699 - $lz_error['lic_invalid'] = __('The license key is invalid', 'loginizer');
700 - return loginizer_page_dashboard_T();
701 -
702 - }else{
703 -
704 - update_option('loginizer_license', $json);
705 -
706 - // Mark as saved
707 - $GLOBALS['lz_saved'] = true;
708 - }
709 -
710 - }
711 -
712 - loginizer_page_dashboard_T();
713 -
714 -}
860 + $del_query = $wpdb->prepare("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= %d", $deltime);
861 + $result = $wpdb->query($del_query);
715 862
716 -// The Loginizer Admin Options Page - THEME
717 -function loginizer_page_dashboard_T(){
718 -
719 - global $loginizer, $lz_error, $lz_env;
863 + update_option('loginizer_last_reset', time());
720 864
721 - loginizer_page_header('Loginizer Dashboard');
722 -?>
723 -<style>
724 -.welcome-panel{
725 - margin: 0px;
726 - padding: 10px;
727 865 }
728 866
729 -input[type="text"], textarea, select {
730 - width: 70%;
731 -}
867 +function loginizer_load_translation_vars(){
868 + global $loginizer;
869 +
870 + $loginizer['login_mail_default_sub'] = __('Login Successful at $sitename', 'loginizer');
871 + $loginizer['login_mail_default_msg'] = __('Hello $user_login,
732 872
733 -.form-table label{
734 - font-weight:bold;
735 -}
873 +Your account was recently logged in from the IP : $ip
874 +Time : $date
875 +If it was not you who logged in then please report this to us immediately.
736 876
737 -.exp{
738 - font-size:12px;
739 -}
740 -</style>
741 -
742 - <?php
743 - echo '<script src="http://api.loginizer.com/'.(defined('LOGINIZER_PREMIUM') ? 'news_security.js' : 'news.js').'"></script><br>';
877 +Regards,
878 +$sitename','loginizer');
744 879
745 - // Saved ?
746 - if(!empty($GLOBALS['lz_saved'])){
747 - echo '<div id="message" class="updated"><p>'. __('The settings were saved successfully', 'loginizer'). '</p></div><br />';
880 + if(empty($loginizer['login_mail_subject'])){
881 + $loginizer['login_mail_subject'] = $loginizer['login_mail_default_sub'];
748 882 }
749 883
750 - // Any errors ?
751 - if(!empty($lz_error)){
752 - lz_report_error($lz_error);echo '<br />';
884 + if(empty($loginizer['login_mail_body'])){
885 + $loginizer['login_mail_body'] = $loginizer['login_mail_default_msg'];
753 886 }
754 887
755 - ?>
888 + // Default messages
889 + $loginizer['d_msg']['inv_userpass'] = __('Incorrect Username or Password', 'loginizer');
890 + $loginizer['d_msg']['ip_blacklisted'] = __('Your IP has been blacklisted', 'loginizer');
891 + $loginizer['d_msg']['attempts_left'] = __('attempt(s) left', 'loginizer');
892 + $loginizer['d_msg']['lockout_err'] = __('You have exceeded maximum login retries<br /> Please try after', 'loginizer');
893 + $loginizer['d_msg']['minutes_err'] = __('minute(s)', 'loginizer');
894 + $loginizer['d_msg']['hours_err'] = __('hour(s)', 'loginizer');
756 895
757 - <div class="postbox">
896 + // Message Strings
897 + $loginizer['msg'] = get_option('loginizer_msg', []);
758 898
759 - <button class="handlediv button-link" aria-expanded="true" type="button">
760 - <span class="screen-reader-text">Toggle panel: Getting Started</span>
761 - <span class="toggle-indicator" aria-hidden="true"></span>
762 - </button>
763 -
764 - <h2 class="hndle ui-sortable-handle">
765 - <span><?php echo __('Getting Started', 'loginizer'); ?></span>
766 - </h2>
767 -
768 - <div class="inside">
769 -
770 - <form action="" method="post" enctype="multipart/form-data">
771 - <?php wp_nonce_field('loginizer-options'); ?>
772 - <table class="form-table">
773 - <tr>
774 - <td scope="row" valign="top" colspan="2" style="line-height:150%">
775 - <i>Welcome to Loginizer Security. By default the <b>Brute Force Protection</b> is immediately enabled. You should start by going over the default settings and tweaking them as per your needs.</i>
776 - <?php
777 - if(defined('LOGINIZER_PREMIUM')){
778 - echo '<br><i>In the Premium version of Loginizer you have many more features. We recommend you enable features like <b>reCAPTCHA, Two Factor Auth or Email based PasswordLess</b> login. These features will improve your websites security.</i>';
779 - }
780 - ?>
781 - </td>
782 - </tr>
783 - </table>
784 - </form>
785 -
786 - </div>
787 - </div>
899 + foreach($loginizer['d_msg'] as $lk => $lv){
900 + if(empty($loginizer['msg'][$lk])){
901 + $loginizer['msg'][$lk] = $loginizer['d_msg'][$lk];
902 + }
903 + }
788 904
789 - <div class="postbox">
905 + $loginizer['2fa_d_msg']['otp_app'] = __('Please enter the OTP as seen in your App', 'loginizer');
906 + $loginizer['2fa_d_msg']['otp_email'] = __('Please enter the OTP emailed to you', 'loginizer');
907 + $loginizer['2fa_d_msg']['otp_field'] = __('One Time Password', 'loginizer');
908 + $loginizer['2fa_d_msg']['otp_question'] = __('Please answer your security question', 'loginizer');
909 + $loginizer['2fa_d_msg']['otp_answer'] = __('Your Answer', 'loginizer');
790 910
791 - <button class="handlediv button-link" aria-expanded="true" type="button">
792 - <span class="screen-reader-text">Toggle panel: System Information</span>
793 - <span class="toggle-indicator" aria-hidden="true"></span>
794 - </button>
795 -
796 - <h2 class="hndle ui-sortable-handle">
797 - <span><?php echo __('System Information', 'loginizer'); ?></span>
798 - </h2>
799 -
800 - <div class="inside">
801 -
802 - <form action="" method="post" enctype="multipart/form-data">
803 - <?php wp_nonce_field('loginizer-options'); ?>
804 - <table class="wp-list-table fixed striped users" cellspacing="1" border="0" width="95%" cellpadding="10" align="center">
805 - <?php
806 - echo '
807 - <tr>
808 - <th align="left" width="25%">'.__('Loginizer Version', 'loginizer').'</th>
809 - <td>'.LOGINIZER_VERSION.(defined('LOGINIZER_PREMIUM') ? ' (Security PRO Version)' : '').'</td>
810 - </tr>';
811 -
812 - if(defined('LOGINIZER_PREMIUM')){
813 - echo '
814 - <tr>
815 - <th align="left" valign="top">'.__('Loginizer License', 'loginizer').'</th>
816 - <td align="left">
817 - '.(empty($loginizer['license']) ? '<span style="color:red">Unlicensed</span> &nbsp; &nbsp;' : '').'
818 - <input type="text" name="lz_license" value="'.(empty($loginizer['license']) ? '' : $loginizer['license']['license']).'" size="30" placeholder="e.g. WXCSE-SFJJX-XXXXX-AAAAA-BBBBB" style="width:300px;" /> &nbsp;
819 - <input name="save_lz" class="button button-primary" value="Update License" type="submit" />';
820 -
821 - if(!empty($loginizer['license'])){
822 -
823 - $expires = $loginizer['license']['expires'];
824 - $expires = substr($expires, 0, 4).'/'.substr($expires, 4, 2).'/'.substr($expires, 6);
825 -
826 - echo '<div style="margin-top:10px;">License Active : '.(empty($loginizer['license']['active']) ? '<span style="color:red">No</span>' : 'Yes').' &nbsp; &nbsp; &nbsp;
827 - License Expires : '.($loginizer['license']['expires'] <= date('Ymd') ? '<span style="color:red">'.$expires.'</span>' : $expires).'
828 - </div>';
829 - }
830 -
831 -
832 - echo
833 - '</td>
834 - </tr>';
835 - }
836 -
837 - echo '<tr>
838 - <th align="left">'.__('URL', 'loginizer').'</th>
839 - <td>'.get_site_url().'</td>
840 - </tr>
841 - <tr>
842 - <th align="left">'.__('Path', 'loginizer').'</th>
843 - <td>'.ABSPATH.'</td>
844 - </tr>
845 - <tr>
846 - <th align="left">'.__('Server\'s IP Address', 'loginizer').'</th>
847 - <td>'.$_SERVER['SERVER_ADDR'].'</td>
848 - </tr>
849 - <tr>
850 - <th align="left">'.__('Your IP Address', 'loginizer').'</th>
851 - <td>'.$_SERVER['REMOTE_ADDR'].'</td>
852 - </tr>
853 - <tr>
854 - <th align="left">'.__('wp-config.php is writable', 'loginizer').'</th>
855 - <td>'.(is_writable(ABSPATH.'/wp-config.php') ? '<span style="color:red">Yes</span>' : '<span style="color:green">No</span>').'</td>
856 - </tr>';
857 -
858 - if(file_exists(ABSPATH.'/.htaccess')){
859 - echo '
860 - <tr>
861 - <th align="left">'.__('.htaccess is writable', 'loginizer').'</th>
862 - <td>'.(is_writable(ABSPATH.'/.htaccess') ? '<span style="color:red">Yes</span>' : '<span style="color:green">No</span>').'</td>
863 - </tr>';
864 -
865 - }
866 -
867 - ?>
868 - </table>
869 - </form>
870 -
871 - </div>
872 - </div>
911 + // Message Strings
912 + $loginizer['2fa_msg'] = get_option('loginizer_2fa_msg', []);
873 913
874 - <div id="" class="postbox">
914 + foreach($loginizer['2fa_d_msg'] as $lk => $lv){
915 + if(empty($loginizer['2fa_msg'][$lk])){
916 + $loginizer['2fa_msg'][$lk] = $loginizer['2fa_d_msg'][$lk];
917 + }
918 + }
875 919
876 - <button class="handlediv button-link" aria-expanded="true" type="button">
877 - <span class="screen-reader-text">Toggle panel: File Permissions</span>
878 - <span class="toggle-indicator" aria-hidden="true"></span>
879 - </button>
880 -
881 - <h2 class="hndle ui-sortable-handle">
882 - <span><?php echo __('File Permissions', 'loginizer'); ?></span>
883 - </h2>
884 -
885 - <div class="inside">
886 -
887 - <form action="" method="post" enctype="multipart/form-data">
888 - <?php wp_nonce_field('loginizer-options'); ?>
889 - <table class="wp-list-table fixed striped users" border="0" width="95%" cellpadding="10" align="center">
890 - <?php
891 -
892 - echo '
893 - <tr>
894 - <th style="background:#EFEFEF;">'.__('Relative Path', 'loginizer').'</th>
895 - <th style="width:10%; background:#EFEFEF;">'.__('Suggested', 'loginizer').'</th>
896 - <th style="width:10%; background:#EFEFEF;">'.__('Actual', 'loginizer').'</th>
897 - </tr>';
898 -
899 - $files_to_check = array('/' => '0755',
900 - '/wp-admin' => '0755',
901 - '/wp-includes' => '0755',
902 - '/wp-config.php' => '0444',
903 - '/wp-content' => '0755',
904 - '/wp-content/themes' => '0755',
905 - '/wp-content/plugins' => '0755',
906 - '.htaccess' => '0444');
907 -
908 - $root = ABSPATH;
909 -
910 - foreach($files_to_check as $k => $v){
911 -
912 - $path = $root.'/'.$k;
913 - $stat = stat($path);
914 - $suggested = $v;
915 - $actual = substr(sprintf('%o', $stat['mode']), -4);
916 -
917 - echo '
918 - <tr>
919 - <td>'.$k.'</td>
920 - <td>'.$suggested.'</td>
921 - <td><span '.($suggested != $actual ? 'style="color: red;"' : '').'>'.$actual.'</span></td>
922 - </tr>';
923 -
924 - }
925 -
926 - ?>
927 - </table>
928 - </form>
929 -
930 - </div>
931 - </div>
920 +}
932 921
933 -<?php
934 -
935 - loginizer_page_footer();
936 -
922 +function loginizer_social_login_load(){
923 + include_once LOGINIZER_DIR . '/main/social-login.php';
937 924 }
938 925
939 -// The Loginizer Admin Options Page
940 -function loginizer_page_brute_force(){
926 +// Checks if softaculous is installed on the server.
927 +function loginizer_check_softaculous(){
941 928
942 - global $wpdb, $wp_roles, $loginizer;
943 -
944 - if(!current_user_can('manage_options')){
945 - wp_die('Sorry, but you do not have permissions to change settings.');
929 + // Checking if we have Softaculous installed?
930 + if(!preg_match('/^\/home(?:\d+)?\/.*\//U', ABSPATH, $matches)){
931 + return false;
946 932 }
947 933
948 - /* Make sure post was from this page */
949 - if(count($_POST) > 0){
950 - check_admin_referer('loginizer-options');
934 + if(empty($matches) || empty($matches[0])){
935 + return false;
951 936 }
952 -
953 - // BEGIN THEME
954 - loginizer_page_header('Loginizer - Brute Force Settings');
955 -
956 - // Load the blacklist and whitelist
957 - $loginizer['blacklist'] = get_option('loginizer_blacklist');
958 - $loginizer['whitelist'] = get_option('loginizer_whitelist');
959 -
960 - if(isset($_POST['save_lz'])){
961 -
962 - $max_retries = (int) lz_optpost('max_retries');
963 - $lockout_time = (int) lz_optpost('lockout_time');
964 - $max_lockouts = (int) lz_optpost('max_lockouts');
965 - $lockouts_extend = (int) lz_optpost('lockouts_extend');
966 - $reset_retries = (int) lz_optpost('reset_retries');
967 - $notify_email = (int) lz_optpost('notify_email');
968 -
969 - $lockout_time = $lockout_time * 60;
970 - $lockouts_extend = $lockouts_extend * 60 * 60;
971 - $reset_retries = $reset_retries * 60 * 60;
972 -
973 - if(empty($error)){
974 -
975 - $option['max_retries'] = $max_retries;
976 - $option['lockout_time'] = $lockout_time;
977 - $option['max_lockouts'] = $max_lockouts;
978 - $option['lockouts_extend'] = $lockouts_extend;
979 - $option['reset_retries'] = $reset_retries;
980 - $option['notify_email'] = $notify_email;
981 -
982 - // Save the options
983 - update_option('loginizer_options', $option);
984 -
985 - $saved = true;
986 -
987 - }else{
988 - lz_report_error($error);
989 - }
990 -
991 - if(!empty($notice)){
992 - lz_report_notice($notice);
993 - }
994 -
995 - if(!empty($saved)){
996 - echo '<div id="message" class="updated"><p>'
997 - . __('The settings were saved successfully', 'loginizer')
998 - . '</p></div><br />';
999 - }
1000 -
937 +
938 + $softaculous_path = $matches[0] . '.softaculous/installations.php';
939 + if(!file_exists($softaculous_path)){
940 + return false;
1001 941 }
1002 942
1003 - // Delete a Blackist IP range
1004 - if(isset($_GET['bdelid'])){
1005 -
1006 - $delid = (int) lz_optreq('bdelid');
1007 -
1008 - // Unset and save
1009 - $blacklist = $loginizer['blacklist'];
1010 - unset($blacklist[$delid]);
1011 - update_option('loginizer_blacklist', $blacklist);
1012 -
1013 - echo '<div id="message" class="updated fade"><p>'
1014 - . __('The Blacklist IP range has been deleted successfully', 'loginizer')
1015 - . '</p></div><br />';
1016 -
943 + // Checking if users has changed the branding of Softaculous.
944 + $universal_file = '';
945 + // Plesk, ISPManager, ISPConfig, InterWorx, H-Sphere, CentOS Web Panel, Softaculous Remote and Softaculous Enterprise
946 + if(file_exists('/usr/local/softaculous/enduser/universal.php')){
947 + $universal_file = '/usr/local/softaculous/enduser/universal.php';
948 + }else if(file_exists('/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php')){
949 + $universal_file = '/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php';
950 + }else if(file_exists('/usr/local/directadmin/plugins/softaculous/enduser/universal.php')){
951 + $universal_file = '/usr/local/directadmin/plugins/softaculous/enduser/universal.php';
952 + }else if(file_exists('/usr/local/vesta/softaculous/enduser/universal.php')){
953 + $universal_file = '/usr/local/vesta/softaculous/enduser/universal.php';
1017 954 }
1018 -
1019 - // Delete a Whitelist IP range
1020 - if(isset($_GET['delid'])){
1021 -
1022 - $delid = (int) lz_optreq('delid');
1023 -
1024 - // Unset and save
1025 - $whitelist = $loginizer['whitelist'];
1026 - unset($whitelist[$delid]);
1027 - update_option('loginizer_whitelist', $whitelist);
1028 -
1029 - echo '<div id="message" class="updated fade"><p>'
1030 - . __('The Whitelist IP range has been deleted successfully', 'loginizer')
1031 - . '</p></div><br />';
1032 -
955 +
956 + if(empty($universal_file)){
957 + return false;
1033 958 }
1034 -
1035 - if(isset($_POST['blacklist_iprange'])){
1036 959
1037 - $start_ip = lz_optpost('start_ip');
1038 - $end_ip = lz_optpost('end_ip');
1039 -
1040 - if(empty($start_ip)){
1041 - $error[] = 'Please enter the Start IP';
1042 - }
1043 -
1044 - // If no end IP we consider only 1 IP
1045 - if(empty($end_ip)){
1046 - $end_ip = $start_ip;
1047 - }
1048 -
1049 - if(!lz_valid_ip($start_ip)){
1050 - $error[] = 'Please provide a valid start IP';
1051 - }
1052 -
1053 - if(!lz_valid_ip($end_ip)){
1054 - $error[] = 'Please provide a valid end IP';
1055 - }
1056 -
1057 - // Regular ranges will work
1058 - if(ip2long($start_ip) > ip2long($end_ip)){
1059 -
1060 - // BUT, if 0.0.0.1 - 255.255.255.255 is given, it will not work
1061 - if(ip2long($start_ip) >= 0 && ip2long($end_ip) < 0){
1062 - // This is right
1063 - }else{
1064 - $error[] = 'The End IP cannot be smaller than the Start IP';
1065 - }
1066 -
1067 - }
1068 -
1069 - if(empty($error)){
1070 -
1071 - $blacklist = $loginizer['blacklist'];
1072 -
1073 - foreach($blacklist as $k => $v){
1074 -
1075 - // This is to check if there is any other range exists with the same Start or End IP
1076 - if(( ip2long($start_ip) <= ip2long($v['start']) && ip2long($v['start']) <= ip2long($end_ip) )
1077 - || ( ip2long($start_ip) <= ip2long($v['end']) && ip2long($v['end']) <= ip2long($end_ip) )
1078 - ){
1079 - $error[] = 'The Start IP or End IP submitted conflicts with an existing IP range !';
1080 - break;
1081 - }
1082 -
1083 - // This is to check if there is any other range exists with the same Start IP
1084 - if(ip2long($v['start']) <= ip2long($start_ip) && ip2long($start_ip) <= ip2long($v['end'])){
1085 - $error[] = 'The Start IP is present in an existing range !';
1086 - break;
1087 - }
1088 -
1089 - // This is to check if there is any other range exists with the same End IP
1090 - if(ip2long($v['start']) <= ip2long($end_ip) && ip2long($end_ip) <= ip2long($v['end'])){
1091 - $error[] = 'The End IP is present in an existing range!';
1092 - break;
1093 - }
1094 -
1095 - }
1096 -
1097 - $newid = ( empty($blacklist) ? 0 : max(array_keys($blacklist)) ) + 1;
1098 -
1099 - if(empty($error)){
1100 -
1101 - $blacklist[$newid] = array();
1102 - $blacklist[$newid]['start'] = $start_ip;
1103 - $blacklist[$newid]['end'] = $end_ip;
1104 - $blacklist[$newid]['time'] = time();
1105 -
1106 - update_option('loginizer_blacklist', $blacklist);
1107 -
1108 - echo '<div id="message" class="updated fade"><p>'
1109 - . __('Blacklist IP range added successfully', 'loginizer')
1110 - . '</p></div><br />';
1111 -
1112 - }
1113 -
1114 - }
1115 -
1116 - if(!empty($error)){
1117 - lz_report_error($error);echo '<br />';
1118 - }
1119 -
960 + $universal = file_get_contents($universal_file);
961 +
962 + if(empty($universal)){
963 + return false;
1120 964 }
1121 -
1122 - if(isset($_POST['whitelist_iprange'])){
1123 965
1124 - $start_ip = lz_optpost('start_ip_w');
1125 - $end_ip = lz_optpost('end_ip_w');
1126 -
1127 - if(empty($start_ip)){
1128 - $error[] = 'Please enter the Start IP';
1129 - }
1130 -
1131 - // If no end IP we consider only 1 IP
1132 - if(empty($end_ip)){
1133 - $end_ip = $start_ip;
1134 - }
1135 -
1136 - if(!lz_valid_ip($start_ip)){
1137 - $error[] = 'Please provide a valid start IP';
1138 - }
1139 -
1140 - if(!lz_valid_ip($end_ip)){
1141 - $error[] = 'Please provide a valid end IP';
1142 - }
1143 -
1144 - if(ip2long($start_ip) > ip2long($end_ip)){
1145 -
1146 - // BUT, if 0.0.0.1 - 255.255.255.255 is given, it will not work
1147 - if(ip2long($start_ip) >= 0 && ip2long($end_ip) < 0){
1148 - // This is right
1149 - }else{
1150 - $error[] = 'The End IP cannot be smaller than the Start IP';
1151 - }
1152 -
1153 - }
1154 -
1155 - if(empty($error)){
1156 -
1157 - $whitelist = $loginizer['whitelist'];
1158 -
1159 - foreach($whitelist as $k => $v){
1160 -
1161 - // This is to check if there is any other range exists with the same Start or End IP
1162 - if(( ip2long($start_ip) <= ip2long($v['start']) && ip2long($v['start']) <= ip2long($end_ip) )
1163 - || ( ip2long($start_ip) <= ip2long($v['end']) && ip2long($v['end']) <= ip2long($end_ip) )
1164 - ){
1165 - $error[] = 'The Start IP or End IP submitted conflicts with an existing IP range !';
1166 - break;
1167 - }
1168 -
1169 - // This is to check if there is any other range exists with the same Start IP
1170 - if(ip2long($v['start']) <= ip2long($start_ip) && ip2long($start_ip) <= ip2long($v['end'])){
1171 - $error[] = 'The Start IP is present in an existing range !';
1172 - break;
1173 - }
1174 -
1175 - // This is to check if there is any other range exists with the same End IP
1176 - if(ip2long($v['start']) <= ip2long($end_ip) && ip2long($end_ip) <= ip2long($v['end'])){
1177 - $error[] = 'The End IP is present in an existing range!';
1178 - break;
1179 - }
1180 -
1181 - }
1182 -
1183 - $newid = ( empty($whitelist) ? 0 : max(array_keys($whitelist)) ) + 1;
1184 -
1185 - if(empty($error)){
1186 -
1187 - $whitelist[$newid] = array();
1188 - $whitelist[$newid]['start'] = $start_ip;
1189 - $whitelist[$newid]['end'] = $end_ip;
1190 - $whitelist[$newid]['time'] = time();
1191 -
1192 - update_option('loginizer_whitelist', $whitelist);
1193 -
1194 - echo '<div id="message" class="updated fade"><p>'
1195 - . __('Whitelist IP range added successfully', 'loginizer')
1196 - . '</p></div><br />';
1197 -
1198 - }
1199 -
1200 - }
1201 -
1202 - if(!empty($error)){
1203 - lz_report_error($error);echo '<br />';
1204 - }
966 + // Checking if Softaculous is being whitelabeled
967 + if(preg_match('/\$globals\[["\']sn["\']\]\s.?=\s.?["\']Softaculous["\']/', $universal)){
968 + update_option('loginizer_softwp_upgrade', time());
1205 969 }
1206 -
1207 - // Get the logs
1208 - $result = array();
1209 - $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` ORDER BY `count` DESC LIMIT 0, 10;", 1);
1210 - //print_r($result);
1211 -
1212 - // Reload the settings
1213 - $loginizer['blacklist'] = get_option('loginizer_blacklist');
1214 - $loginizer['whitelist'] = get_option('loginizer_whitelist');
1215 -
1216 - ?>
1217 970
1218 - <div id="" class="postbox">
1219 -
1220 - <button class="handlediv button-link" aria-expanded="true" type="button">
1221 - <span class="screen-reader-text">Toggle panel: Failed Login Attempts Logs</span>
1222 - <span class="toggle-indicator" aria-hidden="true"></span>
1223 - </button>
1224 -
1225 - <h2 class="hndle ui-sortable-handle">
1226 - <?php echo __('<span>Failed Login Attempts Logs</span> &nbsp; (Past '.($loginizer['reset_retries']/60/60).' hours)','loginizer'); ?>
1227 - </h2>
1228 -
1229 - <div class="inside">
1230 - <table class="wp-list-table widefat fixed users" border="0">
1231 - <tr>
1232 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('IP','loginizer'); ?></th>
1233 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Last Failed Attempt (DD/MM/YYYY)','loginizer'); ?></th>
1234 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Failed Attempts Count','loginizer'); ?></th>
1235 - <th scope="row" valign="top" style="background:#EFEFEF;" width="150"><?php echo __('Lockouts Count','loginizer'); ?></th>
1236 - </tr>
1237 - <?php
1238 - if(empty($result)){
1239 - echo '
1240 - <tr>
1241 - <td colspan="4">
1242 - No Logs. You will see logs about failed login attempts here.
1243 - </td>
1244 - </tr>';
1245 - }else{
1246 - foreach($result as $ik => $iv){
1247 - $status_button = (!empty($iv['status']) ? 'disable' : 'enable');
1248 - echo '
1249 - <tr>
1250 - <td>
1251 - '.$iv['ip'].'
1252 - </td>
1253 - <td>
1254 - '.date('d/m/Y H:i:s', $iv['time']).'
1255 - </td>
1256 - <td>
1257 - '.$iv['count'].'
1258 - </td>
1259 - <td>
1260 - '.$iv['lockout'].'
1261 - </td>
1262 - </tr>';
1263 - }
1264 - }
1265 - ?>
1266 - </table>
1267 - </div>
1268 - </div>
1269 - <br />
1270 -
1271 - <div id="" class="postbox">
1272 -
1273 - <button class="handlediv button-link" aria-expanded="true" type="button">
1274 - <span class="screen-reader-text">Toggle panel: Brute Force Settings</span>
1275 - <span class="toggle-indicator" aria-hidden="true"></span>
1276 - </button>
1277 -
1278 - <h2 class="hndle ui-sortable-handle">
1279 - <span><?php echo __('Brute Force Settings', 'loginizer'); ?></span>
1280 - </h2>
1281 -
1282 - <div class="inside">
1283 -
1284 - <form action="" method="post" enctype="multipart/form-data">
1285 - <?php wp_nonce_field('loginizer-options'); ?>
1286 - <table class="form-table">
1287 - <tr>
1288 - <th scope="row" valign="top"><label for="max_retries"><?php echo __('Max Retries','loginizer'); ?></label></th>
1289 - <td>
1290 - <input type="text" size="3" value="<?php echo lz_optpost('max_retries', $loginizer['max_retries']); ?>" name="max_retries" id="max_retries" /> <?php echo __('Maximum failed attempts allowed before lockout','loginizer'); ?> <br />
1291 - </td>
1292 - </tr>
1293 - <tr>
1294 - <th scope="row" valign="top"><label for="lockout_time"><?php echo __('Lockout Time','loginizer'); ?></label></th>
1295 - <td>
1296 - <input type="text" size="3" value="<?php echo (!empty($lockout_time) ? $lockout_time : $loginizer['lockout_time']) / 60; ?>" name="lockout_time" id="lockout_time" /> <?php echo __('minutes','loginizer'); ?> <br />
1297 - </td>
1298 - </tr>
1299 - <tr>
1300 - <th scope="row" valign="top"><label for="max_lockouts"><?php echo __('Max Lockouts','loginizer'); ?></label></th>
1301 - <td>
1302 - <input type="text" size="3" value="<?php echo lz_optpost('max_lockouts', $loginizer['max_lockouts']); ?>" name="max_lockouts" id="max_lockouts" /> <?php echo __('','loginizer'); ?> <br />
1303 - </td>
1304 - </tr>
1305 - <tr>
1306 - <th scope="row" valign="top"><label for="lockouts_extend"><?php echo __('Extend Lockout','loginizer'); ?></label></th>
1307 - <td>
1308 - <input type="text" size="3" value="<?php echo (!empty($lockouts_extend) ? $lockouts_extend : $loginizer['lockouts_extend']) / 60 / 60; ?>" name="lockouts_extend" id="lockouts_extend" /> <?php echo __('hours. Extend Lockout time after Max Lockouts','loginizer'); ?> <br />
1309 - </td>
1310 - </tr>
1311 - <tr>
1312 - <th scope="row" valign="top"><label for="reset_retries"><?php echo __('Reset Retries','loginizer'); ?></label></th>
1313 - <td>
1314 - <input type="text" size="3" value="<?php echo (!empty($reset_retries) ? $reset_retries : $loginizer['reset_retries']) / 60 / 60; ?>" name="reset_retries" id="reset_retries" /> <?php echo __('hours','loginizer'); ?> <br />
1315 - </td>
1316 - </tr>
1317 - <tr>
1318 - <th scope="row" valign="top"><label for="notify_email"><?php echo __('Email Notification','loginizer'); ?></label></th>
1319 - <td>
1320 - <?php echo __('after ','loginizer'); ?>
1321 - <input type="text" size="3" value="<?php echo (!empty($notify_email) ? $notify_email : $loginizer['notify_email']); ?>" name="notify_email" id="notify_email" /> <?php echo __('lockouts <br />0 to disable email notifications','loginizer'); ?>
1322 - </td>
1323 - </tr>
1324 - </table><br />
1325 - <input name="save_lz" class="button button-primary action" value="<?php echo __('Save Settings','loginizer'); ?>" type="submit" />
1326 - </form>
1327 -
1328 - </div>
1329 - </div>
1330 - <br />
1331 -
1332 - <div id="" class="postbox">
1333 -
1334 - <button class="handlediv button-link" aria-expanded="true" type="button">
1335 - <span class="screen-reader-text">Toggle panel: Blacklist IP</span>
1336 - <span class="toggle-indicator" aria-hidden="true"></span>
1337 - </button>
1338 -
1339 - <h2 class="hndle ui-sortable-handle">
1340 - <span><?php echo __('Blacklist IP','loginizer'); ?></span>
1341 - </h2>
1342 -
1343 - <div class="inside">
1344 -
1345 - <?php echo __('Enter the IP you want to blacklist from login','loginizer'); ?>
1346 -
1347 - <form action="" method="post">
1348 - <?php wp_nonce_field('loginizer-options'); ?>
1349 - <table class="form-table">
1350 - <tr>
1351 - <th scope="row" valign="top"><label for="start_ip"><?php echo __('Start IP','loginizer'); ?></label></th>
1352 - <td>
1353 - <input type="text" size="25" value="<?php echo(lz_optpost('start_ip')); ?>" name="start_ip" id="start_ip"/> <?php echo __('Start IP of the range','loginizer'); ?> <br />
1354 - </td>
1355 - </tr>
1356 - <tr>
1357 - <th scope="row" valign="top"><label for="end_ip"><?php echo __('End IP (Optional)','loginizer'); ?></label></th>
1358 - <td>
1359 - <input type="text" size="25" value="<?php echo(lz_optpost('end_ip')); ?>" name="end_ip" id="end_ip"/> <?php echo __('End IP of the range. <br />If you want to blacklist single IP leave this field blank.','loginizer'); ?> <br />
1360 - </td>
1361 - </tr>
1362 - </table><br />
1363 - <input name="blacklist_iprange" class="button button-primary action" value="<?php echo __('Add Blacklist IP Range','loginizer'); ?>" type="submit" />
1364 - </form>
1365 - </div>
1366 -
1367 - <table class="wp-list-table fixed striped users" border="0" width="95%" cellpadding="10" align="center">
1368 - <tr>
1369 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Start IP','loginizer'); ?></th>
1370 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('End IP','loginizer'); ?></th>
1371 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Date (DD/MM/YYYY)','loginizer'); ?></th>
1372 - <th scope="row" valign="top" style="background:#EFEFEF;" width="100"><?php echo __('Options','loginizer'); ?></th>
1373 - </tr>
1374 - <?php
1375 - if(empty($loginizer['blacklist'])){
1376 - echo '
1377 - <tr>
1378 - <td colspan="4">
1379 - No Blacklist IPs. You will see blacklisted IP ranges here.
1380 - </td>
1381 - </tr>';
1382 - }else{
1383 - foreach($loginizer['blacklist'] as $ik => $iv){
1384 - echo '
1385 - <tr>
1386 - <td>
1387 - '.$iv['start'].'
1388 - </td>
1389 - <td>
1390 - '.$iv['end'].'
1391 - </td>
1392 - <td>
1393 - '.date('d/m/Y', $iv['time']).'
1394 - </td>
1395 - <td>
1396 - <a class="submitdelete" href="admin.php?page=loginizer_brute_force&bdelid='.$ik.'" onclick="return confirm(\'Are you sure you want to delete this IP range ?\')">Delete</a>
1397 - </td>
1398 - </tr>';
1399 - }
1400 - }
1401 - ?>
1402 - </table>
1403 - <br />
1404 -
1405 - </div>
1406 -
1407 - <br />
1408 -
1409 - <div id="" class="postbox">
1410 -
1411 - <button class="handlediv button-link" aria-expanded="true" type="button">
1412 - <span class="screen-reader-text">Toggle panel: Whitelist IP</span>
1413 - <span class="toggle-indicator" aria-hidden="true"></span>
1414 - </button>
1415 -
1416 - <h2 class="hndle ui-sortable-handle">
1417 - <span><?php echo __('Whitelist IP', 'loginizer'); ?></span>
1418 - </h2>
1419 -
1420 - <div class="inside">
1421 -
1422 - <?php echo __('Enter the IP you want to whitelist for login','loginizer'); ?>
1423 - <form action="" method="post">
1424 - <?php wp_nonce_field('loginizer-options'); ?>
1425 - <table class="form-table">
1426 - <tr>
1427 - <th scope="row" valign="top"><label for="start_ip_w"><?php echo __('Start IP','loginizer'); ?></label></th>
1428 - <td>
1429 - <input type="text" size="25" value="<?php echo(lz_optpost('start_ip_w')); ?>" name="start_ip_w" id="start_ip_w"/> <?php echo __('Start IP of the range','loginizer'); ?> <br />
1430 - </td>
1431 - </tr>
1432 - <tr>
1433 - <th scope="row" valign="top"><label for="end_ip_w"><?php echo __('End IP (Optional)','loginizer'); ?></label></th>
1434 - <td>
1435 - <input type="text" size="25" value="<?php echo(lz_optpost('end_ip_w')); ?>" name="end_ip_w" id="end_ip_w"/> <?php echo __('End IP of the range. <br />If you want to whitelist single IP leave this field blank.','loginizer'); ?> <br />
1436 - </td>
1437 - </tr>
1438 - </table><br />
1439 - <input name="whitelist_iprange" class="button button-primary action" value="<?php echo __('Add Whitelist IP Range','loginizer'); ?>" type="submit" />
1440 - </form>
1441 - </div>
1442 -
1443 - <table class="wp-list-table fixed striped users" border="0" width="95%" cellpadding="10" align="center">
1444 - <tr>
1445 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Start IP','loginizer'); ?></th>
1446 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('End IP','loginizer'); ?></th>
1447 - <th scope="row" valign="top" style="background:#EFEFEF;"><?php echo __('Date (DD/MM/YYYY)','loginizer'); ?></th>
1448 - <th scope="row" valign="top" style="background:#EFEFEF;" width="100"><?php echo __('Options','loginizer'); ?></th>
1449 - </tr>
1450 - <?php
1451 - if(empty($loginizer['whitelist'])){
1452 - echo '
1453 - <tr>
1454 - <td colspan="4">
1455 - No Whitelist IPs. You will see whitelisted IP ranges here.
1456 - </td>
1457 - </tr>';
1458 - }else{
1459 - foreach($loginizer['whitelist'] as $ik => $iv){
1460 - echo '
1461 - <tr>
1462 - <td>
1463 - '.$iv['start'].'
1464 - </td>
1465 - <td>
1466 - '.$iv['end'].'
1467 - </td>
1468 - <td>
1469 - '.date('d/m/Y', $iv['time']).'
1470 - </td>
1471 - <td>
1472 - <a class="submitdelete" href="admin.php?page=loginizer_brute_force&delid='.$ik.'" onclick="return confirm(\'Are you sure you want to delete this IP range ?\')">Delete</a>
1473 - </td>
1474 - </tr>';
1475 - }
1476 - }
1477 - ?>
1478 - </table>
1479 - <br />
1480 -
1481 - </div>
1482 -
1483 -<?php
1484 -
1485 -loginizer_page_footer();
1486 -
971 + return false;
1487 972 }
1488 973
1489 -
1490 974 // Sorry to see you going
1491 975 register_uninstall_hook(LOGINIZER_FILE, 'loginizer_deactivation');
1492 976
1493 977 function loginizer_deactivation(){
@@ -1505,7 +989,22 @@
1505 989 delete_option('loginizer_options');
1506 990 delete_option('loginizer_last_reset');
1507 991 delete_option('loginizer_whitelist');
1508 992 delete_option('loginizer_blacklist');
993 + delete_option('loginizer_msg');
994 + delete_option('loginizer_2fa_msg');
995 + delete_option('loginizer_2fa_email_template');
996 + delete_option('loginizer_security');
997 + delete_option('loginizer_wp_admin');
998 + delete_option('loginizer_csrf_promo_time');
999 + delete_option('loginizer_backuply_promo_time');
1000 + delete_option('loginizer_promo_time');
1001 + delete_option('loginizer_ins_time');
1002 + delete_option('loginizer_2fa_whitelist');
1003 + delete_option('loginizer_checksums_last_run');
1004 + delete_option('loginizer_checksums_diff');
1005 + delete_option('loginizer_ip_method');
1006 + delete_option('loginizer_2fa_custom_redirect');
1007 + delete_option('external_updates-loginizer-security');
1008 + delete_option('loginizer_login_attempt_stats');
1509 1009
1510 -}
1511 -
1010 +}