PluginProbe
Loginizer / 2.0.3
Loginizer v2.0.3
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 2.0.3, at init.php

1,032 lines 31.3 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', '2.0.3');
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 // 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
212 // Save the new Version
213 update_option('loginizer_version', LOGINIZER_VERSION);
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
227 }
228
229 // Add the action to load the plugin
230 add_action('plugins_loaded', 'loginizer_load_plugin');
231
232 // The function that will be called when the plugin is loaded
233 function loginizer_load_plugin(){
234
235 global $loginizer;
236
237 // Check if the installed version is outdated
238 loginizer_update_check();
239
240 // Set the array
241 if(empty($loginizer)){
242 $loginizer = array();
243 }
244
245 $loginizer['prefix'] = !defined('SITEPAD') ? 'Loginizer ' : 'SitePad ';
246 $loginizer['app'] = !defined('SITEPAD') ? 'WordPress' : 'SitePad';
247 $loginizer['login_basename'] = !defined('SITEPAD') ? 'wp-login.php' : 'login.php';
248 $loginizer['wp-includes'] = !defined('SITEPAD') ? 'wp-includes' : 'site-inc';
249
250 // The IP Method to use
251 $loginizer['ip_method'] = get_option('loginizer_ip_method');
252 if($loginizer['ip_method'] == 3){
253 $loginizer['custom_ip_method'] = get_option('loginizer_custom_ip_method');
254 }
255
256 // Load settings
257 $options = get_option('loginizer_options');
258 $loginizer['max_retries'] = empty($options['max_retries']) ? 3 : $options['max_retries'];
259 $loginizer['lockout_time'] = empty($options['lockout_time']) ? 900 : $options['lockout_time']; // 15 minutes
260 $loginizer['max_lockouts'] = empty($options['max_lockouts']) ? 5 : $options['max_lockouts'];
261 $loginizer['lockouts_extend'] = empty($options['lockouts_extend']) ? 86400 : $options['lockouts_extend']; // 24 hours
262 $loginizer['reset_retries'] = empty($options['reset_retries']) ? 86400 : $options['reset_retries']; // 24 hours
263 $loginizer['notify_email'] = empty($options['notify_email']) ? 0 : $options['notify_email'];
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
281 // Load the blacklist and whitelist
282 $loginizer['blacklist'] = get_option('loginizer_blacklist', []);
283 $loginizer['whitelist'] = get_option('loginizer_whitelist', []);
284 $loginizer['2fa_whitelist'] = get_option('loginizer_2fa_whitelist');
285
286 // It should not be false
287 if(empty($loginizer['2fa_whitelist'])){
288 $loginizer['2fa_whitelist'] = array();
289 }
290
291 // When was the database cleared last time
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 }
299
300 //print_r($loginizer);
301
302 // Clear retries
303 if((time() - $loginizer['last_reset']) >= $loginizer['reset_retries']){
304 loginizer_reset_retries();
305 }
306
307 $ins_time = get_option('loginizer_ins_time');
308 if(empty($ins_time)){
309 $ins_time = time();
310 update_option('loginizer_ins_time', $ins_time);
311 }
312 $loginizer['ins_time'] = $ins_time;
313
314 // Set the current IP
315 $loginizer['current_ip'] = lz_getip();
316
317 // Is Brute Force Disabled ?
318 $loginizer['disable_brute'] = get_option('loginizer_disable_brute');
319
320 // Filters and actions
321 if(empty($loginizer['disable_brute'])){
322
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
327
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');
331
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', 10, 2);
337
338 if(!empty($loginizer['ultimate-member-active'])){
339 add_action('wp_login_failed', 'loginizer_ultimatemember_error_handler', 10001);
340 }
341
342 if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
343 add_filter('wp_login_errors', 'loginizer_social_login_error_handler', 10000, 2);
344 }
345 }
346
347 // Social Login Form Actions
348 if(!empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
349 if(!empty($loginizer['social_settings']['login']['login_form'])){
350 add_action('login_form', 'loginizer_social_btn_login');
351 }
352 }
353
354 if((function_exists('wp_doing_ajax') && wp_doing_ajax()) || (defined( 'DOING_AJAX' ) && DOING_AJAX)){
355 include_once LOGINIZER_DIR . '/main/ajax.php';
356 }
357
358 if(is_admin()){
359 include_once LOGINIZER_DIR . '/main/admin.php';
360 }
361
362 // ----------------
363 // PRO INIT END
364 // ----------------
365
366 // Secuity checks for social login.
367 if(!empty($_GET['lz_social_provider']) && loginizer_can_login() && empty($_GET['lz_api'])){
368 add_action('init', 'loginizer_social_login_load');
369 return;
370 }
371 }
372
373 // Should return NULL if everything is fine
374 function loginizer_wp_authenticate($user, $username, $password){
375
376 global $loginizer, $lz_error, $lz_cannot_login, $lz_user_pass;
377
378 if(!empty($username) && !empty($password)){
379 $lz_user_pass = 1;
380 }
381
382 // Are you whitelisted ?
383 if(loginizer_is_whitelisted()){
384 $loginizer['ip_is_whitelisted'] = 1;
385 return $user;
386
387 } else if (!empty($loginizer['trusted_ips'])){
388 $lz_cannot_login = 1;
389
390 // This is used by WP Activity Log
391 apply_filters( 'wp_login_blocked', $username );
392
393 // Shows a blocked screen
394 if(!empty($loginizer['blocked_screen'])){
395 $lz_error['trusted_ip'] = __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer');
396 loginizer_blocked_page($lz_error);
397 }
398
399 return new WP_Error('ip_blacklisted', __('You are restricted from logging in as your IP is not whitelisted.', 'loginizer'));
400 }
401
402 // Are you blacklisted ?
403 if(loginizer_is_blacklisted()){
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 loginizer_blocked_page($lz_error);
412 }
413
414 return new WP_Error('ip_blacklisted', implode('', $lz_error), 'loginizer');
415 }
416
417 // Is the username blacklisted ?
418 if(function_exists('loginizer_user_blacklisted')){
419 if(loginizer_user_blacklisted($username)){
420 $lz_cannot_login = 1;
421
422 // This is used by WP Activity Log
423 apply_filters( 'wp_login_blocked', $username );
424
425 return new WP_Error('user_blacklisted', implode('', $lz_error), 'loginizer');
426 }
427 }
428
429 if(loginizer_can_login()){
430 return $user;
431 }
432
433 $lz_cannot_login = 1;
434
435 // This is used by WP Activity Log
436 apply_filters( 'wp_login_blocked', $username );
437
438 // Shows a blocked screen
439 if(!empty($loginizer['blocked_screen'])){
440 loginizer_blocked_page($lz_error);
441 }
442
443 return new WP_Error('ip_blocked', implode('', $lz_error), 'loginizer');
444
445 }
446
447 function loginizer_can_login(){
448
449 global $wpdb, $loginizer, $lz_error;
450
451 // Get the logs
452 $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
453 $result = lz_selectquery($sel_query);
454
455 if(!empty($result['count']) && ($result['count'] % $loginizer['max_retries']) == 0){
456
457 // Has he reached max lockouts ?
458 if($result['lockout'] >= $loginizer['max_lockouts']){
459 $loginizer['lockout_time'] = $loginizer['lockouts_extend'];
460 }
461
462 // Is he in the lockout time ?
463 if($result['time'] >= (time() - $loginizer['lockout_time'])){
464 $banlift = ceil((($result['time'] + $loginizer['lockout_time']) - time()) / 60);
465
466 //echo 'Current Time '.date('d/M/Y H:i:s P', time()).'<br />';
467 //echo 'Last attempt '.date('d/M/Y H:i:s P', $result['time']).'<br />';
468 //echo 'Unlock Time '.date('d/M/Y H:i:s P', $result['time'] + $loginizer['lockout_time']).'<br />';
469
470 $_time = $banlift.' '.$loginizer['msg']['minutes_err'];
471
472 if($banlift > 60){
473 $banlift = ceil($banlift / 60);
474 $_time = $banlift.' '.$loginizer['msg']['hours_err'];
475 }
476
477 $lz_error['ip_blocked'] = $loginizer['msg']['lockout_err'].' '.$_time;
478
479 if(!empty($loginizer['ultimate-member-active']) && class_exists('UM')){
480 \UM()->form()->add_error('blocked_msg', $lz_error['ip_blocked']);
481 }
482 return false;
483 }
484 }
485
486 return true;
487 }
488
489 function loginizer_is_blacklisted(){
490
491 global $wpdb, $loginizer, $lz_error;
492
493 $blacklist = isset($loginizer['blacklist']) ? $loginizer['blacklist'] : [];
494
495 if(empty($blacklist)){
496 return false;
497 }
498
499 foreach($blacklist as $k => $v){
500
501 // Is the IP in the blacklist ?
502 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) && inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
503 $result = 1;
504 break;
505 }
506
507 // Is it in a wider range ?
508 if(inet_ptoi($v['start']) >= 0 && inet_ptoi($v['end']) < 0){
509
510 // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
511 // if the current IP is <= than the start of the range, it is within the range
512 // OR
513 // if the current IP is <= than the end of the range, it is within the range
514 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip'])
515 || inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
516 $result = 1;
517 break;
518 }
519
520 }
521
522 }
523
524 // You are blacklisted
525 if(!empty($result)){
526 $lz_error['ip_blacklisted'] = $loginizer['msg']['ip_blacklisted'];
527 return true;
528 }
529
530 return false;
531
532 }
533
534 function loginizer_is_whitelisted(){
535
536 global $wpdb, $loginizer, $lz_error;
537
538 $whitelist = $loginizer['whitelist'];
539
540 if(empty($whitelist)){
541 return false;
542 }
543
544 foreach($whitelist as $k => $v){
545
546 // Is the IP in the blacklist ?
547 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip']) && inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
548 $result = 1;
549 break;
550 }
551
552 // Is it in a wider range ?
553 if(inet_ptoi($v['start']) >= 0 && inet_ptoi($v['end']) < 0){
554
555 // Since the end of the RANGE (i.e. current IP range) is beyond the +ve value of inet_ptoi,
556 // if the current IP is <= than the start of the range, it is within the range
557 // OR
558 // if the current IP is <= than the end of the range, it is within the range
559 if(inet_ptoi($v['start']) <= inet_ptoi($loginizer['current_ip'])
560 || inet_ptoi($loginizer['current_ip']) <= inet_ptoi($v['end'])){
561 $result = 1;
562 break;
563 }
564
565 }
566
567 }
568
569 // You are whitelisted
570 if(!empty($result)){
571 return true;
572 }
573
574 return false;
575
576 }
577
578 // When the login fails, then this is called
579 // We need to update the database
580 function loginizer_login_failed($username, $is_2fa = ''){
581
582 global $wpdb, $loginizer, $lz_cannot_login;
583
584 // 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
585 if(empty($username) || is_null($username)){
586 $username = '';
587 }
588
589 $fail_type = 'Login';
590
591 if(!empty($is_2fa)){
592 $fail_type = '2FA';
593 }
594
595 if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
596
597 // The params which comes when social login returns an error, have some characters, which WordPress could not save.
598 $server_uri = $_SERVER['REQUEST_URI'];
599 if(!empty($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], 'lz_social_provider') !== FALSE){
600 $request_uri = explode('=', $_SERVER['REQUEST_URI']);
601 $server_uri = $request_uri[0];
602 }
603
604 $url = @addslashes((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$server_uri);
605 $url = esc_url($url);
606
607 $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
608 $result = lz_selectquery($sel_query);
609
610 if(!empty($result)){
611 $lockout = floor((($result['count']+1) / $loginizer['max_retries']));
612
613 $update_data = array('username' => $username,
614 'time' => time(),
615 'count' => $result['count']+1,
616 'lockout' => $lockout,
617 'url' => $url);
618
619 $where_data = array('ip' => $loginizer['current_ip']);
620
621 $format = array('%s','%d','%d','%d','%s');
622 $where_format = array('%s');
623
624 $wpdb->update($wpdb->prefix.'loginizer_logs', $update_data, $where_data, $format, $where_format);
625
626 // Do we need to email admin ?
627 if(!empty($loginizer['notify_email']) && $lockout >= $loginizer['notify_email']){
628
629 $lockout_time = $loginizer['lockout_time'];
630
631 if($lockout >= $loginizer['max_lockouts']){
632 // extended lockout is in hours so we have to convert to minute
633 $lockout_time = $loginizer['lockouts_extend'];
634 }
635
636 $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
637 $mail = array();
638 $mail['to'] = $loginizer['notify_email_address'];
639 $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
640 $mail['message'] = 'Hi,
641
642 '.($result['count']+1).' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
643 '.home_url().'
644
645 Last '.$fail_type.' Attempt : '.date('d/M/Y H:i:s P', time()).'
646 Last User Attempt : '.$username.'
647 IP has been blocked until : '.date('d/M/Y H:i:s P', time() + $lockout_time).'
648
649 Regards,
650 Loginizer';
651
652 @wp_mail($mail['to'], $mail['subject'], $mail['message']);
653 }
654 }else{
655 $result = array();
656 $result['count'] = 0;
657
658 $insert_data = array('username' => $username,
659 'time' => time(),
660 'count' => 1,
661 'ip' => $loginizer['current_ip'],
662 'lockout' => 0,
663 'url' => $url);
664
665 $format = array('%s','%d','%d','%s','%d','%s');
666
667 $wpdb->insert($wpdb->prefix.'loginizer_logs', $insert_data, $format);
668 }
669
670 // We need to add one as this is a failed attempt as well
671 $result['count'] = $result['count'] + 1;
672 loginizer_update_attempt_stats(0);
673 $loginizer['retries_left'] = ($loginizer['max_retries'] - ($result['count'] % $loginizer['max_retries']));
674 $loginizer['retries_left'] = $loginizer['retries_left'] == $loginizer['max_retries'] ? 0 : $loginizer['retries_left'];
675
676 }
677 }
678
679 function loginizer_login_success($user_login, $user) {
680 global $wp_version, $loginizer;
681
682 loginizer_update_attempt_stats(1);
683
684 if(empty($loginizer['login_mail'])){
685 return;
686 }
687
688 if(empty($loginizer['login_mail']['enable'])){
689 return;
690 }
691
692 if(!empty($loginizer['login_mail']['disable_whitelist'])){
693 // Check its whitelist ip
694 if(loginizer_is_whitelisted()){
695 return;
696 }
697 }
698
699 if(empty($user_login) && empty($user)){
700 error_log('Loginizer: No user information to send email');
701 return;
702 }
703
704 if(empty($user)){
705 $user = get_user_by('login', $user_login);
706 }
707
708 if(empty($user)){
709 error_log('Loginizer: Unable to get the user');
710 return;
711 }
712
713 if(empty($loginizer['login_mail']['roles']) || !is_array($loginizer['login_mail']['roles'])){
714 return;
715 }
716
717 // Check if the user role is enabled for email notification.
718 if(!array_intersect($user->roles, $loginizer['login_mail']['roles'])){
719 return;
720 }
721
722 // current_datetime & wp_timezone_string were introduced in WordPress 5.3
723 if(!empty($wp_version) && version_compare($wp_version, '5.3', '>') && function_exists('current_datetime')){
724 $time_zone = wp_timezone_string();
725
726 if(!empty($time_zone) && isset($time_zone[1]) && is_numeric($time_zone[1])){
727 $time_zone = 'UTC'.$time_zone;
728 }
729
730 // Setting up data variables.
731 $date = current_datetime()->format('Y-m-d H:i:s') .' '. $time_zone;
732 } else {
733 $date = date("Y-m-d H:i:s", time()) . ' ' . date_default_timezone_get();
734 }
735
736 $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
737 $email = $user->data->user_email;
738
739 $vars = array(
740 'date' => $date,
741 'ip' => esc_html($loginizer['current_ip']),
742 'sitename' => $sitename,
743 'user_login' => $user_login
744 );
745
746 $message = lz_lang_vars_name($loginizer['login_mail_body'], $vars);
747 $subject = lz_lang_vars_name($loginizer['login_mail_subject'], $vars);
748
749 $headers = [];
750
751 // Do we need to send the email as HTML ?
752 if(!empty($loginizer['login_mail']['html_mail'])){
753 $headers[] = 'Content-Type: text/html; charset=UTF-8';
754
755 if(!empty($loginizer['login_mail']['body'])){
756 $message = html_entity_decode($message);
757 }else{
758 $message = preg_replace("/\<br\s*\/\>/i", "<br/>", $message);
759 $message = preg_replace('/(?<!<br\/>)\n/i', "<br/>\n", $message);
760 }
761 }
762
763 // Sending notification
764 if(empty(wp_mail($email, $subject, $message, $headers))){
765 error_log(__('There was a problem sending your email.', 'loginizer'));
766 return;
767 }
768 }
769
770 function loginizer_update_attempt_stats($type){
771
772 $stats = get_option('loginizer_login_attempt_stats', []);
773 $time = strtotime(date('Y-m-d H:00:00'));
774
775 if(empty($stats[$time][$type])){
776 $stats[$time][$type] = 0;
777 }
778
779 $stats[$time][$type] += 1;
780
781 update_option('loginizer_login_attempt_stats', $stats, false);
782 }
783
784 // Handles the error of the password not being there
785 function loginizer_error_handler($errors, $redirect_to){
786
787 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
788
789 //echo 'loginizer_error_handler :';print_r($errors->errors);echo '<br>';
790 if(is_null($errors) || empty($errors)){
791 return true;
792 }
793
794 // Remove the empty password error
795 if(is_wp_error($errors)){
796
797 $codes = $errors->get_error_codes();
798
799 foreach($codes as $k => $v){
800 if($v == 'invalid_username' || $v == 'incorrect_password'){
801 $show_error = 1;
802 }
803 }
804
805 $errors->remove('invalid_username');
806 $errors->remove('incorrect_password');
807
808 // Add the error
809 if(!empty($lz_user_pass) && !empty($show_error) && empty($lz_cannot_login)){
810 $errors->add('invalid_userpass', '<b>ERROR:</b> ' . $loginizer['msg']['inv_userpass']);
811 }
812
813 // Add the number of retires left as well
814 if(count($errors->get_error_codes()) > 0 && isset($loginizer['retries_left'])){
815 $errors->add('retries_left', loginizer_retries_left());
816 }
817
818 }
819
820 return $errors;
821
822 }
823
824 // Handles the error of the password not being there
825 function loginizer_woocommerce_error_handler(){
826
827 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
828
829 if(function_exists('wc_add_notice')){
830 wc_add_notice( loginizer_retries_left(), 'error' );
831 }
832 }
833
834 function loginizer_ultimatemember_error_handler(){
835
836 if(class_exists('UM')){
837 \UM()->form()->add_error('remaining_tries', loginizer_retries_left());
838 }
839 }
840
841 // Handles social login URL
842 function loginizer_social_login_error_handler($errors = '', $redirect_to = ''){
843 global $loginizer;
844
845 loginizer_get_social_error();
846
847 if(empty($loginizer['social_errors'])){
848 return $errors;
849 }
850
851 if(is_null($errors) || empty($errors) || !is_wp_error($errors)){
852 $errors = new WP_Error();
853 }
854
855 foreach($loginizer['social_errors'] as $key => $text){
856 $errors->add($key, $text);
857 }
858
859 return $errors;
860 }
861
862 // Returns a string with the number of retries left
863 function loginizer_retries_left(){
864
865 global $wpdb, $loginizer, $lz_user_pass, $lz_cannot_login;
866
867 // If we are to show the number of retries left
868 if(isset($loginizer['retries_left'])){
869 $retries_left = apply_filters('loginizer_retries_left_num', $loginizer['retries_left']);
870
871 return '<b>'.esc_html($retries_left).'</b> '.$loginizer['msg']['attempts_left'];
872 }
873
874 }
875
876 function loginizer_reset_retries(){
877
878 global $wpdb, $loginizer;
879
880 $deltime = time() - $loginizer['reset_retries'];
881
882 $del_query = $wpdb->prepare("DELETE FROM `".$wpdb->prefix."loginizer_logs` WHERE `time` <= %d", $deltime);
883 $result = $wpdb->query($del_query);
884
885 update_option('loginizer_last_reset', time());
886
887 }
888
889 function loginizer_load_translation_vars(){
890 global $loginizer;
891
892 $loginizer['login_mail_default_sub'] = __('Login Successful at $sitename', 'loginizer');
893 $loginizer['login_mail_default_msg'] = __('Hello $user_login,
894
895 Your account was recently logged in from the IP : $ip
896 Time : $date
897 If it was not you who logged in then please report this to us immediately.
898
899 Regards,
900 $sitename','loginizer');
901
902 if(empty($loginizer['login_mail_subject'])){
903 $loginizer['login_mail_subject'] = $loginizer['login_mail_default_sub'];
904 }
905
906 if(empty($loginizer['login_mail_body'])){
907 $loginizer['login_mail_body'] = $loginizer['login_mail_default_msg'];
908 }
909
910 // Default messages
911 $loginizer['d_msg']['inv_userpass'] = __('Incorrect Username or Password', 'loginizer');
912 $loginizer['d_msg']['ip_blacklisted'] = __('Your IP has been blacklisted', 'loginizer');
913 $loginizer['d_msg']['attempts_left'] = __('attempt(s) left', 'loginizer');
914 $loginizer['d_msg']['lockout_err'] = __('You have exceeded maximum login retries<br /> Please try after', 'loginizer');
915 $loginizer['d_msg']['minutes_err'] = __('minute(s)', 'loginizer');
916 $loginizer['d_msg']['hours_err'] = __('hour(s)', 'loginizer');
917
918 // Message Strings
919 $loginizer['msg'] = get_option('loginizer_msg', []);
920
921 foreach($loginizer['d_msg'] as $lk => $lv){
922 if(empty($loginizer['msg'][$lk])){
923 $loginizer['msg'][$lk] = $loginizer['d_msg'][$lk];
924 }
925 }
926
927 $loginizer['2fa_d_msg']['otp_app'] = __('Please enter the OTP as seen in your App', 'loginizer');
928 $loginizer['2fa_d_msg']['otp_email'] = __('Please enter the OTP emailed to you', 'loginizer');
929 $loginizer['2fa_d_msg']['otp_field'] = __('One Time Password', 'loginizer');
930 $loginizer['2fa_d_msg']['otp_question'] = __('Please answer your security question', 'loginizer');
931 $loginizer['2fa_d_msg']['otp_answer'] = __('Your Answer', 'loginizer');
932
933 // Message Strings
934 $loginizer['2fa_msg'] = get_option('loginizer_2fa_msg', []);
935
936 foreach($loginizer['2fa_d_msg'] as $lk => $lv){
937 if(empty($loginizer['2fa_msg'][$lk])){
938 $loginizer['2fa_msg'][$lk] = $loginizer['2fa_d_msg'][$lk];
939 }
940 }
941
942 }
943
944 function loginizer_social_login_load(){
945 include_once LOGINIZER_DIR . '/main/social-login.php';
946 }
947
948 // Checks if softaculous is installed on the server.
949 function loginizer_check_softaculous(){
950
951 // Checking if we have Softaculous installed?
952 if(!preg_match('/^\/home(?:\d+)?\/.*\//U', ABSPATH, $matches)){
953 return false;
954 }
955
956 if(empty($matches) || empty($matches[0])){
957 return false;
958 }
959
960 $softaculous_path = $matches[0] . '.softaculous/installations.php';
961 if(!file_exists($softaculous_path)){
962 return false;
963 }
964
965 // Checking if users has changed the branding of Softaculous.
966 $universal_file = '';
967 // Plesk, ISPManager, ISPConfig, InterWorx, H-Sphere, CentOS Web Panel, Softaculous Remote and Softaculous Enterprise
968 if(file_exists('/usr/local/softaculous/enduser/universal.php')){
969 $universal_file = '/usr/local/softaculous/enduser/universal.php';
970 }else if(file_exists('/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php')){
971 $universal_file = '/usr/local/cpanel/whostmgr/docroot/cgi/softaculous/enduser/universal.php';
972 }else if(file_exists('/usr/local/directadmin/plugins/softaculous/enduser/universal.php')){
973 $universal_file = '/usr/local/directadmin/plugins/softaculous/enduser/universal.php';
974 }else if(file_exists('/usr/local/vesta/softaculous/enduser/universal.php')){
975 $universal_file = '/usr/local/vesta/softaculous/enduser/universal.php';
976 }
977
978 if(empty($universal_file)){
979 return false;
980 }
981
982 $universal = file_get_contents($universal_file);
983
984 if(empty($universal)){
985 return false;
986 }
987
988 // Checking if Softaculous is being whitelabeled
989 if(preg_match('/\$globals\[["\']sn["\']\]\s.?=\s.?["\']Softaculous["\']/', $universal)){
990 update_option('loginizer_softwp_upgrade', time());
991 }
992
993 return false;
994 }
995
996 // Sorry to see you going
997 register_uninstall_hook(LOGINIZER_FILE, 'loginizer_deactivation');
998
999 function loginizer_deactivation(){
1000
1001 global $wpdb;
1002
1003 $sql = array();
1004 $sql[] = "DROP TABLE ".$wpdb->prefix."loginizer_logs;";
1005
1006 foreach($sql as $sk => $sv){
1007 $wpdb->query($sv);
1008 }
1009
1010 delete_option('loginizer_version');
1011 delete_option('loginizer_options');
1012 delete_option('loginizer_last_reset');
1013 delete_option('loginizer_whitelist');
1014 delete_option('loginizer_blacklist');
1015 delete_option('loginizer_msg');
1016 delete_option('loginizer_2fa_msg');
1017 delete_option('loginizer_2fa_email_template');
1018 delete_option('loginizer_security');
1019 delete_option('loginizer_wp_admin');
1020 delete_option('loginizer_csrf_promo_time');
1021 delete_option('loginizer_backuply_promo_time');
1022 delete_option('loginizer_promo_time');
1023 delete_option('loginizer_ins_time');
1024 delete_option('loginizer_2fa_whitelist');
1025 delete_option('loginizer_checksums_last_run');
1026 delete_option('loginizer_checksums_diff');
1027 delete_option('loginizer_ip_method');
1028 delete_option('loginizer_2fa_custom_redirect');
1029 delete_option('external_updates-loginizer-security');
1030 delete_option('loginizer_login_attempt_stats');
1031
1032 }