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