654 if($this->compat) |
654 if($this->compat) |
655 { |
655 { |
656 return $this->login_compat($username, md5($password), $level); |
656 return $this->login_compat($username, md5($password), $level); |
657 } |
657 } |
658 |
658 |
|
659 // Lockout check |
659 if ( !defined('IN_ENANO_INSTALL') ) |
660 if ( !defined('IN_ENANO_INSTALL') ) |
660 { |
661 { |
661 $lockout_data = $this->get_lockout_info($lockout_data); |
662 $lockout_data = $this->get_lockout_info($lockout_data); |
662 |
663 |
663 $captcha_good = false; |
664 $captcha_good = false; |
673 if ( $lockout_data['lockout_policy'] != 'disable' && !$captcha_good ) |
674 if ( $lockout_data['lockout_policy'] != 'disable' && !$captcha_good ) |
674 { |
675 { |
675 if ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] ) |
676 if ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] ) |
676 { |
677 { |
677 // ooh boy, somebody's in trouble ;-) |
678 // ooh boy, somebody's in trouble ;-) |
678 $row = $db->fetchrow(); |
|
679 $db->free_result(); |
|
680 return array( |
679 return array( |
681 'success' => false, |
680 'success' => false, |
682 'error' => 'locked_out', |
681 'error' => 'locked_out', |
683 'lockout_threshold' => $lockout_data['lockout_threshold'], |
682 'lockout_threshold' => $lockout_data['lockout_threshold'], |
684 'lockout_duration' => ( $lockout_data['lockout_duration'] ), |
683 'lockout_duration' => ( $lockout_data['lockout_duration'] ), |
685 'lockout_fails' => $lockout_data['lockout_fails'], |
684 'lockout_fails' => $lockout_data['lockout_fails'], |
686 'lockout_policy' => $lockout_data['lockout_policy'], |
685 'lockout_policy' => $lockout_data['lockout_policy'], |
687 'time_rem' => $lockout_data['lockout_time_rem'], |
686 'time_rem' => $lockout_data['time_rem'], |
688 'lockout_last_time' => $lockout_data['lockout_last_time'] |
687 'lockout_last_time' => $lockout_data['lockout_last_time'] |
689 ); |
688 ); |
690 } |
689 } |
691 } |
690 } |
692 $db->free_result(); |
|
693 } |
691 } |
694 |
692 |
695 // Instanciate the Rijndael encryption object |
693 // Instanciate the Rijndael encryption object |
696 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); |
694 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); |
697 |
695 |
1020 |
1018 |
1021 // Query database for lockout info |
1019 // Query database for lockout info |
1022 $locked_out = false; |
1020 $locked_out = false; |
1023 $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; |
1021 $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; |
1024 $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; |
1022 $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; |
1025 // convert to minutes |
1023 // convert to seconds |
1026 $duration = $duration * 60; |
1024 $duration = $duration * 60; |
|
1025 // decide on policy |
1027 $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; |
1026 $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; |
1028 if ( $policy != 'disable' ) |
1027 if ( $policy != 'disable' ) |
1029 { |
1028 { |
|
1029 // enabled; make decision |
1030 $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); |
1030 $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); |
1031 $timestamp_cutoff = time() - $duration; |
1031 $timestamp_cutoff = time() - $duration; |
1032 $q = $this->sql('SELECT timestamp FROM ' . table_prefix . 'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); |
1032 $q = $this->sql('SELECT timestamp FROM ' . table_prefix . 'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); |
1033 $fails = $db->numrows($q); |
1033 $fails = $db->numrows($q); |
1034 $row = $db->fetchrow($q); |
1034 $row = $db->fetchrow($q); |
1038 'lockout_threshold' => $threshold, |
1038 'lockout_threshold' => $threshold, |
1039 'lockout_duration' => ( $duration / 60 ), |
1039 'lockout_duration' => ( $duration / 60 ), |
1040 'lockout_fails' => $fails, |
1040 'lockout_fails' => $fails, |
1041 'lockout_policy' => $policy, |
1041 'lockout_policy' => $policy, |
1042 'lockout_last_time' => $row['timestamp'], |
1042 'lockout_last_time' => $row['timestamp'], |
1043 'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ), |
1043 'time_rem' => $locked_out ? ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ) : 0, |
1044 'captcha' => '' |
1044 'captcha' => '' |
1045 ); |
1045 ); |
1046 $db->free_result(); |
1046 $db->free_result(); |
1047 } |
1047 } |
1048 else |
1048 else |
1049 { |
1049 { |
|
1050 // disabled; send back default dataset |
1050 $lockdata = array( |
1051 $lockdata = array( |
1051 'locked_out' => false, |
1052 'locked_out' => false, |
1052 'lockout_threshold' => $threshold, |
1053 'lockout_threshold' => $threshold, |
1053 'lockout_duration' => ( $duration / 60 ), |
1054 'lockout_duration' => ( $duration / 60 ), |
1054 'lockout_fails' => 0, |
1055 'lockout_fails' => 0, |
4022 * than these will be treated as a pass-through, and the user's password will be validated through Enano's standard process. |
4023 * than these will be treated as a pass-through, and the user's password will be validated through Enano's standard process. |
4023 * @hook login_process_userdata_json |
4024 * @hook login_process_userdata_json |
4024 */ |
4025 */ |
4025 |
4026 |
4026 $code = $plugins->setHook('login_process_userdata_json', true); |
4027 $code = $plugins->setHook('login_process_userdata_json', true); |
|
4028 |
4027 foreach ( $code as $cmd ) |
4029 foreach ( $code as $cmd ) |
4028 { |
4030 { |
4029 $result = eval($cmd); |
4031 $result = eval($cmd); |
4030 if ( $result === true ) |
4032 if ( $result === true ) |
4031 { |
4033 { |