PluginProbe
Loginizer / 1.9.7
Loginizer v1.9.7
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
loginizer / init.php

init.php in Loginizer 1.9.7, at init.php

1,034 lines 31.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if(!function_exists('add_action')){
4 echo 'You are not allowed to access this page directly.';
5 exit;
6 }
7
8 define('LOGINIZER_VERSION', '1.9.7');
9 define('LOGINIZER_DIR', dirname(LOGINIZER_FILE));
10 define('LOGINIZER_URL', plugins_url('', LOGINIZER_FILE));
11 define('LOGINIZER_PRO_URL', 'https://loginizer.com/features#compare');
12 define('LOGINIZER_PRICING_URL', 'https://loginizer.com/pricing');
13 define('LOGINIZER_DOCS', 'https://loginizer.com/docs/');
14
15 include_once(LOGINIZER_DIR.'/functions.php');
16
17 // Ok so we are now ready to go
18 register_activation_hook(LOGINIZER_FILE, 'loginizer_activation');
19
20 // Is called when the ADMIN enables the plugin
21 function loginizer_activation(){
22
23 global $wpdb;
24
25 $sql = array();
26
27 $sql[] = "DROP TABLE IF EXISTS `".$wpdb->prefix."loginizer_logs`";
28
29 $sql[] = "CREATE TABLE `".$wpdb->prefix."loginizer_logs` (
30 `username` varchar(255) NOT NULL DEFAULT '',
31 `time` int(10) NOT NULL DEFAULT '0',
32 `count` int(10) NOT NULL DEFAULT '0',
33 `lockout` int(10) NOT NULL DEFAULT '0',
34 `ip` varchar(255) NOT NULL DEFAULT '',
35 `url` varchar(255) NOT NULL DEFAULT '',
36 UNIQUE KEY `ip` (`ip`)
37 ) DEFAULT CHARSET=utf8;";
38
39 foreach($sql as $sk => $sv){
40 $wpdb->query($sv);
41 }
42
43 add_option('loginizer_version', LOGINIZER_VERSION);
44 add_option('loginizer_options', array());
45 add_option('loginizer_last_reset', 0);
46 add_option('loginizer_whitelist', array());
47 add_option('loginizer_blacklist', array());
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 }
55 }
56
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 */
64 function loginizer_update_check(){
65
66 global $wpdb;
67
68 $sql = array();
69 $current_version = get_option('loginizer_version');
70
71 // It must be the 1.0 pre stuff
72 if(empty($current_version)){
73 $current_version = get_option('lz_version');
74 }
75
76 $version = (int) str_replace('.', '', $current_version);
77
78 // No update required
79 if($current_version == LOGINIZER_VERSION){
80 return true;
81 }
82
83 // Is it first run ?
84 if(empty($current_version)){
85
86 // Reinstall
87 loginizer_activation();
88
89 // Trick the following if conditions to not run
90 $version = (int) str_replace('.', '', LOGINIZER_VERSION);
91
92 }
93
94 // Is it less than 1.0.1 ?
95 if($version < 101){
96
97 // TODO : GET the existing settings
98
99 // Get the existing settings
100 $lz_failed_logs = lz_selectquery("SELECT * FROM `".$wpdb->prefix."lz_failed_logs`;", 1);
101 $lz_options = lz_selectquery("SELECT * FROM `".$wpdb->prefix."lz_options`;", 1);
102 $lz_iprange = lz_selectquery("SELECT * FROM `".$wpdb->prefix."lz_iprange`;", 1);
103
104 // Delete the three tables
105 $sql = array();
106 $sql[] = "DROP TABLE IF EXISTS ".$wpdb->prefix."lz_failed_logs;";
107 $sql[] = "DROP TABLE IF EXISTS ".$wpdb->prefix."lz_options;";
108 $sql[] = "DROP TABLE IF EXISTS ".$wpdb->prefix."lz_iprange;";
109
110 foreach($sql as $sk => $sv){
111 $wpdb->query($sv);
112 }
113
114 // Delete option
115 delete_option('lz_version');
116
117 // Reinstall
118 loginizer_activation();
119
120 // TODO : Save the existing settings
121
122 // Update the existing failed logs to new table
123 if(is_array($lz_failed_logs)){
124 foreach($lz_failed_logs as $fk => $fv){
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);
134 }
135 }
136
137 // Update the existing options to new structure
138 if(is_array($lz_options)){
139 foreach($lz_options as $ok => $ov){
140
141 if($ov['option_name'] == 'lz_last_reset'){
142 update_option('loginizer_last_reset', $ov['option_value']);
143 continue;
144 }
145
146 $old_option[str_replace('lz_', '', $ov['option_name'])] = $ov['option_value'];
147 }
148 // Save the options
149 update_option('loginizer_options', $old_option);
150 }
151
152 // Update the existing iprange to new structure
153 if(is_array($lz_iprange)){
154
155 $old_blacklist = array();
156 $old_whitelist = array();
157 $bid = 1;
158 $wid = 1;
159 foreach($lz_iprange as $ik => $iv){
160
161 if(!empty($iv['blacklist'])){
162 $old_blacklist[$bid] = array();
163 $old_blacklist[$bid]['start'] = long2ip($iv['start']);
164 $old_blacklist[$bid]['end'] = long2ip($iv['end']);
165 $old_blacklist[$bid]['time'] = strtotime($iv['date']);
166 $bid = $bid + 1;
167 }
168
169 if(!empty($iv['whitelist'])){
170 $old_whitelist[$wid] = array();
171 $old_whitelist[$wid]['start'] = long2ip($iv['start']);
172 $old_whitelist[$wid]['end'] = long2ip($iv['end']);
173 $old_whitelist[$wid]['time'] = strtotime($iv['date']);
174 $wid = $wid + 1;
175 }
176 }
177
178 if(!empty($old_blacklist)) update_option('loginizer_blacklist', $old_blacklist);
179 if(!empty($old_whitelist)) update_option('loginizer_whitelist', $old_whitelist);
180 }
181
182 }
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 // Save the new Version
192 update_option('loginizer_version', LOGINIZER_VERSION);
193
194 // TODO:: REMOVE THIS AFTER MARCH 2025
195 $softwp_upgrade = get_option('loginizer_softwp_upgrade', 0);
196 if(!defined('SITEPAD') && empty($softwp_upgrade)){
197 loginizer_check_softaculous();
198 }
199
200 // In Sitepad Math Captcha is enabled by default
201 if(defined('SITEPAD') && get_option('loginizer_captcha') === false){
202 $option['captcha_no_google'] = 1;
203 add_option('loginizer_captcha', $option);
204 }
205
206 }
207
208 // Add the action to load the plugin
209 add_action('plugins_loaded', 'loginizer_load_plugin');
210
211 // The function that will be called when the plugin is loaded
212 function loginizer_load_plugin(){
213
214 global $loginizer;
215
216 // Check if the installed version is outdated
217 loginizer_update_check();
218
219 // Set the array
220 if(empty($loginizer)){
221 $loginizer = array();
222 }
223
224 $loginizer['prefix'] = !defined('SITEPAD') ? 'Loginizer ' : 'SitePad ';
225 $loginizer['app'] = !defined('SITEPAD') ? 'WordPress' : 'SitePad';
226 $loginizer['login_basename'] = !defined('SITEPAD') ? 'wp-login.php' : 'login.php';
227 $loginizer['wp-includes'] = !defined('SITEPAD') ? 'wp-includes' : 'site-inc';
228
229 // The IP Method to use
230 $loginizer['ip_method'] = get_option('loginizer_ip_method');
231 if($loginizer['ip_method'] == 3){
232 $loginizer['custom_ip_method'] = get_option('loginizer_custom_ip_method');
233 }
234
235 // Load settings
236 $options = get_option('loginizer_options');
237 $loginizer['max_retries'] = empty($options['max_retries']) ? 3 : $options['max_retries'];
238 $loginizer['lockout_time'] = empty($options['lockout_time']) ? 900 : $options['lockout_time']; // 15 minutes
239 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
240 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
241 $loginizer['reset_retries'] = empty($options['reset_retries']) ? 86400 : $options['reset_retries']; // 24 hours
242 $loginizer['notify_email'] = empty($options['notify_email']) ? 0 : $options['notify_email'];
243 $loginizer['notify_email_address'] = lz_is_multisite() ? get_site_option('admin_email') : get_option('admin_email');
244 $loginizer['trusted_ips'] = empty($options['trusted_ips']) ? false : true;
245 $loginizer['blocked_screen'] = empty($options['blocked_screen']) ? false : true;
246 $loginizer['social_settings'] = get_option('loginizer_social_settings', []);
247
248 if(!empty($options['notify_email_address'])){
249 $loginizer['notify_email_address'] = $options['notify_email_address'];
250 $loginizer['custom_notify_email'] = 1;
251 }
252
253 // Login Success Email Notification.
254 $loginizer['login_mail'] = get_option('loginizer_login_mail', []);
255 add_action('init', 'loginizer_load_translation_vars', 0);
256
257 $loginizer['login_mail_subject'] = empty($loginizer['login_mail']['subject']) ? '' : $loginizer['login_mail']['subject'];
258 $loginizer['login_mail_body'] = empty($loginizer['login_mail']['body']) ? '' : $loginizer['login_mail']['body'];
259
260 // Load the blacklist and whitelist
261 $loginizer['blacklist'] = get_option('loginizer_blacklist', []);
262 $loginizer['whitelist'] = get_option('loginizer_whitelist', []);
263 $loginizer['2fa_whitelist'] = get_option('loginizer_2fa_whitelist');
264
265 // It should not be false
266 if(empty($loginizer['2fa_whitelist'])){
267 $loginizer['2fa_whitelist'] = array();
268 }
269
270 // When was the database cleared last time
271 $loginizer['last_reset'] = get_option('loginizer_last_reset');
272
273 //print_r($loginizer);
274
275 // Clear retries
276 if((time() - $loginizer['last_reset']) >= $loginizer['reset_retries']){
277 loginizer_reset_retries();
278 }
279
280 $ins_time = get_option('loginizer_ins_time');
281 if(empty($ins_time)){
282 $ins_time = time();
283 update_option('loginizer_ins_time', $ins_time);
284 }
285 $loginizer['ins_time'] = $ins_time;
286
287 // Set the current IP
288 $loginizer['current_ip'] = lz_getip();
289
290 // Is Brute Force Disabled ?
291 $loginizer['disable_brute'] = get_option('loginizer_disable_brute');
292
293 // Filters and actions
294 if(empty($loginizer['disable_brute'])){
295
296 // Use this to verify before WP tries to login
297 // Is always called and is the first function to be called
298 //add_action('wp_authenticate', 'loginizer_wp_authenticate', 10, 2);// Not called by XML-RPC
299 add_filter('authenticate', 'loginizer_wp_authenticate', 10001, 3);// This one is called by xmlrpc as well as GUI
300
301 // Is called when a login attempt fails
302 // Hence Update our records that the login failed
303 add_action('wp_login_failed', 'loginizer_login_failed');
304
305 // Is called before displaying the error message so that we dont show that the username is wrong or the password
306 // Update Error message
307 add_action('wp_login_errors', 'loginizer_error_handler', 10001, 2);
308 add_action('woocommerce_login_failed', 'loginizer_woocommerce_error_handler', 10001);
309 add_action('wp_login', 'loginizer_login_success', 10, 2);
310
311 if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
312 add_filter('wp_login_errors', 'loginizer_social_login_error_handler', 10000, 2);
313 }
314 }
315
316 // Social Login Form Actions
317 if(!empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
318 if(!empty($loginizer['social_settings']['login']['login_form'])){
319 add_action('login_form', 'loginizer_social_btn_login');
320 }
321 }
322
323 if((function_exists('wp_doing_ajax') && wp_doing_ajax()) || (defined( 'DOING_AJAX' ) && DOING_AJAX)){
324 include_once LOGINIZER_DIR . '/main/ajax.php';
325 }
326
327 if(is_admin()){
328 include_once LOGINIZER_DIR . '/main/admin.php';
329 }
330
331 // ----------------
332 // PRO INIT END
333 // ----------------
334
335 // Is the premium features there ?
336 if(!defined('LOGINIZER_PREMIUM')){
337
338 if(current_user_can('activate_plugins')){
339 // The promo time
340 $loginizer['promo_time'] = get_option('loginizer_promo_time');
341 if(empty($loginizer['promo_time'])){
342 $loginizer['promo_time'] = time();
343 update_option('loginizer_promo_time', $loginizer['promo_time']);
344 }
345
346 // Are we to show the loginizer promo
347 if(!empty($loginizer['promo_time']) && $loginizer['promo_time'] > 0 && $loginizer['promo_time'] < (time() - (30*24*3600))){
348
349 add_action('admin_notices', 'loginizer_promo');
350
351 }
352
353 if(!empty($loginizer['csrf_promo']) && $loginizer['csrf_promo'] > 0 && $loginizer['csrf_promo'] < (time() - 86400)){
354
355 add_action('admin_notices', 'loginizer_csrf_promo');
356
357 }
358
359 // Are we to disable the promo
360 if(isset($_GET['loginizer_promo']) && (int)$_GET['loginizer_promo'] == 0){
361 update_option('loginizer_promo_time', (0 - time()) );
362 die('DONE');
363 }
364
365 $loginizer['backuply_promo'] = get_option('loginizer_backuply_promo_time');
366
367 if(empty($loginizer['backuply_promo'])){
368 $loginizer['backuply_promo'] = abs($loginizer['promo_time']);
369 update_option('loginizer_backuply_promo_time', $loginizer['backuply_promo']);
370 }
371
372 // Setting CSRF Promo time
373 $loginizer['csrf_promo'] = get_option('loginizer_csrf_promo_time');
374
375 if(empty($loginizer['csrf_promo'])){
376 $loginizer['csrf_promo'] = abs($loginizer['promo_time']);
377 update_option('loginizer_csrf_promo_time', $loginizer['csrf_promo']);
378 }
379 }
380 }
381
382 // Secuity checks for social login.
383 if(!empty($_GET['lz_social_provider']) && loginizer_can_login()){
384 include_once LOGINIZER_DIR . '/main/social-login.php';
385 return;
386 }
387 }
388
389 // Should return NULL if everything is fine
390 function loginizer_wp_authenticate($user, $username, $password){
391
392 global $loginizer, $lz_error, $lz_cannot_login, $lz_user_pass;
393
394 if(!empty($username) && !empty($password)){
395 $lz_user_pass = 1;
396 }
397
398 // Are you whitelisted ?
399 if(loginizer_is_whitelisted()){
400 $loginizer['ip_is_whitelisted'] = 1;
401 return $user;
402
403 } else if (!empty($loginizer['trusted_ips'])){
404 $lz_cannot_login = 1;
405
406 // This is used by WP Activity Log
407 apply_filters( 'wp_login_blocked', $username );
408
409 // Shows a blocked screen
410 if(!empty($loginizer['blocked_screen'])){
411 $lz_error['trusted_ip'] = __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer');
412 loginizer_blocked_page($lz_error);
413 }
414
415 return new WP_Error('ip_blacklisted', __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer'));
416 }
417
418 // Are you blacklisted ?
419 if(loginizer_is_blacklisted()){
420 $lz_cannot_login = 1;
421
422 // This is used by WP Activity Log
423 apply_filters( 'wp_login_blocked', $username );
424
425 // Shows a blocked screen
426 if(!empty($loginizer['blocked_screen'])){
427 loginizer_blocked_page($lz_error);
428 }
429
430 return new WP_Error('ip_blacklisted', implode('', $lz_error), 'loginizer');
431 }
432
433 // Is the username blacklisted ?
434 if(function_exists('loginizer_user_blacklisted')){
435 if(loginizer_user_blacklisted($username)){
436 $lz_cannot_login = 1;
437
438 // This is used by WP Activity Log
439 apply_filters( 'wp_login_blocked', $username );
440
441 return new WP_Error('user_blacklisted', implode('', $lz_error), 'loginizer');
442 }
443 }
444
445 if(loginizer_can_login()){
446 return $user;
447 }
448
449 $lz_cannot_login = 1;
450
451 // This is used by WP Activity Log
452 apply_filters( 'wp_login_blocked', $username );
453
454 // Shows a blocked screen
455 if(!empty($loginizer['blocked_screen'])){
456 loginizer_blocked_page($lz_error);
457 }
458
459 return new WP_Error('ip_blocked', implode('', $lz_error), 'loginizer');
460
461 }
462
463 function loginizer_can_login(){
464
465 global $wpdb, $loginizer, $lz_error;
466
467 // Get the logs
468 $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
469 $result = lz_selectquery($sel_query);
470
471 if(!empty($result['count']) && ($result['count'] % $loginizer['max_retries']) == 0){
472
473 // Has he reached max lockouts ?
474 if($result['lockout'] >= $loginizer['max_lockouts']){
475 $loginizer['lockout_time'] = $loginizer['lockouts_extend'];
476 }
477
478 // Is he in the lockout time ?
479 if($result['time'] >= (time() - $loginizer['lockout_time'])){
480 $banlift = ceil((($result['time'] + $loginizer['lockout_time']) - time()) / 60);
481
482 //echo 'Current Time '.date('d/M/Y H:i:s P', time()).'<br />';
483 //echo 'Last attempt '.date('d/M/Y H:i:s P', $result['time']).'<br />';
484 //echo 'Unlock Time '.date('d/M/Y H:i:s P', $result['time'] + $loginizer['lockout_time']).'<br />';
485
486 $_time = $banlift.' '.$loginizer['msg']['minutes_err'];
487
488 if($banlift > 60){
489 $banlift = ceil($banlift / 60);
490 $_time = $banlift.' '.$loginizer['msg']['hours_err'];
491 }
492
493 $lz_error['ip_blocked'] = $loginizer['msg']['lockout_err'].' '.$_time;
494
495 return false;
496 }
497 }
498
499 return true;
500 }
501
502 function loginizer_is_blacklisted(){
503
504 global $wpdb, $loginizer, $lz_error;
505
506 $blacklist = isset($loginizer['blacklist']) ? $loginizer['blacklist'] : [];
507
508 if(empty($blacklist)){
509 return false;
510 }
511
512 foreach($blacklist as $k => $v){
513
514 // Is the IP in the blacklist ?
515 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) && inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
516 $result = 1;
517 break;
518 }
519
520 // Is it in a wider range ?
521 if(inet_ptoi($v['start']) >= 0 && inet_ptoi($v['end']) < 0){
522
523 // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
524 // if the current IP is <= than the start of the range, it is within the range
525 // OR
526 // if the current IP is <= than the end of the range, it is within the range
527 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip'])
528 || inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
529 $result = 1;
530 break;
531 }
532
533 }
534
535 }
536
537 // You are blacklisted
538 if(!empty($result)){
539 $lz_error['ip_blacklisted'] = $loginizer['msg']['ip_blacklisted'];
540 return true;
541 }
542
543 return false;
544
545 }
546
547 function loginizer_is_whitelisted(){
548
549 global $wpdb, $loginizer, $lz_error;
550
551 $whitelist = $loginizer['whitelist'];
552
553 if(empty($whitelist)){
554 return false;
555 }
556
557 foreach($whitelist as $k => $v){
558
559 // Is the IP in the blacklist ?
560 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) && inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
561 $result = 1;
562 break;
563 }
564
565 // Is it in a wider range ?
566 if(inet_ptoi($v['start']) >= 0 && inet_ptoi($v['end']) < 0){
567
568 // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
569 // if the current IP is <= than the start of the range, it is within the range
570 // OR
571 // if the current IP is <= than the end of the range, it is within the range
572 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip'])
573 || inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
574 $result = 1;
575 break;
576 }
577
578 }
579
580 }
581
582 // You are whitelisted
583 if(!empty($result)){
584 return true;
585 }
586
587 return false;
588
589 }
590
591 // When the login fails, then this is called
592 // We need to update the database
593 function loginizer_login_failed($username, $is_2fa = ''){
594
595 global $wpdb, $loginizer, $lz_cannot_login;
596
597 // 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
598 if(empty($username) || is_null($username)){
599 $username = '';
600 }
601
602 $fail_type = 'Login';
603
604 if(!empty($is_2fa)){
605 $fail_type = '2FA';
606 }
607
608 if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
609
610 // The params which comes when social login returns an error, have some characters, which WordPress could not save.
611 $server_uri = $_SERVER['REQUEST_URI'];
612 if(!empty($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], 'lz_social_provider') !== FALSE){
613 $request_uri = explode('=', $_SERVER['REQUEST_URI']);
614 $server_uri = $request_uri[0];
615 }
616
617 $url = @addslashes((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$server_uri);
618 $url = esc_url($url);
619
620 $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
621 $result = lz_selectquery($sel_query);
622
623 if(!empty($result)){
624 $lockout = floor((($result['count']+1) / $loginizer['max_retries']));
625
626 $update_data = array('username' => $username,
627 'time' => time(),
628 'count' => $result['count']+1,
629 'lockout' => $lockout,
630 'url' => $url);
631
632 $where_data = array('ip' => $loginizer['current_ip']);
633
634 $format = array('%s','%d','%d','%d','%s');
635 $where_format = array('%s');
636
637 $wpdb->update($wpdb->prefix.'loginizer_logs', $update_data, $where_data, $format, $where_format);
638
639 // Do we need to email admin ?
640 if(!empty($loginizer['notify_email']) && $lockout >= $loginizer['notify_email']){
641
642 $lockout_time = $loginizer['lockout_time'];
643
644 if($lockout >= $loginizer['max_lockouts']){
645 // extended lockout is in hours so we have to convert to minute
646 $lockout_time = $loginizer['lockouts_extend'];
647 }
648
649 $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
650 $mail = array();
651 $mail['to'] = $loginizer['notify_email_address'];
652 $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
653 $mail['message'] = 'Hi,
654
655 '.($result['count']+1).' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
656 '.home_url().'
657
658 Last '.$fail_type.' Attempt : '.date('d/M/Y H:i:s P', time()).'
659 Last User Attempt : '.$username.'
660 IP has been blocked until : '.date('d/M/Y H:i:s P', time() + $lockout_time).'
661
662 Regards,
663 Loginizer';
664
665 @wp_mail($mail['to'], $mail['subject'], $mail['message']);
666 }
667 }else{
668 $result = array();
669 $result['count'] = 0;
670
671 $insert_data = array('username' => $username,
672 'time' => time(),
673 'count' => 1,
674 'ip' => $loginizer['current_ip'],
675 'lockout' => 0,
676 'url' => $url);
677
678 $format = array('%s','%d','%d','%s','%d','%s');
679
680 $wpdb->insert($wpdb->prefix.'loginizer_logs', $insert_data, $format);
681 }
682
683 // We need to add one as this is a failed attempt as well
684 $result['count'] = $result['count'] + 1;
685 loginizer_update_attempt_stats(0);
686 $loginizer['retries_left'] = ($loginizer['max_retries'] - ($result['count'] % $loginizer['max_retries']));
687 $loginizer['retries_left'] = $loginizer['retries_left'] == $loginizer['max_retries'] ? 0 : $loginizer['retries_left'];
688
689 }
690 }
691
692 function loginizer_login_success($user_login, $user) {
693 global $wp_version, $loginizer;
694
695 loginizer_update_attempt_stats(1);
696
697 if(empty($loginizer['login_mail'])){
698 return;
699 }
700
701 if(empty($loginizer['login_mail']['enable'])){
702 return;
703 }
704
705 if(!empty($loginizer['login_mail']['disable_whitelist'])){
706 // Check its whitelist ip
707 if(loginizer_is_whitelisted()){
708 return;
709 }
710 }
711
712 if(empty($user_login) && empty($user)){
713 error_log('Loginizer: No user information to send email');
714 return;
715 }
716
717 if(empty($user)){
718 $user = get_user_by('login', $user_login);
719 }
720
721 if(empty($user)){
722 error_log('Loginizer: Unable to get the user');
723 return;
724 }
725
726 if(empty($loginizer['login_mail']['roles']) || !is_array($loginizer['login_mail']['roles'])){
727 return;
728 }
729
730 // Check if the user role is enabled for email notification.
731 if(!array_intersect($user->roles, $loginizer['login_mail']['roles'])){
732 return;
733 }
734
735 // current_datetime & wp_timezone_string were introduced in WordPress 5.3
736 if(!empty($wp_version) && version_compare($wp_version, '5.3', '>') && function_exists('current_datetime')){
737 $time_zone = wp_timezone_string();
738
739 if(!empty($time_zone) && isset($time_zone[1]) && is_numeric($time_zone[1])){
740 $time_zone = 'UTC'.$time_zone;
741 }
742
743 // Setting up data variables.
744 $date = current_datetime()->format('Y-m-d H:i:s') .' '. $time_zone;
745 } else {
746 $date = date("Y-m-d H:i:s", time()) . ' ' . date_default_timezone_get();
747 }
748
749 $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
750 $email = $user->data->user_email;
751
752 $vars = array(
753 'date' => $date,
754 'ip' => esc_html($loginizer['current_ip']),
755 'sitename' => $sitename,
756 'user_login' => $user_login
757 );
758
759 $message = lz_lang_vars_name($loginizer['login_mail_body'], $vars);
760 $subject = lz_lang_vars_name($loginizer['login_mail_subject'], $vars);
761
762 $headers = [];
763
764 // Do we need to send the email as HTML ?
765 if(!empty($loginizer['login_mail']['html_mail'])){
766 $headers[] = 'Content-Type: text/html; charset=UTF-8';
767
768 if(!empty($loginizer['login_mail']['body'])){
769 $message = html_entity_decode($message);
770 }else{
771 $message = preg_replace("/\<br\s*\/\>/i", "<br/>", $message);
772 $message = preg_replace('/(?<!<br\/>)\n/i', "<br/>\n", $message);
773 }
774 }
775
776 // Sending notification
777 if(empty(wp_mail($email, $subject, $message, $headers))){
778 error_log(__('There was a problem sending your email.', 'loginizer'));
779 return;
780 }
781 }
782
783 function loginizer_update_attempt_stats($type){
784
785 $stats = get_option('loginizer_login_attempt_stats', []);
786 $time = strtotime(date('Y-m-d H:00:00'));
787
788 if(empty($stats[$time][$type])){
789 $stats[$time][$type] = 0;
790 }
791
792 $stats[$time][$type] += 1;
793
794 update_option('loginizer_login_attempt_stats', $stats, false);
795 }
796
797 // Handles the error of the password not being there
798 function loginizer_error_handler($errors, $redirect_to){
799
800 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
801
802 //echo 'loginizer_error_handler :';print_r($errors->errors);echo '<br>';
803 if(is_null($errors) || empty($errors)){
804 return true;
805 }
806
807 // Remove the empty password error
808 if(is_wp_error($errors)){
809
810 $codes = $errors->get_error_codes();
811
812 foreach($codes as $k => $v){
813 if($v == 'invalid_username' || $v == 'incorrect_password'){
814 $show_error = 1;
815 }
816 }
817
818 $errors->remove('invalid_username');
819 $errors->remove('incorrect_password');
820
821 // Add the error
822 if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
823 $errors->add('invalid_userpass', '<b>ERROR:</b> ' . $loginizer['msg']['inv_userpass']);
824 }
825
826 // Add the number of retires left as well
827 if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
828 $errors->add('retries_left', loginizer_retries_left());
829 }
830
831 }
832
833 return $errors;
834
835 }
836
837 // Handles the error of the password not being there
838 function loginizer_woocommerce_error_handler(){
839
840 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
841
842 if(function_exists('wc_add_notice')){
843 wc_add_notice( loginizer_retries_left(), 'error' );
844 }
845 }
846
847 // Handles social login URL
848 function loginizer_social_login_error_handler($errors = '', $redirect_to = ''){
849 global $loginizer;
850
851 loginizer_get_social_error();
852
853 if(empty($loginizer['social_errors'])){
854 return $errors;
855 }
856
857 if(is_null($errors) || empty($errors) || !is_wp_error($errors)){
858 $errors = new WP_Error();
859 }
860
861 foreach($loginizer['social_errors'] as $key => $text){
862 $errors->add($key, $text);
863 }
864
865 return $errors;
866 }
867
868 // Returns a string with the number of retries left
869 function loginizer_retries_left(){
870
871 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
872
873 // If we are to show the number of retries left
874 if(isset($loginizer['retries_left'])){
875 $retries_left = apply_filters('loginizer_retries_left_num', $loginizer['retries_left']);
876
877 return '<b>'.esc_html($retries_left).'</b> '.$loginizer['msg']['attempts_left'];
878 }
879
880 }
881
882 function loginizer_reset_retries(){
883
884 global $wpdb, $loginizer;
885
886 $deltime = time() - $loginizer['reset_retries'];
887
888 $del_query = $wpdb->prepare("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= %d", $deltime);
889 $result = $wpdb->query($del_query);
890
891 update_option('loginizer_last_reset', time());
892
893 }
894
895 function loginizer_load_translation_vars(){
896 global $loginizer;
897
898 $loginizer['login_mail_default_sub'] = __('Login Successful at $sitename', 'loginizer');
899 $loginizer['login_mail_default_msg'] = __('Hello $user_login,
900
901 Your account was recently logged in from the IP : $ip
902 Time : $date
903 If it was not you who logged in then please report this to us immediately.
904
905 Regards,
906 $sitename','loginizer');
907
908 if(empty($loginizer['login_mail_subject'])){
909 $loginizer['login_mail_subject'] = $loginizer['login_mail_default_sub'];
910 }
911
912 if(empty($loginizer['login_mail_body'])){
913 $loginizer['login_mail_body'] = $loginizer['login_mail_default_msg'];
914 }
915
916 // Default messages
917 $loginizer['d_msg']['inv_userpass'] = __('Incorrect Username or Password', 'loginizer');
918 $loginizer['d_msg']['ip_blacklisted'] = __('Your IP has been blacklisted', 'loginizer');
919 $loginizer['d_msg']['attempts_left'] = __('attempt(s) left', 'loginizer');
920 $loginizer['d_msg']['lockout_err'] = __('You have exceeded maximum login retries<br /> Please try after', 'loginizer');
921 $loginizer['d_msg']['minutes_err'] = __('minute(s)', 'loginizer');
922 $loginizer['d_msg']['hours_err'] = __('hour(s)', 'loginizer');
923
924 // Message Strings
925 $loginizer['msg'] = get_option('loginizer_msg', []);
926
927 foreach($loginizer['d_msg'] as $lk => $lv){
928 if(empty($loginizer['msg'][$lk])){
929 $loginizer['msg'][$lk] = $loginizer['d_msg'][$lk];
930 }
931 }
932
933 $loginizer['2fa_d_msg']['otp_app'] = __('Please enter the OTP as seen in your App', 'loginizer');
934 $loginizer['2fa_d_msg']['otp_email'] = __('Please enter the OTP emailed to you', 'loginizer');
935 $loginizer['2fa_d_msg']['otp_field'] = __('One Time Password', 'loginizer');
936 $loginizer['2fa_d_msg']['otp_question'] = __('Please answer your security question', 'loginizer');
937 $loginizer['2fa_d_msg']['otp_answer'] = __('Your Answer', 'loginizer');
938
939 // Message Strings
940 $loginizer['2fa_msg'] = get_option('loginizer_2fa_msg', []);
941
942 foreach($loginizer['2fa_d_msg'] as $lk => $lv){
943 if(empty($loginizer['2fa_msg'][$lk])){
944 $loginizer['2fa_msg'][$lk] = $loginizer['2fa_d_msg'][$lk];
945 }
946 }
947
948 }
949
950 // Checks if softaculous is installed on the server.
951 function loginizer_check_softaculous(){
952
953 // Checking if we have Softaculous installed?
954 if(!preg_match('/^\/home(?:\d+)?\/.*\//U', ABSPATH, $matches)){
955 return false;
956 }
957
958 if(empty($matches) || empty($matches[0])){
959 return false;
960 }
961
962 $softaculous_path = $matches[0] . '.softaculous/installations.php';
963 if(!file_exists($softaculous_path)){
964 return false;
965 }
966
967 // Checking if users has changed the branding of Softaculous.
968 $universal_file = '';
969 // Plesk, ISPManager, ISPConfig, InterWorx, H-Sphere, CentOS Web Panel, Softaculous Remote and Softaculous Enterprise
970 if(file_exists('/usr/local/softaculous/enduser/universal.php')){
971 $universal_file = '/usr/local/softaculous/enduser/universal.php';
972 }else if(file_exists('/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php')){
973 $universal_file = '/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php';
974 }else if(file_exists('/usr/local/directadmin/plugins/softaculous/enduser/universal.php')){
975 $universal_file = '/usr/local/directadmin/plugins/softaculous/enduser/universal.php';
976 }else if(file_exists('/usr/local/vesta/softaculous/enduser/universal.php')){
977 $universal_file = '/usr/local/vesta/softaculous/enduser/universal.php';
978 }
979
980 if(empty($universal_file)){
981 return false;
982 }
983
984 $universal = file_get_contents($universal_file);
985
986 if(empty($universal)){
987 return false;
988 }
989
990 // Checking if Softaculous is being whitelabeled
991 if(preg_match('/\$globals\[["\']sn["\']\]\s.?=\s.?["\']Softaculous["\']/', $universal)){
992 update_option('loginizer_softwp_upgrade', time());
993 }
994
995 return false;
996 }
997
998 // Sorry to see you going
999 register_uninstall_hook(LOGINIZER_FILE, 'loginizer_deactivation');
1000
1001 function loginizer_deactivation(){
1002
1003 global $wpdb;
1004
1005 $sql = array();
1006 $sql[] = "DROP TABLE ".$wpdb->prefix."loginizer_logs;";
1007
1008 foreach($sql as $sk => $sv){
1009 $wpdb->query($sv);
1010 }
1011
1012 delete_option('loginizer_version');
1013 delete_option('loginizer_options');
1014 delete_option('loginizer_last_reset');
1015 delete_option('loginizer_whitelist');
1016 delete_option('loginizer_blacklist');
1017 delete_option('loginizer_msg');
1018 delete_option('loginizer_2fa_msg');
1019 delete_option('loginizer_2fa_email_template');
1020 delete_option('loginizer_security');
1021 delete_option('loginizer_wp_admin');
1022 delete_option('loginizer_csrf_promo_time');
1023 delete_option('loginizer_backuply_promo_time');
1024 delete_option('loginizer_promo_time');
1025 delete_option('loginizer_ins_time');
1026 delete_option('loginizer_2fa_whitelist');
1027 delete_option('loginizer_checksums_last_run');
1028 delete_option('loginizer_checksums_diff');
1029 delete_option('loginizer_ip_method');
1030 delete_option('loginizer_2fa_custom_redirect');
1031 delete_option('external_updates-loginizer-security');
1032 delete_option('loginizer_login_attempt_stats');
1033
1034 }