Added possibility for auth plugins, which can log a user in using non-standard authentication methods.
authorDan
Thu, 26 Feb 2009 01:07:32 -0500
changeset 8434415e50e4e84
parent 842 f13bb4f21890
child 844 7549f2880c32
Added possibility for auth plugins, which can log a user in using non-standard authentication methods.
includes/clientside/static/crypto.js
includes/clientside/static/login.js
includes/paths.php
includes/sessions.php
includes/template.php
plugins/SpecialUserFuncs.php
     1.1 --- a/includes/clientside/static/crypto.js	Thu Feb 26 01:06:58 2009 -0500
     1.2 +++ b/includes/clientside/static/crypto.js	Thu Feb 26 01:07:32 2009 -0500
     1.3 @@ -1981,7 +1981,6 @@
     1.4        var hexch = text.substr(i, 3);
     1.5        if ( hexch.match(/^%[a-f0-9][a-f0-9]$/i) )
     1.6        {
     1.7 -        console.debug('hexch: ', hexch);
     1.8          result[result.length] = (unescape(hexch)).charCodeAt(0);
     1.9          a = true;
    1.10          i += 2;
     2.1 --- a/includes/clientside/static/login.js	Thu Feb 26 01:06:58 2009 -0500
     2.2 +++ b/includes/clientside/static/login.js	Thu Feb 26 01:07:32 2009 -0500
     2.3 @@ -347,6 +347,10 @@
     2.4        
     2.5        break;
     2.6        
     2.7 +    default:
     2.8 +      eval(setHook('login_set_status'));
     2.9 +      break;
    2.10 +      
    2.11      case AJAX_STATUS_DESTROY:
    2.12      case null:
    2.13      case undefined:
    2.14 @@ -556,6 +560,8 @@
    2.15    tr2.appendChild(td2_2);
    2.16    table.appendChild(tr2);
    2.17    
    2.18 +  eval(setHook('login_build_form'));
    2.19 +  
    2.20    // Field - captcha
    2.21    if ( show_captcha )
    2.22    {
    2.23 @@ -806,11 +812,11 @@
    2.24      }
    2.25    }
    2.26    
    2.27 -  if ( !username )
    2.28 +  if ( typeof(username) != 'string' )
    2.29    {
    2.30      var username = document.getElementById('ajax_login_field_username').value;
    2.31    }
    2.32 -  if ( !password )
    2.33 +  if ( typeof(password) != 'string' )
    2.34    {
    2.35      var password = document.getElementById('ajax_login_field_password').value;
    2.36    }
    2.37 @@ -851,10 +857,14 @@
    2.38    ajaxLoginSetStatus(AJAX_STATUS_LOGGING_IN);
    2.39    
    2.40    // Encrypt the password and username
    2.41 -  var userinfo = toJSONString({
    2.42 +  var userinfo = {
    2.43        username: username,
    2.44        password: password
    2.45 -    });
    2.46 +    };
    2.47 +    
    2.48 +  eval(setHook('login_build_userinfo'));
    2.49 +    
    2.50 +  userinfo = toJSONString(userinfo);
    2.51    var crypt_key_ba = hexToByteArray(crypt_key);
    2.52    userinfo = stringToByteArray(userinfo);
    2.53    
    2.54 @@ -957,10 +967,18 @@
    2.55  
    2.56  window.ajaxLoginGetErrorText = function(response)
    2.57  {
    2.58 +  if ( !response.error_code.match(/^[a-z0-9]+_[a-z0-9_]+$/) )
    2.59 +  {
    2.60 +    return response.error_code;
    2.61 +  }
    2.62    switch ( response.error_code )
    2.63    {
    2.64      default:
    2.65 -      return $lang.get('user_err_' + response.error_code);
    2.66 +      var ls = $lang.get('user_err_' + response.error_code);
    2.67 +      if ( ls == 'user_err_' + response.error_code )
    2.68 +        ls = $lang.get(response.error_code);
    2.69 +      
    2.70 +      return ls;
    2.71        break;
    2.72      case 'locked_out':
    2.73        if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' )
    2.74 @@ -1005,13 +1023,18 @@
    2.75          switch ( response.respawn_info.lockout_info.lockout_policy )
    2.76          {
    2.77            case 'captcha':
    2.78 -            base += $lang.get('user_err_invalid_credentials_lockout', { 
    2.79 +            base += $lang.get('user_err_invalid_credentials_lockout_captcha', { 
    2.80                  fails: response.respawn_info.lockout_info.lockout_fails,
    2.81                  lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
    2.82                  lockout_duration: response.respawn_info.lockout_info.lockout_duration
    2.83                });
    2.84              break;
    2.85            case 'lockout':
    2.86 +            base += $lang.get('user_err_invalid_credentials_lockout', { 
    2.87 +                fails: response.respawn_info.lockout_info.lockout_fails,
    2.88 +                lockout_threshold: response.respawn_info.lockout_info.lockout_threshold,
    2.89 +                lockout_duration: response.respawn_info.lockout_info.lockout_duration
    2.90 +              });
    2.91              break;
    2.92          }
    2.93        }
     3.1 --- a/includes/paths.php	Thu Feb 26 01:06:58 2009 -0500
     3.2 +++ b/includes/paths.php	Thu Feb 26 01:07:32 2009 -0500
     3.3 @@ -476,12 +476,12 @@
     3.4      foreach($k as $key)
     3.5      {
     3.6        $i++;
     3.7 -      $name = ( preg_match('/^[a-z0-9_]+$/', $key) ) ? $lang->get($key) : $key;
     3.8 +      $name = $lang->get($key);
     3.9        $ret .= "['".$name."', 'javascript:trees[0].toggle($i)', \n";
    3.10        foreach($this->admin_tree[$key] as $c)
    3.11        {
    3.12          $i++;
    3.13 -        $name = ( preg_match('/^[a-z0-9_]+$/', $key) ) ? $lang->get($c['name']) : $c['name'];
    3.14 +        $name = $lang->get($c['name']);
    3.15          if ( $c['icon'] && $c['icon'] != cdnPath . '/images/spacer.gif' )
    3.16          {
    3.17            if ( is_array($c['icon']) )
     4.1 --- a/includes/sessions.php	Thu Feb 26 01:06:58 2009 -0500
     4.2 +++ b/includes/sessions.php	Thu Feb 26 01:07:32 2009 -0500
     4.3 @@ -658,20 +658,10 @@
     4.4      
     4.5      if ( !defined('IN_ENANO_INSTALL') )
     4.6      {
     4.7 -      // Lockout stuff
     4.8 -      $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5;
     4.9 -      $duration  = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15;
    4.10 -      // convert to minutes
    4.11 -      $duration  = $duration * 60;
    4.12 -      $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
    4.13 -      
    4.14 -      $timestamp_cutoff = time() - $duration;
    4.15 -      $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
    4.16 -      $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;');
    4.17 -      $fails = $db->numrows();
    4.18 +      $locked_out = $this->get_lockout_info($lockout_data);
    4.19        
    4.20        $captcha_good = false;
    4.21 -      if ( $policy == 'captcha' && $captcha_hash && $captcha_code )
    4.22 +      if ( $lockout_data['lockout_policy'] == 'captcha' && $captcha_hash && $captcha_code )
    4.23        {
    4.24          // policy is captcha -- check if it's correct, and if so, bypass lockout check
    4.25          $real_code = $this->get_captcha($captcha_hash);
    4.26 @@ -682,7 +672,7 @@
    4.27        }
    4.28        if ( $policy != 'disable' && !$captcha_good )
    4.29        {
    4.30 -        if ( $fails >= $threshold )
    4.31 +        if ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] )
    4.32          {
    4.33            // ooh boy, somebody's in trouble ;-)
    4.34            $row = $db->fetchrow();
    4.35 @@ -690,12 +680,12 @@
    4.36            return array(
    4.37                'success' => false,
    4.38                'error' => 'locked_out',
    4.39 -              'lockout_threshold' => $threshold,
    4.40 -              'lockout_duration' => ( $duration / 60 ),
    4.41 -              'lockout_fails' => $fails,
    4.42 -              'lockout_policy' => $policy,
    4.43 -              'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ),
    4.44 -              'lockout_last_time' => $row['timestamp']
    4.45 +              'lockout_threshold' => $lockout_data['lockout_threshold'],
    4.46 +              'lockout_duration' => ( $lockout_data['lockout_duration'] ),
    4.47 +              'lockout_fails' => $lockout_data['lockout_fails'],
    4.48 +              'lockout_policy' => $lockout_data['lockout_policy'],
    4.49 +              'time_rem' => $lockout_data['lockout_time_rem'],
    4.50 +              'lockout_last_time' => $lockout_data['lockout_last_time']
    4.51              );
    4.52          }
    4.53        }
    4.54 @@ -729,19 +719,19 @@
    4.55                        . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\')');
    4.56        
    4.57        // Do we also need to increment the lockout countdown?
    4.58 -      if ( @$policy != 'disable' && !defined('IN_ENANO_INSTALL') )
    4.59 +      if ( @$lockout_data['lockout_policy'] != 'disable' && !defined('IN_ENANO_INSTALL') )
    4.60        {
    4.61          $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
    4.62          // increment fail count
    4.63          $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');');
    4.64 -        $fails++;
    4.65 +        $lockout_data['lockout_fails']++;
    4.66          return array(
    4.67              'success' => false,
    4.68 -            'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials',
    4.69 -            'lockout_threshold' => $threshold,
    4.70 -            'lockout_duration' => ( $duration / 60 ),
    4.71 -            'lockout_fails' => $fails,
    4.72 -            'lockout_policy' => $policy
    4.73 +            'error' => ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] ) ? 'locked_out' : 'invalid_credentials',
    4.74 +            'lockout_threshold' => $lockout_data['lockout_threshold'],
    4.75 +            'lockout_duration' => ( $lockout_data['lockout_duration'] ),
    4.76 +            'lockout_fails' => $lockout_data['lockout_fails'],
    4.77 +            'lockout_policy' => $lockout_data['lockout_policy']
    4.78            );
    4.79        }
    4.80        
    4.81 @@ -851,19 +841,19 @@
    4.82          $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')');
    4.83          
    4.84        // Do we also need to increment the lockout countdown?
    4.85 -      if ( !defined('IN_ENANO_INSTALL') && $policy != 'disable' )
    4.86 +      if ( !defined('IN_ENANO_INSTALL') && $lockout_data['lockout_policy'] != 'disable' )
    4.87        {
    4.88          $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
    4.89          // increment fail count
    4.90          $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');');
    4.91 -        $fails++;
    4.92 +        $lockout_data['lockout_fails']++;
    4.93          return array(
    4.94              'success' => false,
    4.95 -            'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials',
    4.96 -            'lockout_threshold' => $threshold,
    4.97 -            'lockout_duration' => ( $duration / 60 ),
    4.98 -            'lockout_fails' => $fails,
    4.99 -            'lockout_policy' => $policy
   4.100 +            'error' => ( $lockout_data['lockout_fails'] >= $lockout_data['lockout_threshold'] ) ? 'locked_out' : 'invalid_credentials',
   4.101 +            'lockout_threshold' => $lockout_data['lockout_threshold'],
   4.102 +            'lockout_duration' => ( $lockout_data['lockout_duration'] ),
   4.103 +            'lockout_fails' => $lockout_data['lockout_fails'],
   4.104 +            'lockout_policy' => $lockout_data['lockout_policy']
   4.105            );
   4.106        }
   4.107          
   4.108 @@ -1009,6 +999,49 @@
   4.109    }
   4.110    
   4.111    /**
   4.112 +   * Tells us if we're locked out from logging in or not.
   4.113 +   * @param reference will be filled with information regarding in-progress lockout
   4.114 +   * @return bool True if locked out, false otherwise
   4.115 +   */
   4.116 +  
   4.117 +  function get_lockout_info(&$lockdata)
   4.118 +  {
   4.119 +    global $db;
   4.120 +    
   4.121 +    // this has to be initialized to hide warnings
   4.122 +    $lockdata = null;
   4.123 +    
   4.124 +    // Query database for lockout info
   4.125 +    $locked_out = false;
   4.126 +    $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5;
   4.127 +    $duration  = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15;
   4.128 +    // convert to minutes
   4.129 +    $duration  = $duration * 60;
   4.130 +    $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
   4.131 +    if ( $policy != 'disable' )
   4.132 +    {
   4.133 +      $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
   4.134 +      $timestamp_cutoff = time() - $duration;
   4.135 +      $q = $this->sql('SELECT timestamp FROM ' . table_prefix . 'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;');
   4.136 +      $fails = $db->numrows();
   4.137 +      $row = $db->fetchrow();
   4.138 +      $locked_out = ( $fails >= $threshold );
   4.139 +      $lockdata = array(
   4.140 +          'locked_out' => $locked_out,
   4.141 +          'lockout_threshold' => $threshold,
   4.142 +          'lockout_duration' => ( $duration / 60 ),
   4.143 +          'lockout_fails' => $fails,
   4.144 +          'lockout_policy' => $policy,
   4.145 +          'lockout_last_time' => $row['timestamp'],
   4.146 +          'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ),
   4.147 +          'captcha' => ''
   4.148 +        );
   4.149 +      $db->free_result();
   4.150 +    }
   4.151 +    return $locked_out;
   4.152 +  }
   4.153 +  
   4.154 +  /**
   4.155     * Creates/restores a guest session
   4.156     * @todo implement real session management for guests
   4.157     */
   4.158 @@ -1038,7 +1071,7 @@
   4.159        @setlocale(LC_ALL, $lang->lang_code);
   4.160      }
   4.161      // make a CSRF token
   4.162 -    $this->csrf_token = sha1($_SERVER['REMOTE_ADDR'] . sha1($this->private_key));
   4.163 +    $this->csrf_token = hmac_sha1($_SERVER['REMOTE_ADDR'], sha1($this->private_key));
   4.164    }
   4.165    
   4.166    /**
   4.167 @@ -3821,34 +3854,7 @@
   4.168          
   4.169          $this->start();
   4.170          
   4.171 -        // Query database for lockout info
   4.172 -        $locked_out = false;
   4.173 -        // are we locked out?
   4.174 -        $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5;
   4.175 -        $duration  = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15;
   4.176 -        // convert to minutes
   4.177 -        $duration  = $duration * 60;
   4.178 -        $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
   4.179 -        if ( $policy != 'disable' )
   4.180 -        {
   4.181 -          $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
   4.182 -          $timestamp_cutoff = time() - $duration;
   4.183 -          $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;');
   4.184 -          $fails = $db->numrows();
   4.185 -          $row = $db->fetchrow();
   4.186 -          $locked_out = ( $fails >= $threshold );
   4.187 -          $lockdata = array(
   4.188 -              'locked_out' => $locked_out,
   4.189 -              'lockout_threshold' => $threshold,
   4.190 -              'lockout_duration' => ( $duration / 60 ),
   4.191 -              'lockout_fails' => $fails,
   4.192 -              'lockout_policy' => $policy,
   4.193 -              'lockout_last_time' => $row['timestamp'],
   4.194 -              'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ),
   4.195 -              'captcha' => ''
   4.196 -            );
   4.197 -          $db->free_result();
   4.198 -        }
   4.199 +        $locked_out = $this->get_lockout_info($lockdata);
   4.200          
   4.201          $response = array('mode' => 'build_box');
   4.202          $response['allow_diffiehellman'] = $dh_supported;
   4.203 @@ -3862,7 +3868,7 @@
   4.204          $response['locked_out'] = $locked_out;
   4.205          
   4.206          $response['lockout_info'] = $lockdata;
   4.207 -        if ( $policy == 'captcha' && $locked_out )
   4.208 +        if ( $lockdata['lockout_policy'] == 'captcha' && $locked_out )
   4.209          {
   4.210            $response['lockout_info']['captcha'] = $this->make_captcha();
   4.211          }
   4.212 @@ -3992,6 +3998,41 @@
   4.213          $username =& $userinfo['username'];
   4.214          $password =& $userinfo['password'];
   4.215          
   4.216 +        // At this point if any extra info was injected into the login data packet, we need to let plugins process it
   4.217 +        /**
   4.218 +         * Called upon processing an incoming login request. If you added anything to the userinfo object during the jshook
   4.219 +         * login_build_userinfo, that will be in the $userinfo array here. Expected return values are: true if your plugin has
   4.220 +         * not only succeeded but ALSO issued a session key (bypass the whole Enano builtin login process) and an associative array
   4.221 +         * with "mode" set to "error" and an error string in "error" to send an error back to the client. Any return value other
   4.222 +         * than these will be ignored.
   4.223 +         * @hook login_process_userdata_json
   4.224 +         */
   4.225 +        
   4.226 +        $code = $plugins->setHook('login_process_userdata_json');
   4.227 +        foreach ( $code as $cmd )
   4.228 +        {
   4.229 +          $result = eval($cmd);
   4.230 +          if ( $result === true )
   4.231 +          {
   4.232 +            return array(
   4.233 +                'mode' => 'login_success',
   4.234 +                'key' => ( $this->sid_super ) ? $this->sid_super : false
   4.235 +              );
   4.236 +          }
   4.237 +          else if ( is_array($result) )
   4.238 +          {
   4.239 +            if ( isset($result['mode']) && $result['mode'] === 'error' && isset($result['error']) )
   4.240 +            {
   4.241 +              return array(
   4.242 +                'mode' => 'login_failure',
   4.243 +                'error_code' => $result['error'],
   4.244 +                // Use this to provide a way to respawn the login box
   4.245 +                'respawn_info' => $this->process_login_request(array('mode' => 'getkey'))
   4.246 +              );
   4.247 +            }
   4.248 +          }
   4.249 +        }
   4.250 +        
   4.251          // If we're logging in with a temp password, attach to the login_password_reset hook to send our JSON response
   4.252          // A bit hackish since it just dies with the response :-(
   4.253          $plugins->attachHook('login_password_reset', '$this->process_login_request(array(\'mode\' => \'respond_password_reset\', \'user_id\' => $row[\'user_id\'], \'temp_password\' => $this->pk_encrypt($password)));');
     5.1 --- a/includes/template.php	Thu Feb 26 01:06:58 2009 -0500
     5.2 +++ b/includes/template.php	Thu Feb 26 01:07:32 2009 -0500
     5.3 @@ -1499,7 +1499,7 @@
     5.4      }
     5.5      
     5.6      // Full pathname of template file
     5.7 -    $tpl_file_fullpath = ENANO_ROOT . '/themes/' . $this->theme . '/' . $file;
     5.8 +    $tpl_file_fullpath = ( strstr($file, '/') ) ? $file : ENANO_ROOT . '/themes/' . $this->theme . '/' . $file;
     5.9      
    5.10      // Make sure the template even exists
    5.11      if ( !is_file($tpl_file_fullpath) )
     6.1 --- a/plugins/SpecialUserFuncs.php	Thu Feb 26 01:06:58 2009 -0500
     6.2 +++ b/plugins/SpecialUserFuncs.php	Thu Feb 26 01:07:32 2009 -0500
     6.3 @@ -264,6 +264,9 @@
     6.4          $errstring = $lang->get('user_err_locked_out', array('plural' => $s, 'captcha_blurb' => $captcha_string, 'time_rem' => $time_rem));
     6.5          
     6.6          break;
     6.7 +      default:
     6.8 +        $errstring = $lang->get($errstring);
     6.9 +        break;
    6.10      }
    6.11      echo '<div class="error-box-mini">'.$errstring.'</div>';
    6.12    }
    6.13 @@ -343,6 +346,11 @@
    6.14           }
    6.15           ?>
    6.16           <?php
    6.17 +         $code = $plugins->setHook('login_form_html');
    6.18 +         foreach ( $code as $cmd )
    6.19 +         {
    6.20 +           eval($cmd);
    6.21 +         }
    6.22           if ( $level <= USER_LEVEL_MEMBER )
    6.23           {
    6.24             // "remember me" switch
    6.25 @@ -504,7 +512,53 @@
    6.26        return false;
    6.27      }
    6.28      
    6.29 -    $result = $session->login_without_crypto($_POST['username'], $password, false, intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
    6.30 +    // These are to allow auth plugins to work universally between JSON and HTML login forms
    6.31 +    $userinfo =& $_POST;
    6.32 +    $req = array(
    6.33 +      'level' => intval($_POST['auth_level']),
    6.34 +      'remember' => isset($_POST['remember'])
    6.35 +    );
    6.36 +    
    6.37 +    // At this point if any extra fields were injected into the login form, we need to let plugins process it
    6.38 +    
    6.39 +    /**
    6.40 +     * Called upon processing an incoming login request from the plain HTML login form.. If you added anything to the form,
    6.41 +     * that will be in the $userinfo array here and on $_POST. Expected return values are: true if your plugin has
    6.42 +     * not only succeeded but ALSO issued a session key (bypass the whole Enano builtin login process) and an associative array
    6.43 +     * with "mode" set to "error" and an error string in "error" to send an error back to the client. Any return value other
    6.44 +     * than these will be ignored.
    6.45 +     * @hook login_process_userdata_json
    6.46 +     */
    6.47 +     
    6.48 +    $skip_normal_login = false;
    6.49 +    
    6.50 +    $code = $plugins->setHook('login_process_userdata_json');
    6.51 +    foreach ( $code as $cmd )
    6.52 +    {
    6.53 +      $result = eval($cmd);
    6.54 +      if ( $result === true )
    6.55 +      {
    6.56 +        $skip_normal_login = true;
    6.57 +        $result = array('success' => true);
    6.58 +        break;
    6.59 +      }
    6.60 +      else if ( is_array($result) )
    6.61 +      {
    6.62 +        if ( isset($result['mode']) && $result['mode'] === 'error' && isset($result['error']) )
    6.63 +        {
    6.64 +          $__login_status = array(
    6.65 +            'mode' => 'error',
    6.66 +            'error' => $result['error']
    6.67 +          );
    6.68 +          return false;
    6.69 +        }
    6.70 +      }
    6.71 +    }
    6.72 +    
    6.73 +    if ( !$skip_normal_login )
    6.74 +    {
    6.75 +      $result = $session->login_without_crypto($_POST['username'], $password, false, intval($_POST['auth_level']), $captcha_hash, $captcha_code, isset($_POST['remember']));
    6.76 +    }
    6.77     
    6.78      if($result['success'])
    6.79      {