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