PluginProbe
Loginizer / 2.1.0
Loginizer v2.1.0
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 +586 -1089 1.2.02.1.0 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.0');
9 +define('LOGINIZER_DIR', dirname(LOGINIZER_FILE));
10 10 define('LOGINIZER_URL', plugins_url('', LOGINIZER_FILE));
11 11 define('LOGINIZER_PRO_URL', 'https://loginizer.com/features#compare');
12 +define('LOGINIZER_PRICING_URL', 'https://loginizer.com/pricing');
13 +define('LOGINIZER_DOCS', 'https://loginizer.com/docs/');
12 14
13 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,11 +180,51 @@
155 180 }
156 181
157 182 }
158 183
184 + // Is it less than 1.3.9 ?
185 + if($version < 139){
186 +
187 + $wpdb->query("ALTER TABLE ".$wpdb->prefix."loginizer_logs ADD `url` VARCHAR(255) NOT NULL DEFAULT '' AFTER `ip`;");
188 +
189 + }
190 +
191 + // Setting alignment to left in social login ?
192 + if($version < 201){
193 + $social_settings = get_option('loginizer_social_settings', []);
194 +
195 + if(!empty($social_settings)){
196 + if(!empty($social_settings['login']) && (!empty($social_settings['login']['login_form']) || !empty($social_settings['login']['registration_form']))){
197 + $social_settings['login']['button_alignment'] = 'left';
198 + }
199 +
200 + if(!empty($social_settings['woocommerce']) && (!empty($social_settings['woocommmerce']['login_form']) || !empty($social_settings['woocommerce']['registration_form']))){
201 + $social_settings['woocommerce']['button_alignment'] = 'left';
202 + }
203 +
204 + if(!empty($social_settings['comment']) && !empty($social_settings['comment']['enable_buttons'])){
205 + $social_settings['comment']['button_alignment'] = 'left';
206 + }
207 +
208 + update_option('loginizer_social_settings', $social_settings);
209 + }
210 + }
211 +
159 212 // Save the new Version
160 213 update_option('loginizer_version', LOGINIZER_VERSION);
161 214
215 + // TODO:: REMOVE THIS AFTER MARCH 2025
216 + $softwp_upgrade = get_option('loginizer_softwp_upgrade', 0);
217 + if(!defined('SITEPAD') && empty($softwp_upgrade)){
218 + loginizer_check_softaculous();
219 + }
220 +
221 + // In Sitepad Math Captcha is enabled by default
222 + if(defined('SITEPAD') && get_option('loginizer_captcha') === false){
223 + $option['captcha_no_google'] = 1;
224 + add_option('loginizer_captcha', $option);
225 + }
226 +
162 227 }
163 228
164 229 // Add the action to load the plugin
165 230 add_action('plugins_loaded', 'loginizer_load_plugin');
@@ -170,12 +235,27 @@
170 235 global $loginizer;
171 236
172 237 // Check if the installed version is outdated
173 238 loginizer_update_check();
239 +
240 + // Set the array
241 + if(empty($loginizer)){
242 + $loginizer = array();
243 + }
174 244
245 + $loginizer['prefix'] = !defined('SITEPAD') ? 'Loginizer ' : 'SitePad ';
246 + $loginizer['app'] = !defined('SITEPAD') ? 'WordPress' : 'SitePad';
247 + $loginizer['login_basename'] = !defined('SITEPAD') ? 'wp-login.php' : 'login.php';
248 + $loginizer['wp-includes'] = !defined('SITEPAD') ? 'wp-includes' : 'site-inc';
249 +
250 + // The IP Method to use
251 + $loginizer['ip_method'] = get_option('loginizer_ip_method');
252 + if($loginizer['ip_method'] == 3){
253 + $loginizer['custom_ip_method'] = get_option('loginizer_custom_ip_method');
254 + }
255 +
256 + // Load settings
175 257 $options = get_option('loginizer_options');
176 -
177 - $loginizer = array();
178 258 $loginizer['max_retries'] = empty($options['max_retries']) ? 3 : $options['max_retries'];
179 259 $loginizer['lockout_time'] = empty($options['lockout_time']) ? 900 : $options['lockout_time']; // 15 minutes
180 260 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
181 261 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
@@ -180,15 +260,43 @@
180 260 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
181 261 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
182 262 $loginizer['reset_retries'] = empty($options['reset_retries']) ? 86400 : $options['reset_retries']; // 24 hours
183 263 $loginizer['notify_email'] = empty($options['notify_email']) ? 0 : $options['notify_email'];
184 -
264 + $loginizer['notify_email_address'] = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email');
265 + $loginizer['trusted_ips'] = empty($options['trusted_ips']) ? false : true;
266 + $loginizer['blocked_screen'] = empty($options['blocked_screen']) ? false : true;
267 + $loginizer['social_settings'] = get_option('loginizer_social_settings', []);
268 +
269 + if(!empty($options['notify_email_address'])){
270 + $loginizer['notify_email_address'] = $options['notify_email_address'];
271 + $loginizer['custom_notify_email'] = 1;
272 + }
273 +
274 + // Login Success Email Notification.
275 + $loginizer['login_mail'] = get_option('loginizer_login_mail', []);
276 + add_action('init', 'loginizer_load_translation_vars', 0);
277 +
278 + $loginizer['login_mail_subject'] = empty($loginizer['login_mail']['subject']) ? '' : $loginizer['login_mail']['subject'];
279 + $loginizer['login_mail_body'] = empty($loginizer['login_mail']['body']) ? '' : $loginizer['login_mail']['body'];
280 +
185 281 // Load the blacklist and whitelist
186 - $loginizer['blacklist'] = get_option('loginizer_blacklist');
187 - $loginizer['whitelist'] = get_option('loginizer_whitelist');
282 + $loginizer['blacklist'] = get_option('loginizer_blacklist', []);
283 + $loginizer['whitelist'] = get_option('loginizer_whitelist', []);
284 + $loginizer['2fa_whitelist'] = get_option('loginizer_2fa_whitelist');
188 285
286 + // It should not be false
287 + if(empty($loginizer['2fa_whitelist'])){
288 + $loginizer['2fa_whitelist'] = array();
289 + }
290 +
189 291 // When was the database cleared last time
190 292 $loginizer['last_reset'] = get_option('loginizer_last_reset');
293 +
294 + if(!isset($loginizer['ultimate-member-active'])){
295 + $um_is_active = in_array('ultimate-member/ultimate-member.php', apply_filters('active_plugins', get_option('active_plugins', [])));
296 +
297 + $loginizer['ultimate-member-active'] = !empty($um_is_active) ? true : false;
298 + }
191 299
192 300 //print_r($loginizer);
193 301
194 302 // Clear retries
@@ -204,34 +312,64 @@
204 312 $loginizer['ins_time'] = $ins_time;
205 313
206 314 // Set the current IP
207 315 $loginizer['current_ip'] = lz_getip();
316 +
317 + // Is Brute Force Disabled ?
318 + $loginizer['disable_brute'] = get_option('loginizer_disable_brute');
208 319
209 - /* Filters and actions */
320 + // Filters and actions
321 + if(empty($loginizer['disable_brute'])){
210 322
211 - // Use this to verify before WP tries to login
212 - // Is always called and is the first function to be called
213 - //add_action('wp_authenticate', 'loginizer_wp_authenticate', 10, 2);// Not called by XML-RPC
214 - add_filter('authenticate', 'loginizer_wp_authenticate', 10001, 3);// This one is called by xmlrpc as well as GUI
215 -
216 - // Is called when a login attempt fails
217 - // Hence Update our records that the login failed
218 - add_action('wp_login_failed', 'loginizer_login_failed');
219 -
220 - // Is called before displaying the error message so that we dont show that the username is wrong or the password
221 - // Update Error message
222 - add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2);
223 -
224 - // Is the premium features there ?
225 - if(file_exists(LOGINIZER_DIR.'/premium.php')){
323 + // Use this to verify before WP tries to login
324 + // Is always called and is the first function to be called
325 + //add_action('wp_authenticate', 'loginizer_wp_authenticate', 10, 2);// Not called by XML-RPC
326 + add_filter('authenticate', 'loginizer_wp_authenticate', 10001, 3);// This one is called by xmlrpc as well as GUI
226 327
227 - // Include the file
228 - include_once(LOGINIZER_DIR.'/premium.php');
328 + // Is called when a login attempt fails
329 + // Hence Update our records that the login failed
330 + add_action('wp_login_failed', 'loginizer_login_failed');
229 331
230 - loginizer_security_init();
332 + // Is called before displaying the error message so that we dont show that the username is wrong or the password
333 + // Update Error message
334 + add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2);
335 + add_action('woocommerce_login_failed', 'loginizer_woocommerce_error_handler', 10001);
336 + add_action('wp_login', 'loginizer_login_success', 11, 2);
337 + add_action('rsssl_two_factor_user_authenticated', 'loginizer_rsssl_2fa_success');
231 338
339 + if(!empty($loginizer['ultimate-member-active'])){
340 + add_action('wp_login_failed', 'loginizer_ultimatemember_error_handler', 10001);
341 + }
342 +
343 + if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings'])){
344 + add_filter('wp_login_errors', 'loginizer_social_login_error_handler', 10000, 2);
345 + }
232 346 }
347 +
348 + // Social Login Form Actions
349 + if(!empty($loginizer['social_settings'])){
350 + if(!empty($loginizer['social_settings']['login']['login_form'])){
351 + add_action('login_form', 'loginizer_social_btn_login');
352 + }
353 + }
233 354
355 + if((function_exists('wp_doing_ajax') && wp_doing_ajax()) || (defined( 'DOING_AJAX' ) && DOING_AJAX)){
356 + include_once LOGINIZER_DIR . '/main/ajax.php';
357 + }
358 +
359 + if(is_admin()){
360 + include_once LOGINIZER_DIR . '/main/admin.php';
361 + }
362 +
363 + // ----------------
364 + // PRO INIT END
365 + // ----------------
366 +
367 + // Secuity checks for social login.
368 + if(!empty($_GET['lz_social_provider']) && loginizer_can_login() && empty($_GET['lz_api'])){
369 + add_action('init', 'loginizer_social_login_load');
370 + return;
371 + }
234 372 }
235 373
236 374 // Should return NULL if everything is fine
237 375 function loginizer_wp_authenticate($user, $username, $password){
@@ -245,24 +383,67 @@
245 383 // Are you whitelisted ?
246 384 if(loginizer_is_whitelisted()){
247 385 $loginizer['ip_is_whitelisted'] = 1;
248 386 return $user;
387 +
388 + } else if (!empty($loginizer['trusted_ips'])){
389 + $lz_cannot_login = 1;
390 +
391 + // This is used by WP Activity Log
392 + apply_filters( 'wp_login_blocked', $username );
393 +
394 + // Shows a blocked screen
395 + if(!empty($loginizer['blocked_screen'])){
396 + $lz_error['trusted_ip'] = __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer');
397 + loginizer_blocked_page($lz_error);
398 + }
399 +
400 + return new WP_Error('ip_blacklisted', __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer'));
249 401 }
250 402
251 403 // Are you blacklisted ?
252 404 if(loginizer_is_blacklisted()){
253 405 $lz_cannot_login = 1;
406 +
407 + // This is used by WP Activity Log
408 + apply_filters( 'wp_login_blocked', $username );
409 +
410 + // Shows a blocked screen
411 + if(!empty($loginizer['blocked_screen'])){
412 + loginizer_blocked_page($lz_error);
413 + }
414 +
254 415 return new WP_Error('ip_blacklisted', implode('', $lz_error), 'loginizer');
255 416 }
256 417
418 + // Is the username blacklisted ?
419 + if(function_exists('loginizer_user_blacklisted')){
420 + if(loginizer_user_blacklisted($username)){
421 + $lz_cannot_login = 1;
422 +
423 + // This is used by WP Activity Log
424 + apply_filters( 'wp_login_blocked', $username );
425 +
426 + return new WP_Error('user_blacklisted', implode('', $lz_error), 'loginizer');
427 + }
428 + }
429 +
257 430 if(loginizer_can_login()){
258 431 return $user;
259 432 }
260 433
261 434 $lz_cannot_login = 1;
435 +
436 + // This is used by WP Activity Log
437 + apply_filters( 'wp_login_blocked', $username );
262 438
439 + // Shows a blocked screen
440 + if(!empty($loginizer['blocked_screen'])){
441 + loginizer_blocked_page($lz_error);
442 + }
443 +
263 444 return new WP_Error('ip_blocked', implode('', $lz_error), 'loginizer');
264 -
445 +
265 446 }
266 447
267 448 function loginizer_can_login(){
268 449
@@ -268,12 +449,13 @@
268 449
269 450 global $wpdb, $loginizer, $lz_error;
270 451
271 452 // Get the logs
272 - $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
453 + $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
454 + $result = lz_selectquery($sel_query);
273 455
274 456 if(!empty($result['count']) && ($result['count'] % $loginizer['max_retries']) == 0){
275 -
457 +
276 458 // Has he reached max lockouts ?
277 459 if($result['lockout'] >= $loginizer['max_lockouts']){
278 460 $loginizer['lockout_time'] = $loginizer['lockouts_extend'];
279 461 }
@@ -281,21 +463,24 @@
281 463 // Is he in the lockout time ?
282 464 if($result['time'] >= (time() - $loginizer['lockout_time'])){
283 465 $banlift = ceil((($result['time'] + $loginizer['lockout_time']) - time()) / 60);
284 466
285 - //echo 'Current Time '.date('m/d/Y H:i:s', time()).'<br />';
286 - //echo 'Last attempt '.date('m/d/Y H:i:s', $result['time']).'<br />';
287 - //echo 'Unlock Time '.date('m/d/Y H:i:s', $result['time'] + $loginizer['lockout_time']).'<br />';
467 + //echo 'Current Time '.date('d/M/Y H:i:s P', time()).'<br />';
468 + //echo 'Last attempt '.date('d/M/Y H:i:s P', $result['time']).'<br />';
469 + //echo 'Unlock Time '.date('d/M/Y H:i:s P', $result['time'] + $loginizer['lockout_time']).'<br />';
288 470
289 - $_time = $banlift.' minute(s)';
471 + $_time = $banlift.' '.$loginizer['msg']['minutes_err'];
290 472
291 473 if($banlift > 60){
292 474 $banlift = ceil($banlift / 60);
293 - $_time = $banlift.' hour(s)';
475 + $_time = $banlift.' '.$loginizer['msg']['hours_err'];
294 476 }
295 477
296 - $lz_error['ip_blocked'] = 'You have exceeded maximum login retries<br /> Please try after '.$_time;
478 + $lz_error['ip_blocked'] = $loginizer['msg']['lockout_err'].' '.$_time;
297 479
480 + if(!empty($loginizer['ultimate-member-active']) && class_exists('UM')){
481 + \UM()->form()->add_error('blocked_msg', $lz_error['ip_blocked']);
482 + }
298 483 return false;
299 484 }
300 485 }
301 486
@@ -305,27 +490,36 @@
305 490 function loginizer_is_blacklisted(){
306 491
307 492 global $wpdb, $loginizer, $lz_error;
308 493
309 - $blacklist = $loginizer['blacklist'];
310 -
494 + $blacklist = isset($loginizer['blacklist']) ? $loginizer['blacklist'] : [];
495 +
496 + if(empty($blacklist)){
497 + return false;
498 + }
499 +
500 + $current_ip_inet = inet_ptoi($loginizer['current_ip']);
501 +
311 502 foreach($blacklist as $k => $v){
312 -
503 +
504 + $start_inet = inet_ptoi($v['start']);
505 + $end_inet = inet_ptoi($v['end']);
506 +
313 507 // Is the IP in the blacklist ?
314 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip']) && ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
508 + if($start_inet <= $current_ip_inet && $current_ip_inet <= $end_inet){
315 509 $result = 1;
316 510 break;
317 511 }
318 -
512 +
319 513 // Is it in a wider range ?
320 - if(ip2long($v['start']) >= 0 && ip2long($v['end']) < 0){
514 + if($start_inet >= 0 && $end_inet < 0){
321 515
322 - // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of ip2long,
516 + // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
323 517 // if the current IP is <= than the start of the range, it is within the range
324 518 // OR
325 519 // if the current IP is <= than the end of the range, it is within the range
326 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip'])
327 - || ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
520 + if($start_inet <= $current_ip_inet
521 + || $current_ip_inet <= $end_inet){
328 522 $result = 1;
329 523 break;
330 524 }
331 525
@@ -331,12 +525,12 @@
331 525
332 526 }
333 527
334 528 }
335 -
529 +
336 530 // You are blacklisted
337 531 if(!empty($result)){
338 - $lz_error['ip_blacklisted'] = 'Your IP has been blacklisted';
532 + $lz_error['ip_blacklisted'] = $loginizer['msg']['ip_blacklisted'];
339 533 return true;
340 534 }
341 535
342 536 return false;
@@ -342,93 +536,224 @@
342 536 return false;
343 537
344 538 }
345 539
346 -function loginizer_is_whitelisted(){
540 +// When the login fails, then this is called
541 +// We need to update the database
542 +function loginizer_login_failed($username, $is_2fa = ''){
347 543
348 - global $wpdb, $loginizer, $lz_error;
544 + global $wpdb, $loginizer, $lz_cannot_login;
349 545
350 - $whitelist = $loginizer['whitelist'];
351 -
352 - foreach($whitelist as $k => $v){
546 + // Some plugins are changing the value for username as null so we need to handle it before using it for the INSERT OR UPDATE query
547 + if(empty($username) || is_null($username)){
548 + $username = '';
549 + }
550 +
551 + $fail_type = 'Login';
552 +
553 + if(!empty($is_2fa)){
554 + $fail_type = '2FA';
555 + }
556 +
557 + if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
353 558
354 - // Is the IP in the blacklist ?
355 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip']) && ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
356 - $result = 1;
357 - break;
559 + // The params which comes when social login returns an error, have some characters, which WordPress could not save.
560 + // REQUEST_URI / HTTP_HOST are not always set (WP-CLI, some CGI and XML-RPC setups)
561 + $server_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
562 + $http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
563 +
564 + if(!empty($server_uri) && strpos($server_uri, 'lz_social_provider') !== FALSE){
565 + $request_uri = explode('=', $server_uri);
566 + $server_uri = $request_uri[0];
358 567 }
568 +
569 + // No addslashes() here, $wpdb->prepare() below does the escaping
570 + $url = esc_url((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$http_host.$server_uri);
359 571
360 - // Is it in a wider range ?
361 - if(ip2long($v['start']) >= 0 && ip2long($v['end']) < 0){
362 -
363 - // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of ip2long,
364 - // if the current IP is <= than the start of the range, it is within the range
365 - // OR
366 - // if the current IP is <= than the end of the range, it is within the range
367 - if(ip2long($v['start']) <= ip2long($loginizer['current_ip'])
368 - || ip2long($loginizer['current_ip']) <= ip2long($v['end'])){
369 - $result = 1;
370 - break;
572 + // Must never be 0, we divide by it below
573 + $max_retries = (int) $loginizer['max_retries'] < 1 ? 1 : (int) $loginizer['max_retries'];
574 +
575 + // This way is atomic now, the earlier one were causing race condition.
576 + // NOTE : In the UPDATE part `count` is already the new value, as MySQL / MariaDB
577 + // evaluate the assignments from left to right, so lockout must NOT add 1 again
578 + $upsert = $wpdb->prepare(
579 + "INSERT INTO `".$wpdb->prefix."loginizer_logs`
580 + (username, time, count, ip, lockout, url)
581 + VALUES
582 + (%s, %d, 1, %s, FLOOR(1 / %d), %s)
583 + ON DUPLICATE KEY UPDATE
584 + username = VALUES(username),
585 + time = VALUES(time),
586 + count = count + 1,
587 + lockout = FLOOR(count / %d),
588 + url = VALUES(url)",
589 + $username,
590 + time(),
591 + $loginizer['current_ip'],
592 + $max_retries,
593 + $url,
594 + $max_retries
595 + );
596 + $wpdb->query($upsert);
597 +
598 + // Re-read the persisted row so email/retries-left reflect the actual count
599 + $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
600 + $result = lz_selectquery($sel_query);
601 +
602 + if(empty($result)){
603 + $result = array('count' => 0);
604 + }
605 +
606 + $count = (int) $result['count'];
607 + $lockout = !empty($result['lockout']) ? (int) $result['lockout'] : 0;
608 +
609 + // The lockout goes up only on every max_retries'th failure, which is the
610 + // attempt that actually locks the IP out. On the failures in between there
611 + // is nothing new to report, so we must not email on each one of them
612 + $is_new_lockout = !empty($count) && ($count % $max_retries) == 0;
613 +
614 + // Do we need to email admin ?
615 + if(!empty($loginizer['notify_email']) && !empty($is_new_lockout) && $lockout >= $loginizer['notify_email']){
616 +
617 + $lockout_time = $loginizer['lockout_time'];
618 +
619 + if($lockout >= $loginizer['max_lockouts']){
620 + $lockout_time = $loginizer['lockouts_extend'];
371 621 }
372 -
622 +
623 + $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
624 + $mail = array();
625 + $mail['to'] = $loginizer['notify_email_address'];
626 + $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
627 + $mail['message'] = 'Hi,
628 +
629 +'.(int) $result['count'].' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
630 +'.home_url().'
631 +
632 +Last '.$fail_type.' Attempt : '.date('d/M/Y H:i:s P', time()).'
633 +Last User Attempt : '.$username.'
634 +IP has been blocked until : '.date('d/M/Y H:i:s P', time() + $lockout_time).'
635 +
636 +Regards,
637 +Loginizer';
638 +
639 + @wp_mail($mail['to'], $mail['subject'], $mail['message']);
373 640 }
641 +
642 + loginizer_update_attempt_stats(0);
643 + $loginizer['retries_left'] = $max_retries - ($count % $max_retries);
644 + $loginizer['retries_left'] = $loginizer['retries_left'] == $max_retries ? 0 : $loginizer['retries_left'];
374 645
375 646 }
376 -
377 - // You are whitelisted
378 - if(!empty($result)){
379 - return true;
380 - }
381 -
382 - return false;
383 -
384 647 }
385 648
649 +function loginizer_rsssl_2fa_success($user){
650 + loginizer_login_success('', $user);
651 +}
386 652
387 -// When the login fails, then this is called
388 -// We need to update the database
389 -function loginizer_login_failed($username){
653 +function loginizer_login_success($user_login, $user) {
654 + global $wp_version, $loginizer;
655 +
656 + loginizer_update_attempt_stats(1);
390 657
391 - global $wpdb, $loginizer, $lz_cannot_login;
658 + if(empty($loginizer['login_mail'])){
659 + return;
660 + }
392 661
393 - if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
394 -
395 - $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
396 -
397 - if(!empty($result)){
398 - $lockout = floor((($result['count']+1) / $loginizer['max_retries']));
399 - $sresult = $wpdb->query("UPDATE `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = `count`+1, `lockout` = '".$lockout."' WHERE `ip` = '".$loginizer['current_ip']."';");
400 -
401 - // Do we need to email admin ?
402 - if(!empty($loginizer['notify_email']) && $lockout >= $loginizer['notify_email']){
403 -
404 - $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
405 - $mail = array();
406 - $mail['to'] = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email');
407 - $mail['subject'] = 'Failed Login Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
408 - $mail['message'] = 'Hi,
662 + if(empty($loginizer['login_mail']['enable'])){
663 + return;
664 + }
409 665
410 -'.($result['count']+1).' failed login attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].'
666 + if(!empty($loginizer['login_mail']['disable_whitelist'])){
667 + // Check its whitelist ip
668 + if(loginizer_is_whitelisted()){
669 + return;
670 + }
671 + }
411 672
412 -Last Login Attempt : '.date('d/m/Y H:i:s', time()).'
413 -Last User Attempt : '.$username.'
414 -IP has been blocked until : '.date('d/m/Y H:i:s', time() + $loginizer['lockout_time']).'
673 + if(empty($user_login) && empty($user)){
674 + error_log('Loginizer: No user information to send email');
675 + return;
676 + }
415 677
416 -Regards,
417 -Loginizer';
678 + if(empty($user)){
679 + $user = get_user_by('login', $user_login);
680 + }
418 681
419 - @wp_mail($mail['to'], $mail['subject'], $mail['message']);
420 - }
682 + if(empty($user)){
683 + error_log('Loginizer: Unable to get the user');
684 + return;
685 + }
686 +
687 + if(empty($loginizer['login_mail']['roles']) || !is_array($loginizer['login_mail']['roles'])){
688 + return;
689 + }
690 +
691 + // Check if the user role is enabled for email notification.
692 + if(!array_intersect($user->roles, $loginizer['login_mail']['roles'])){
693 + return;
694 + }
695 +
696 + // current_datetime & wp_timezone_string were introduced in WordPress 5.3
697 + if(!empty($wp_version) && version_compare($wp_version, '5.3', '>') && function_exists('current_datetime')){
698 + $time_zone = wp_timezone_string();
699 +
700 + if(!empty($time_zone) && isset($time_zone[1]) && is_numeric($time_zone[1])){
701 + $time_zone = 'UTC'.$time_zone;
702 + }
703 +
704 + // Setting up data variables.
705 + $date = current_datetime()->format('Y-m-d H:i:s') .' '. $time_zone;
706 + } else {
707 + $date = date("Y-m-d H:i:s", time()) . ' ' . date_default_timezone_get();
708 + }
709 +
710 + $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
711 + $email = $user->data->user_email;
712 +
713 + $vars = array(
714 + 'date' => $date,
715 + 'ip' => esc_html($loginizer['current_ip']),
716 + 'sitename' => $sitename,
717 + 'user_login' => $user_login
718 + );
719 +
720 + $message = lz_lang_vars_name($loginizer['login_mail_body'], $vars);
721 + $subject = lz_lang_vars_name($loginizer['login_mail_subject'], $vars);
722 +
723 + $headers = [];
724 +
725 + // Do we need to send the email as HTML ?
726 + if(!empty($loginizer['login_mail']['html_mail'])){
727 + $headers[] = 'Content-Type: text/html; charset=UTF-8';
728 +
729 + if(!empty($loginizer['login_mail']['body'])){
730 + $message = html_entity_decode($message);
421 731 }else{
422 - $insert = $wpdb->query("INSERT INTO `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = '1', `ip` = '".$loginizer['current_ip']."', `lockout` = '0';");
732 + $message = preg_replace("/\<br\s*\/\>/i", "<br/>", $message);
733 + $message = preg_replace('/(?<!<br\/>)\n/i', "<br/>\n", $message);
423 734 }
735 + }
736 +
737 + // Sending notification
738 + if(empty(wp_mail($email, $subject, $message, $headers))){
739 + error_log(__('There was a problem sending your email.', 'loginizer'));
740 + return;
741 + }
742 +}
743 +
744 +function loginizer_update_attempt_stats($type){
745 +
746 + $stats = get_option('loginizer_login_attempt_stats', []);
747 + $time = strtotime(date('Y-m-d H:00:00'));
424 748
425 - // We need to add one as this is a failed attempt as well
426 - $result['count'] = $result['count'] + 1;
427 - $loginizer['retries_left'] = ($loginizer['max_retries'] - ($result['count'] % $loginizer['max_retries']));
428 - $loginizer['retries_left'] = $loginizer['retries_left'] == $loginizer['max_retries'] ? 0 : $loginizer['retries_left'];
429 -
749 + if(empty($stats[$time][$type])){
750 + $stats[$time][$type] = 0;
430 751 }
752 +
753 + $stats[$time][$type] += 1;
754 +
755 + update_option('loginizer_login_attempt_stats', $stats, false);
431 756 }
432 757
433 758 // Handles the error of the password not being there
434 759 function loginizer_error_handler($errors, $redirect_to){
@@ -433,11 +758,14 @@
433 758 // Handles the error of the password not being there
434 759 function loginizer_error_handler($errors, $redirect_to){
435 760
436 761 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
437 -
762 +
438 763 //echo 'loginizer_error_handler :';print_r($errors->errors);echo '<br>';
439 -
764 + if(is_null($errors) || empty($errors)){
765 + return true;
766 + }
767 +
440 768 // Remove the empty password error
441 769 if(is_wp_error($errors)){
442 770
443 771 $codes = $errors->get_error_codes();
@@ -449,1047 +777,201 @@
449 777 }
450 778
451 779 $errors->remove('invalid_username');
452 780 $errors->remove('incorrect_password');
781 +
782 + // Add the error
783 + if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
784 + $errors->add('invalid_userpass', '<b>ERROR:</b> ' . $loginizer['msg']['inv_userpass']);
785 + }
453 786
787 + // Add the number of retires left as well
788 + if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
789 + $errors->add('retries_left', loginizer_retries_left());
790 + }
791 +
454 792 }
455 793
456 - // Add the error
457 - if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
458 - $errors->add('invalid_userpass', '<b>ERROR:</b> Incorrect Username or Password');
459 - }
460 -
461 - // Add the number of retires left as well
462 - if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
463 - $errors->add('retries_left', loginizer_retries_left());
464 - }
465 -
466 794 return $errors;
467 795
468 796 }
469 797
470 -// Returns a string with the number of retries left
471 -function loginizer_retries_left(){
472 -
798 +// Handles the error of the password not being there
799 +function loginizer_woocommerce_error_handler(){
800 +
473 801 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
474 802
475 - // If we are to show the number of retries left
476 - if(isset($loginizer['retries_left'])){
477 - return '<b>'.$loginizer['retries_left'].'</b> attempt(s) left';
803 + if(function_exists('wc_add_notice')){
804 + wc_add_notice( loginizer_retries_left(), 'error' );
478 805 }
479 -
480 806 }
481 807
482 -function loginizer_reset_retries(){
808 +function loginizer_ultimatemember_error_handler(){
483 809
484 - global $wpdb, $loginizer;
485 -
486 - $deltime = time() - $loginizer['reset_retries'];
487 - $result = $wpdb->query("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= '".$deltime."';");
488 -
489 - update_option('loginizer_last_reset', time());
490 -
810 + if(class_exists('UM')){
811 + \UM()->form()->add_error('remaining_tries', loginizer_retries_left());
812 + }
491 813 }
492 814
493 -add_filter("plugin_action_links_$plugin_loginizer", 'loginizer_plugin_action_links');
494 -
495 -// Add settings link on plugin page
496 -function loginizer_plugin_action_links($links) {
815 +// Handles social login URL
816 +function loginizer_social_login_error_handler($errors = '', $redirect_to = ''){
817 + global $loginizer;
497 818
498 - if(!defined('LOGINIZER_PREMIUM')){
499 - $links[] = '<a href="'.LOGINIZER_PRO_URL.'" style="color:#3db634;" target="_blank">'._x('Upgrade', 'Plugin action link label.', 'loginizer').'</a>';
819 + if(loginizer_is_blacklisted()){
820 + return $errors;
500 821 }
501 822
502 - $settings_link = '<a href="admin.php?page=loginizer">Settings</a>';
503 - array_unshift($links, $settings_link);
504 -
505 - return $links;
506 -}
823 + loginizer_get_social_error();
507 824
508 -add_action('admin_menu', 'loginizer_admin_menu');
825 + if(empty($loginizer['social_errors'])){
826 + return $errors;
827 + }
509 828
510 -// Shows the admin menu of Loginizer
511 -function loginizer_admin_menu() {
512 -
513 - global $wp_version, $loginizer;
514 -
515 - // Add the menu page
516 - add_menu_page(__('Loginizer Dashboard'), __('Loginizer Security'), 'activate_plugins', 'loginizer', 'loginizer_page_dashboard');
517 -
518 - // Dashboard
519 - add_submenu_page('loginizer', __('Loginizer Dashboard'), __('Dashboard'), 'activate_plugins', 'loginizer', 'loginizer_page_dashboard');
520 -
521 - // Brute Force
522 - add_submenu_page('loginizer', __('Loginizer Brute Force Settings'), __('Brute Force'), 'activate_plugins', 'loginizer_brute_force', 'loginizer_page_brute_force');
523 -
524 - if(defined('LOGINIZER_PREMIUM')){
525 -
526 - // PasswordLess
527 - add_submenu_page('loginizer', __('Loginizer PasswordLess Settings'), __('PasswordLess'), 'activate_plugins', 'loginizer_passwordless', 'loginizer_page_passwordless');
528 -
529 - // Two Factor Auth
530 - add_submenu_page('loginizer', __('Loginizer Two Factor Authentication'), __('Two Factor Auth'), 'activate_plugins', 'loginizer_2fa', 'loginizer_page_2fa');
531 -
532 - // reCaptcha
533 - add_submenu_page('loginizer', __('Loginizer reCAPTCHA Settings'), __('reCAPTCHA'), 'activate_plugins', 'loginizer_recaptcha', 'loginizer_page_recaptcha');
534 -
535 - // Security Settings
536 - add_submenu_page('loginizer', __('Loginizer Security Settings'), __('Security Settings'), 'activate_plugins', 'loginizer_security', 'loginizer_page_security');
537 -
538 - }elseif(!defined('LOGINIZER_PREMIUM') && !empty($loginizer['ins_time']) && $loginizer['ins_time'] < (time() - (30*24*3600))){
539 -
540 - // Go Pro link
541 - add_submenu_page('loginizer', __('Loginizer Go Pro'), __('Go Pro'), 'activate_plugins', LOGINIZER_PRO_URL);
542 -
829 + if(is_null($errors) || empty($errors) || !is_wp_error($errors)){
830 + $errors = new WP_Error();
543 831 }
544 -
545 -}
546 832
547 -// The Loginizer Admin Options Page
548 -function loginizer_page_header($title = 'Loginizer'){
549 - /*wp_enqueue_script('common');
550 - wp_enqueue_script('wp-lists');
551 - wp_enqueue_script('postbox');
552 - wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
553 -
554 - echo '
555 -<script>
556 -jQuery(document).ready( function() {
557 - //add_postbox_toggles("loginizer");
558 -});
559 -</script>';*/
833 + foreach($loginizer['social_errors'] as $key => $text){
834 + $errors->add($key, $text);
835 + }
560 836
561 -?>
562 -<style>
563 -.lz-right-ul{
564 - padding-left: 10px !important;
837 + return $errors;
565 838 }
566 839
567 -.lz-right-ul li{
568 - list-style: circle !important;
569 -}
570 -</style>
571 -<?php
840 +// Returns a string with the number of retries left
841 +function loginizer_retries_left(){
572 842
573 - echo '<div style="margin: 10px 20px 0 2px;">
574 -<div class="metabox-holder columns-2">
575 -<div class="postbox-container">
576 -<div id="top-sortables" class="meta-box-sortables ui-sortable">
843 + global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
577 844
578 - <table cellpadding="2" cellspacing="1" width="100%" class="fixed" border="0">
579 - <tr>
580 - <td valign="top"><h3>'.$title.'</h3></td>
581 - <td align="right"><a target="_blank" class="button button-primary" href="https://wordpress.org/support/view/plugin-reviews/loginizer">Review Loginizer</a></td>
582 - </tr>
583 - </table>
584 - <hr />
845 + // If we are to show the number of retries left
846 + if(isset($loginizer['retries_left'])){
847 + $retries_left = apply_filters('loginizer_retries_left_num', $loginizer['retries_left']);
848 +
849 + return '<b>'.esc_html($retries_left).'</b> '.$loginizer['msg']['attempts_left'];
850 + }
585 851
586 - <!--Main Table-->
587 - <table cellpadding="8" cellspacing="1" width="100%" class="fixed">
588 - <tr>
589 - <td valign="top">';
590 -
591 852 }
592 853
593 -// The Loginizer Theme footer
594 -function loginizer_page_footer(){
595 -
596 - echo '</td>
597 - <td width="200" valign="top" id="loginizer-right-bar">';
598 -
599 - if(!defined('LOGINIZER_PREMIUM')){
600 -
601 - echo '
602 - <div class="postbox" style="min-width:0px !important;">
603 - <h2 class="hndle ui-sortable-handle">
604 - <span>Premium Version</span>
605 - </h2>
606 - <div class="inside">
607 - <i>Upgrade to the premium version and get the following features </i>:<br>
608 - <ul class="lz-right-ul">
609 - <li>PasswordLess Login</li>
610 - <li>Two Factor Auth - Email</li>
611 - <li>Two Factor Auth - App</li>
612 - <li>Login Challenge Question</li>
613 - <li>reCAPTCHA</li>
614 - <li>Rename Login Page</li>
615 - <li>Disable XML-RPC</li>
616 - <li>And many more ...</li>
617 - </ul>
618 - <center><a class="button button-primary" href="https://loginizer.com/members/cart.php">Upgrade</a></center>
619 - </div>
620 - </div>';
621 -
622 - }else{
623 -
624 - echo '
625 - <div class="postbox" style="min-width:0px !important;">
626 - <h2 class="hndle ui-sortable-handle">
627 - <span>Recommedations</span>
628 - </h2>
629 - <div class="inside">
630 - <i>We recommed that you enable atleast one of the following security features</i>:<br>
631 - <ul class="lz-right-ul">
632 - <li>Rename Login Page</li>
633 - <li>Login Challenge Question</li>
634 - <li>reCAPTCHA</li>
635 - <li>Two Factor Auth - Email</li>
636 - <li>Two Factor Auth - App</li>
637 - </ul>
638 - </div>
639 - </div>';
640 - }
641 -
642 - echo '</td>
643 - </tr>
644 - </table>
645 - <br />
646 - <div style="width:45%;background:#FFF;padding:15px; margin:auto">
647 - <b>Let your friends know that you have secured your website :</b>
648 - <form method="get" action="http://twitter.com/intent/tweet" id="tweet" onsubmit="return dotweet(this);">
649 - <textarea name="text" cols="45" row="3" style="resize:none;">I just secured my @WordPress site against #bruteforce using @loginizer</textarea>
650 - &nbsp; &nbsp; <input type="submit" value="Tweet!" class="button button-primary" onsubmit="return false;" id="twitter-btn" style="margin-top:20px;"/>
651 - </form>
652 -
653 - </div>
654 - <br />
655 -
656 - <script>
657 - function dotweet(ele){
658 - window.open(jQuery("#"+ele.id).attr("action")+"?"+jQuery("#"+ele.id).serialize(), "_blank", "scrollbars=no, menubar=no, height=400, width=500, resizable=yes, toolbar=no, status=no");
659 - return false;
660 - }
661 - </script>
662 -
663 - <hr />
664 - <a href="http://loginizer.com" target="_blank">Loginizer</a> v'.LOGINIZER_VERSION.'. You can report any bugs <a href="http://wordpress.org/support/plugin/loginizer" target="_blank">here</a>.
854 +function loginizer_reset_retries(){
665 855
666 -</div>
667 -</div>
668 -</div>
669 -</div>';
856 + global $wpdb, $loginizer;
670 857
671 -}
858 + $deltime = time() - $loginizer['reset_retries'];
672 859
673 -// The Loginizer Admin Options Page
674 -function loginizer_page_dashboard(){
675 -
676 - global $loginizer, $lz_error, $lz_env;
677 -
678 - // Is there a license key ?
679 - if(isset($_POST['save_lz'])){
680 -
681 - $license = lz_optpost('lz_license');
682 -
683 - // Check if its a valid license
684 - if(empty($license)){
685 - $lz_error['lic_invalid'] = __('The license key was not submitted', 'loginizer');
686 - return loginizer_page_dashboard_T();
687 - }
688 -
689 - $resp = wp_remote_get(LOGINIZER_API.'license.php?license='.$license);
690 -
691 - if(is_array($resp)){
692 - $json = json_decode($resp['body'], true);
693 - //print_r($json);
694 - }
695 -
696 - // Save the License
697 - if(empty($json)){
698 -
699 - $lz_error['lic_invalid'] = __('The license key is invalid', 'loginizer');
700 - return loginizer_page_dashboard_T();
701 -
702 - }else{
703 -
704 - update_option('loginizer_license', $json);
705 -
706 - // Mark as saved
707 - $GLOBALS['lz_saved'] = true;
708 - }
709 -
710 - }
711 -
712 - loginizer_page_dashboard_T();
713 -
714 -}
860 + $del_query = $wpdb->prepare("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= %d", $deltime);
861 + $result = $wpdb->query($del_query);
715 862
716 -// The Loginizer Admin Options Page - THEME
717 -function loginizer_page_dashboard_T(){
718 -
719 - global $loginizer, $lz_error, $lz_env;
863 + update_option('loginizer_last_reset', time());
720 864
721 - loginizer_page_header('Loginizer Dashboard');
722 -?>
723 -<style>
724 -.welcome-panel{
725 - margin: 0px;
726 - padding: 10px;
727 865 }
728 866
729 -input[type="text"], textarea, select {
730 - width: 70%;
731 -}
867 +function loginizer_load_translation_vars(){
868 + global $loginizer;
869 +
870 + $loginizer['login_mail_default_sub'] = __('Login Successful at $sitename', 'loginizer');
871 + $loginizer['login_mail_default_msg'] = __('Hello $user_login,
732 872
733 -.form-table label{
734 - font-weight:bold;
735 -}
873 +Your account was recently logged in from the IP : $ip
874 +Time : $date
875 +If it was not you who logged in then please report this to us immediately.
736 876
737 -.exp{
738 - font-size:12px;
739 -}
740 -</style>
741 -
742 - <?php
743 - echo '<script src="http://api.loginizer.com/'.(defined('LOGINIZER_PREMIUM') ? 'news_security.js' : 'news.js').'"></script><br>';
877 +Regards,
878 +$sitename','loginizer');
744 879
745 - // Saved ?
746 - if(!empty($GLOBALS['lz_saved'])){
747 - echo '<div id="message" class="updated"><p>'. __('The settings were saved successfully', 'loginizer'). '</p></div><br />';
880 + if(empty($loginizer['login_mail_subject'])){
881 + $loginizer['login_mail_subject'] = $loginizer['login_mail_default_sub'];
748 882 }
749 883
750 - // Any errors ?
751 - if(!empty($lz_error)){
752 - lz_report_error($lz_error);echo '<br />';
884 + if(empty($loginizer['login_mail_body'])){
885 + $loginizer['login_mail_body'] = $loginizer['login_mail_default_msg'];
753 886 }
754 887
755 - ?>
888 + // Default messages
889 + $loginizer['d_msg']['inv_userpass'] = __('Incorrect Username or Password', 'loginizer');
890 + $loginizer['d_msg']['ip_blacklisted'] = __('Your IP has been blacklisted', 'loginizer');
891 + $loginizer['d_msg']['attempts_left'] = __('attempt(s) left', 'loginizer');
892 + $loginizer['d_msg']['lockout_err'] = __('You have exceeded maximum login retries<br /> Please try after', 'loginizer');
893 + $loginizer['d_msg']['minutes_err'] = __('minute(s)', 'loginizer');
894 + $loginizer['d_msg']['hours_err'] = __('hour(s)', 'loginizer');
756 895
757 - <div class="postbox">
896 + // Message Strings
897 + $loginizer['msg'] = get_option('loginizer_msg', []);
758 898
759 - <button class="handlediv button-link" aria-expanded="true" type="button">
760 - <span class="screen-reader-text">Toggle panel: Getting Started</span>
761 - <span class="toggle-indicator" aria-hidden="true"></span>
762 - </button>
763 -
764 - <h2 class="hndle ui-sortable-handle">
765 - <span><?php echo __('Getting Started', 'loginizer'); ?></span>
766 - </h2>
767 -
768 - <div class="inside">
769 -
770 - <form action="" method="post" enctype="multipart/form-data">
771 - <?php wp_nonce_field('loginizer-options'); ?>
772 - <table class="form-table">
773 - <tr>
774 - <td scope="row" valign="top" colspan="2" style="line-height:150%">
775 - <i>Welcome to Loginizer Security. By default the <b>Brute Force Protection</b> is immediately enabled. You should start by going over the default settings and tweaking them as per your needs.</i>
776 - <?php
777 - if(defined('LOGINIZER_PREMIUM')){
778 - echo '<br><i>In the Premium version of Loginizer you have many more features. We recommend you enable features like <b>reCAPTCHA, Two Factor Auth or Email based PasswordLess</b> login. These features will improve your websites security.</i>';
779 - }
780 - ?>
781 - </td>
782 - </tr>
783 - </table>
784 - </form>
785 -
786 - </div>
787 - </div>
899 + foreach($loginizer['d_msg'] as $lk => $lv){
900 + if(empty($loginizer['msg'][$lk])){
901 + $loginizer['msg'][$lk] = $loginizer['d_msg'][$lk];
902 + }
903 + }
788 904
789 - <div class="postbox">
905 + $loginizer['2fa_d_msg']['otp_app'] = __('Please enter the OTP as seen in your App', 'loginizer');
906 + $loginizer['2fa_d_msg']['otp_email'] = __('Please enter the OTP emailed to you', 'loginizer');
907 + $loginizer['2fa_d_msg']['otp_field'] = __('One Time Password', 'loginizer');
908 + $loginizer['2fa_d_msg']['otp_question'] = __('Please answer your security question', 'loginizer');
909 + $loginizer['2fa_d_msg']['otp_answer'] = __('Your Answer', 'loginizer');
790 910
791 - <button class="handlediv button-link" aria-expanded="true" type="button">
792 - <span class="screen-reader-text">Toggle panel: System Information</span>
793 - <span class="toggle-indicator" aria-hidden="true"></span>
794 - </button>
795 -
796 - <h2 class="hndle ui-sortable-handle">
797 - <span><?php echo __('System Information', 'loginizer'); ?></span>
798 - </h2>
799 -
800 - <div class="inside">
801 -
802 - <form action="" method="post" enctype="multipart/form-data">
803 - <?php wp_nonce_field('loginizer-options'); ?>
804 - <table class="wp-list-table fixed striped users" cellspacing="1" border="0" width="95%" cellpadding="10" align="center">
805 - <?php
806 - echo '
807 - <tr>
808 - <th align="left" width="25%">'.__('Loginizer Version', 'loginizer').'</th>
809 - <td>'.LOGINIZER_VERSION.(defined('LOGINIZER_PREMIUM') ? ' (Security PRO Version)' : '').'</td>
810 - </tr>';
811 -
812 - if(defined('LOGINIZER_PREMIUM')){
813 - echo '
814 - <tr>
815 - <th align="left" valign="top">'.__('Loginizer License', 'loginizer').'</th>
816 - <td align="left">
817 - '.(empty($loginizer['license']) ? '<span style="color:red">Unlicensed</span> &nbsp; &nbsp;' : '').'
818 - <input type="text" name="lz_license" value="'.(empty($loginizer['license']) ? '' : $loginizer['license']['license']).'" size="30" placeholder="e.g. WXCSE-SFJJX-XXXXX-AAAAA-BBBBB" style="width:300px;" /> &nbsp;
819 - <input name="save_lz" class="button button-primary" value="Update License" type="submit" />';
820 -
821 - if(!empty($loginizer['license'])){
822 -
823 - $expires = $loginizer['license']['expires'];
824 - $expires = substr($expires, 0, 4).'/'.substr($expires, 4, 2).'/'.substr($expires, 6);
825 -
826 - echo '<div style="margin-top:10px;">License Active : '.(empty($loginizer['license']['active']) ? '<span style="color:red">No</span>' : 'Yes').' &nbsp; &nbsp; &nbsp;
827 - License Expires : '.($loginizer['license']['expires'] <= date('Ymd') ? '<span style="color:red">'.$expires.'</span>' : $expires).'
828 - </div>';
829 - }
830 -
831 -
832 - echo
833 - '</td>
834 - </tr>';
835 - }
836 -
837 - echo '<tr>
838 - <th align="left">'.__('URL', 'loginizer').'</th>
839 - <td>'.get_site_url().'</td>
840 - </tr>
841 - <tr>
842 - <th align="left">'.__('Path', 'loginizer').'</th>
843 - <td>'.ABSPATH.'</td>
844 - </tr>
845 - <tr>
846 - <th align="left">'.__('Server\'s IP Address', 'loginizer').'</th>
847 - <td>'.$_SERVER['SERVER_ADDR'].'</td>
848 - </tr>
849 - <tr>
850 - <th align="left">'.__('Your IP Address', 'loginizer').'</th>
851 - <td>'.$_SERVER['REMOTE_ADDR'].'</td>
852 - </tr>
853 - <tr>
854 - <th align="left">'.__('wp-config.php is writable', 'loginizer').'</th>
855 - <td>'.(is_writable(ABSPATH.'/wp-config.php') ? '<span style="color:red">Yes</span>' : '<span style="color:green">No</span>').'</td>
856 - </tr>';
857 -
858 - if(file_exists(ABSPATH.'/.htaccess')){
859 - echo '
860 - <tr>
861 - <th align="left">'.__('.htaccess is writable', 'loginizer').'</th>
862 - <td>'.(is_writable(ABSPATH.'/.htaccess') ? '<span style="color:red">Yes</span>' : '<span style="color:green">No</span>').'</td>
863 - </tr>';
864 -
865 - }
866 -
867 - ?>
868 - </table>
869 - </form>
870 -
871 - </div>
872 - </div>
911 + // Message Strings
912 + $loginizer['2fa_msg'] = get_option('loginizer_2fa_msg', []);
873 913
874 - <div id="" class="postbox">
914 + foreach($loginizer['2fa_d_msg'] as $lk => $lv){
915 + if(empty($loginizer['2fa_msg'][$lk])){
916 + $loginizer['2fa_msg'][$lk] = $loginizer['2fa_d_msg'][$lk];
917 + }
918 + }
875 919
876 - <button class="handlediv button-link" aria-expanded="true" type="button">
877 - <span class="screen-reader-text">Toggle panel: File Permissions</span>
878 - <span class="toggle-indicator" aria-hidden="true"></span>
879 - </button>
880 -
881 - <h2 class="hndle ui-sortable-handle">
882 - <span><?php echo __('File Permissions', 'loginizer'); ?></span>
883 - </h2>
884 -
885 - <div class="inside">
886 -
887 - <form action="" method="post" enctype="multipart/form-data">
888 - <?php wp_nonce_field('loginizer-options'); ?>
889 - <table class="wp-list-table fixed striped users" border="0" width="95%" cellpadding="10" align="center">
890 - <?php
891 -
892 - echo '
893 - <tr>
894 - <th style="background:#EFEFEF;">'.__('Relative Path', 'loginizer').'</th>
895 - <th style="width:10%; background:#EFEFEF;">'.__('Suggested', 'loginizer').'</th>
896 - <th style="width:10%; background:#EFEFEF;">'.__('Actual', 'loginizer').'</th>
897 - </tr>';
898 -
899 - $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>
920 +}
934 921
935 -<?php
936 -
937 - loginizer_page_footer();
938 -
922 +function loginizer_social_login_load(){
923 + include_once LOGINIZER_DIR . '/main/social-login.php';
939 924 }
940 925
941 -// The Loginizer Admin Options Page
942 -function loginizer_page_brute_force(){
926 +// Checks if softaculous is installed on the server.
927 +function loginizer_check_softaculous(){
943 928
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.');
929 + // Checking if we have Softaculous installed?
930 + if(!preg_match('/^\/home(?:\d+)?\/.*\//U', ABSPATH, $matches)){
931 + return false;
948 932 }
949 933
950 - /* Make sure post was from this page */
951 - if(count($_POST) > 0){
952 - check_admin_referer('loginizer-options');
934 + if(empty($matches) || empty($matches[0])){
935 + return false;
953 936 }
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 -
937 +
938 + $softaculous_path = $matches[0] . '.softaculous/installations.php';
939 + if(!file_exists($softaculous_path)){
940 + return false;
1003 941 }
1004 942
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 -
943 + // Checking if users has changed the branding of Softaculous.
944 + $universal_file = '';
945 + // Plesk, ISPManager, ISPConfig, InterWorx, H-Sphere, CentOS Web Panel, Softaculous Remote and Softaculous Enterprise
946 + if(file_exists('/usr/local/softaculous/enduser/universal.php')){
947 + $universal_file = '/usr/local/softaculous/enduser/universal.php';
948 + }else if(file_exists('/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php')){
949 + $universal_file = '/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php';
950 + }else if(file_exists('/usr/local/directadmin/plugins/softaculous/enduser/universal.php')){
951 + $universal_file = '/usr/local/directadmin/plugins/softaculous/enduser/universal.php';
952 + }else if(file_exists('/usr/local/vesta/softaculous/enduser/universal.php')){
953 + $universal_file = '/usr/local/vesta/softaculous/enduser/universal.php';
1019 954 }
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 -
955 +
956 + if(empty($universal_file)){
957 + return false;
1035 958 }
1036 -
1037 - if(isset($_POST['blacklist_iprange'])){
1038 959
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 -
960 + $universal = file_get_contents($universal_file);
961 +
962 + if(empty($universal)){
963 + return false;
1122 964 }
1123 -
1124 - if(isset($_POST['whitelist_iprange'])){
1125 965
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 - }
966 + // Checking if Softaculous is being whitelabeled
967 + if(preg_match('/\$globals\[["\']sn["\']\]\s.?=\s.?["\']Softaculous["\']/', $universal)){
968 + update_option('loginizer_softwp_upgrade', time());
1207 969 }
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 970
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 -
971 + return false;
1489 972 }
1490 973
1491 -
1492 974 // Sorry to see you going
1493 975 register_uninstall_hook(LOGINIZER_FILE, 'loginizer_deactivation');
1494 976
1495 977 function loginizer_deactivation(){
@@ -1507,7 +989,22 @@
1507 989 delete_option('loginizer_options');
1508 990 delete_option('loginizer_last_reset');
1509 991 delete_option('loginizer_whitelist');
1510 992 delete_option('loginizer_blacklist');
993 + delete_option('loginizer_msg');
994 + delete_option('loginizer_2fa_msg');
995 + delete_option('loginizer_2fa_email_template');
996 + delete_option('loginizer_security');
997 + delete_option('loginizer_wp_admin');
998 + delete_option('loginizer_csrf_promo_time');
999 + delete_option('loginizer_backuply_promo_time');
1000 + delete_option('loginizer_promo_time');
1001 + delete_option('loginizer_ins_time');
1002 + delete_option('loginizer_2fa_whitelist');
1003 + delete_option('loginizer_checksums_last_run');
1004 + delete_option('loginizer_checksums_diff');
1005 + delete_option('loginizer_ip_method');
1006 + delete_option('loginizer_2fa_custom_redirect');
1007 + delete_option('external_updates-loginizer-security');
1008 + delete_option('loginizer_login_attempt_stats');
1511 1009
1512 -}
1513 -
1010 +}