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