PluginProbe
Loginizer / trunk
Loginizer vtrunk
2.1.1 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 All 75 releases
← All changes | init.php +85 -63 2.0.8 → trunk View file →
@@ -4,9 +4,9 @@
4 4 echo 'You are not allowed to access this page directly.';
5 5 exit;
6 6 }
7 7
8 -define('LOGINIZER_VERSION', '2.0.8');
8 +define('LOGINIZER_VERSION', '2.1.1');
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 12 define('LOGINIZER_PRICING_URL', 'https://loginizer.com/pricing');
@@ -225,9 +225,9 @@
225 225 }
226 226
227 227 }
228 228
229 -// Add the action to load the plugin
229 +// Add the action to load the plugin
230 230 add_action('plugins_loaded', 'loginizer_load_plugin');
231 231
232 232 // The function that will be called when the plugin is loaded
233 233 function loginizer_load_plugin(){
@@ -235,8 +235,18 @@
235 235 global $loginizer;
236 236
237 237 // Check if the installed version is outdated
238 238 loginizer_update_check();
239 +
240 + // There was an issue were for some users update was stuck, and free was able to get updated through auto updater option
241 + // removing these filters fixes that issue, and our Pro update blocker was improved in 2.1.1
242 + // This check can be removed 1 year from 28.09.2026
243 + if(defined('LOGINIZER_PRO_VERSION') && version_compare(LOGINIZER_PRO_VERSION, '2.1.1', '<')){
244 + foreach(['site_transient_update_plugins', 'pre_site_transient_update_plugins'] as $hook){
245 + remove_filter($hook, 'loginizer_pro_disable_manual_update_for_plugin'); // Older Pro used the default priority
246 + remove_filter($hook, 'loginizer_pro_disable_manual_update_for_plugin', 99);
247 + }
248 + }
239 249
240 250 // Set the array
241 251 if(empty($loginizer)){
242 252 $loginizer = array();
@@ -339,15 +349,15 @@
339 349 if(!empty($loginizer['ultimate-member-active'])){
340 350 add_action('wp_login_failed', 'loginizer_ultimatemember_error_handler', 10001);
341 351 }
342 352
343 - if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
353 + if(!empty($_COOKIE['lz_social_error']) && !empty($loginizer['social_settings'])){
344 354 add_filter('wp_login_errors', 'loginizer_social_login_error_handler', 10000, 2);
345 355 }
346 356 }
347 357
348 358 // Social Login Form Actions
349 - if(!empty($loginizer['social_settings']) && !loginizer_is_blacklisted()){
359 + if(!empty($loginizer['social_settings'])){
350 360 if(!empty($loginizer['social_settings']['login']['login_form'])){
351 361 add_action('login_form', 'loginizer_social_btn_login');
352 362 }
353 363 }
@@ -556,53 +566,78 @@
556 566
557 567 if(empty($lz_cannot_login) && empty($loginizer['ip_is_whitelisted']) && empty($loginizer['no_loginizer_logs'])){
558 568
559 569 // 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']);
570 + // REQUEST_URI / HTTP_HOST are not always set (WP-CLI, some CGI and XML-RPC setups)
571 + $server_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
572 + $http_host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
573 +
574 + if(!empty($server_uri) && strpos($server_uri, 'lz_social_provider') !== FALSE){
575 + $request_uri = explode('=', $server_uri);
563 576 $server_uri = $request_uri[0];
564 577 }
565 578
566 - $url = @addslashes((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$server_uri);
567 - $url = esc_url($url);
579 + // No addslashes() here, $wpdb->prepare() below does the escaping
580 + $url = esc_url((!empty($_SERVER['HTTPS']) ? 'https://' : 'http://').$http_host.$server_uri);
568 581
582 + // Must never be 0, we divide by it below
583 + $max_retries = (int) $loginizer['max_retries'] < 1 ? 1 : (int) $loginizer['max_retries'];
584 +
585 + // This way is atomic now, the earlier one were causing race condition.
586 + // NOTE : In the UPDATE part `count` is already the new value, as MySQL / MariaDB
587 + // evaluate the assignments from left to right, so lockout must NOT add 1 again
588 + $upsert = $wpdb->prepare(
589 + "INSERT INTO `".$wpdb->prefix."loginizer_logs`
590 + (username, time, count, ip, lockout, url)
591 + VALUES
592 + (%s, %d, 1, %s, FLOOR(1 / %d), %s)
593 + ON DUPLICATE KEY UPDATE
594 + username = VALUES(username),
595 + time = VALUES(time),
596 + count = count + 1,
597 + lockout = FLOOR(count / %d),
598 + url = VALUES(url)",
599 + $username,
600 + time(),
601 + $loginizer['current_ip'],
602 + $max_retries,
603 + $url,
604 + $max_retries
605 + );
606 + $wpdb->query($upsert);
607 +
608 + // Re-read the persisted row so email/retries-left reflect the actual count
569 609 $sel_query = $wpdb->prepare("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = %s", $loginizer['current_ip']);
570 610 $result = lz_selectquery($sel_query);
571 -
572 - if(!empty($result)){
573 - $lockout = floor((($result['count']+1) / $loginizer['max_retries']));
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 -
588 - // Do we need to email admin ?
589 - if(!empty($loginizer['notify_email']) && $lockout >= $loginizer['notify_email']){
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 -
598 - $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
599 - $mail = array();
600 - $mail['to'] = $loginizer['notify_email_address'];
601 - $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
602 - $mail['message'] = 'Hi,
603 611
604 -'.($result['count']+1).' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
612 + if(empty($result)){
613 + $result = array('count' => 0);
614 + }
615 +
616 + $count = (int) $result['count'];
617 + $lockout = !empty($result['lockout']) ? (int) $result['lockout'] : 0;
618 +
619 + // The lockout goes up only on every max_retries'th failure, which is the
620 + // attempt that actually locks the IP out. On the failures in between there
621 + // is nothing new to report, so we must not email on each one of them
622 + $is_new_lockout = !empty($count) && ($count % $max_retries) == 0;
623 +
624 + // Do we need to email admin ?
625 + if(!empty($loginizer['notify_email']) && !empty($is_new_lockout) && $lockout >= $loginizer['notify_email']){
626 +
627 + $lockout_time = $loginizer['lockout_time'];
628 +
629 + if($lockout >= $loginizer['max_lockouts']){
630 + $lockout_time = $loginizer['lockouts_extend'];
631 + }
632 +
633 + $sitename = lz_is_multisite() ? get_site_option('site_name') : get_option('blogname');
634 + $mail = array();
635 + $mail['to'] = $loginizer['notify_email_address'];
636 + $mail['subject'] = 'Failed '.$fail_type.' Attempts from IP '.$loginizer['current_ip'].' ('.$sitename.')';
637 + $mail['message'] = 'Hi,
638 +
639 +'.(int) $result['count'].' failed '.strtolower($fail_type).' attempts and '.$lockout.' lockout(s) from IP '.$loginizer['current_ip'].' on your site :
605 640 '.home_url().'
606 641
607 642 Last '.$fail_type.' Attempt : '.date('d/M/Y H:i:s P', time()).'
608 643 Last User Attempt : '.$username.'
@@ -610,31 +645,14 @@
610 645
611 646 Regards,
612 647 Loginizer';
613 648
614 - @wp_mail($mail['to'], $mail['subject'], $mail['message']);
615 - }
616 - }else{
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);
649 + @wp_mail($mail['to'], $mail['subject'], $mail['message']);
630 650 }
631 -
632 - // We need to add one as this is a failed attempt as well
633 - $result['count'] = $result['count'] + 1;
651 +
634 652 loginizer_update_attempt_stats(0);
635 - $loginizer['retries_left'] = ($loginizer['max_retries'] - ($result['count'] % $loginizer['max_retries']));
636 - $loginizer['retries_left'] = $loginizer['retries_left'] == $loginizer['max_retries'] ? 0 : $loginizer['retries_left'];
653 + $loginizer['retries_left'] = $max_retries - ($count % $max_retries);
654 + $loginizer['retries_left'] = $loginizer['retries_left'] == $max_retries ? 0 : $loginizer['retries_left'];
637 655
638 656 }
639 657 }
640 658
@@ -806,8 +824,12 @@
806 824
807 825 // Handles social login URL
808 826 function loginizer_social_login_error_handler($errors = '', $redirect_to = ''){
809 827 global $loginizer;
828 +
829 + if(loginizer_is_blacklisted()){
830 + return $errors;
831 + }
810 832
811 833 loginizer_get_social_error();
812 834
813 835 if(empty($loginizer['social_errors'])){