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