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