[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/includes/auth/ -> auth_db.php (source)

   1  <?php
   2  /**
   3  * Database auth plug-in for phpBB3
   4  *
   5  * Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him.
   6  *
   7  * This is for authentication via the integrated user table
   8  *
   9  * @package login
  10  * @version $Id$
  11  * @copyright (c) 2005 phpBB Group
  12  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  13  *
  14  */
  15  
  16  /**
  17  * @ignore
  18  */
  19  if (!defined('IN_PHPBB'))
  20  {
  21      exit;
  22  }
  23  
  24  /**
  25  * Login function
  26  *
  27  * @param string $username
  28  * @param string $password
  29  * @param string $ip            IP address the login is taking place from. Used to
  30  *                            limit the number of login attempts per IP address.
  31  * @param string $browser    The user agent used to login
  32  * @param string $forwarded_for X_FORWARDED_FOR header sent with login request
  33  * @return array                A associative array of the format
  34  *                            array(
  35  *                                'status' => status constant
  36  *                                'error_msg' => string
  37  *                                'user_row' => array
  38  *                            )
  39  */
  40  function login_db($username, $password, $ip = '', $browser = '', $forwarded_for = '')
  41  {
  42      global $db, $config;
  43  
  44      // do not allow empty password
  45      if (!$password)
  46      {
  47          return array(
  48              'status'    => LOGIN_ERROR_PASSWORD,
  49              'error_msg'    => 'NO_PASSWORD_SUPPLIED',
  50              'user_row'    => array('user_id' => ANONYMOUS),
  51          );
  52      }
  53  
  54      if (!$username)
  55      {
  56          return array(
  57              'status'    => LOGIN_ERROR_USERNAME,
  58              'error_msg'    => 'LOGIN_ERROR_USERNAME',
  59              'user_row'    => array('user_id' => ANONYMOUS),
  60          );
  61      }
  62  
  63      $username_clean = utf8_clean_string($username);
  64  
  65      $sql = 'SELECT user_id, username, user_password, user_passchg, user_pass_convert, user_email, user_type, user_login_attempts
  66          FROM ' . USERS_TABLE . "
  67          WHERE username_clean = '" . $db->sql_escape($username_clean) . "'";
  68      $result = $db->sql_query($sql);
  69      $row = $db->sql_fetchrow($result);
  70      $db->sql_freeresult($result);
  71  
  72      if (($ip && !$config['ip_login_limit_use_forwarded']) ||
  73          ($forwarded_for && $config['ip_login_limit_use_forwarded']))
  74      {
  75          $sql = 'SELECT COUNT(*) AS attempts
  76              FROM ' . LOGIN_ATTEMPT_TABLE . '
  77              WHERE attempt_time > ' . (time() - (int) $config['ip_login_limit_time']);
  78          if ($config['ip_login_limit_use_forwarded'])
  79          {
  80              $sql .= " AND attempt_forwarded_for = '" . $db->sql_escape($forwarded_for) . "'";
  81          }
  82          else
  83          {
  84              $sql .= " AND attempt_ip = '" . $db->sql_escape($ip) . "' ";
  85          }
  86  
  87          $result = $db->sql_query($sql);
  88          $attempts = (int) $db->sql_fetchfield('attempts');
  89          $db->sql_freeresult($result);
  90  
  91          $attempt_data = array(
  92              'attempt_ip'            => $ip,
  93              'attempt_browser'        => trim(substr($browser, 0, 149)),
  94              'attempt_forwarded_for'    => $forwarded_for,
  95              'attempt_time'            => time(),
  96              'user_id'                => ($row) ? (int) $row['user_id'] : 0,
  97              'username'                => $username,
  98              'username_clean'        => $username_clean,
  99          );
 100          $sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $db->sql_build_array('INSERT', $attempt_data);
 101          $result = $db->sql_query($sql);
 102      }
 103      else
 104      {
 105          $attempts = 0;
 106      }
 107  
 108      if (!$row)
 109      {
 110          if ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max'])
 111          {
 112              return array(
 113                  'status'        => LOGIN_ERROR_ATTEMPTS,
 114                  'error_msg'        => 'LOGIN_ERROR_ATTEMPTS',
 115                  'user_row'        => array('user_id' => ANONYMOUS),
 116              );
 117          }
 118  
 119          return array(
 120              'status'    => LOGIN_ERROR_USERNAME,
 121              'error_msg'    => 'LOGIN_ERROR_USERNAME',
 122              'user_row'    => array('user_id' => ANONYMOUS),
 123          );
 124      }
 125  
 126      $show_captcha = ($config['max_login_attempts'] && $row['user_login_attempts'] >= $config['max_login_attempts']) ||
 127          ($config['ip_login_limit_max'] && $attempts >= $config['ip_login_limit_max']);
 128  
 129      // If there are too much login attempts, we need to check for an confirm image
 130      // Every auth module is able to define what to do by itself...
 131      if ($show_captcha)
 132      {
 133          // Visual Confirmation handling
 134          if (!class_exists('phpbb_captcha_factory'))
 135          {
 136              global $phpbb_root_path, $phpEx;
 137              include ($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
 138          }
 139  
 140          $captcha =& phpbb_captcha_factory::get_instance($config['captcha_plugin']);
 141          $captcha->init(CONFIRM_LOGIN);
 142          $vc_response = $captcha->validate($row);
 143          if ($vc_response)
 144          {
 145              return array(
 146                  'status'        => LOGIN_ERROR_ATTEMPTS,
 147                  'error_msg'        => 'LOGIN_ERROR_ATTEMPTS',
 148                  'user_row'        => $row,
 149              );
 150          }
 151          else
 152          {
 153              $captcha->reset();
 154          }
 155  
 156      }
 157  
 158      // If the password convert flag is set we need to convert it
 159      if ($row['user_pass_convert'])
 160      {
 161          // in phpBB2 passwords were used exactly as they were sent, with addslashes applied
 162          $password_old_format = isset($_REQUEST['password']) ? (string) $_REQUEST['password'] : '';
 163          $password_old_format = (!STRIP) ? addslashes($password_old_format) : $password_old_format;
 164          $password_new_format = '';
 165  
 166          set_var($password_new_format, stripslashes($password_old_format), 'string', true);
 167  
 168          if ($password == $password_new_format)
 169          {
 170              if (!function_exists('utf8_to_cp1252'))
 171              {
 172                  global $phpbb_root_path, $phpEx;
 173                  include($phpbb_root_path . 'includes/utf/data/recode_basic.' . $phpEx);
 174              }
 175  
 176              // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding
 177              // plain md5 support left in for conversions from other systems.
 178              if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password'])))
 179                  || (strlen($row['user_password']) == 32  && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password'])))
 180              {
 181                  $hash = phpbb_hash($password_new_format);
 182  
 183                  // Update the password in the users table to the new format and remove user_pass_convert flag
 184                  $sql = 'UPDATE ' . USERS_TABLE . '
 185                      SET user_password = \'' . $db->sql_escape($hash) . '\',
 186                          user_pass_convert = 0
 187                      WHERE user_id = ' . $row['user_id'];
 188                  $db->sql_query($sql);
 189  
 190                  $row['user_pass_convert'] = 0;
 191                  $row['user_password'] = $hash;
 192              }
 193              else
 194              {
 195                  // Although we weren't able to convert this password we have to
 196                  // increase login attempt count to make sure this cannot be exploited
 197                  $sql = 'UPDATE ' . USERS_TABLE . '
 198                      SET user_login_attempts = user_login_attempts + 1
 199                      WHERE user_id = ' . (int) $row['user_id'] . '
 200                          AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
 201                  $db->sql_query($sql);
 202  
 203                  return array(
 204                      'status'        => LOGIN_ERROR_PASSWORD_CONVERT,
 205                      'error_msg'        => 'LOGIN_ERROR_PASSWORD_CONVERT',
 206                      'user_row'        => $row,
 207                  );
 208              }
 209          }
 210      }
 211  
 212      // Check password ...
 213      if (!$row['user_pass_convert'] && phpbb_check_hash($password, $row['user_password']))
 214      {
 215          // Check for old password hash...
 216          if (strlen($row['user_password']) == 32)
 217          {
 218              $hash = phpbb_hash($password);
 219  
 220              // Update the password in the users table to the new format
 221              $sql = 'UPDATE ' . USERS_TABLE . "
 222                  SET user_password = '" . $db->sql_escape($hash) . "',
 223                      user_pass_convert = 0
 224                  WHERE user_id = {$row['user_id']}";
 225              $db->sql_query($sql);
 226  
 227              $row['user_password'] = $hash;
 228          }
 229  
 230          $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
 231              WHERE user_id = ' . $row['user_id'];
 232          $db->sql_query($sql);
 233  
 234          if ($row['user_login_attempts'] != 0)
 235          {
 236              // Successful, reset login attempts (the user passed all stages)
 237              $sql = 'UPDATE ' . USERS_TABLE . '
 238                  SET user_login_attempts = 0
 239                  WHERE user_id = ' . $row['user_id'];
 240              $db->sql_query($sql);
 241          }
 242  
 243          // User inactive...
 244          if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
 245          {
 246              return array(
 247                  'status'        => LOGIN_ERROR_ACTIVE,
 248                  'error_msg'        => 'ACTIVE_ERROR',
 249                  'user_row'        => $row,
 250              );
 251          }
 252  
 253          // Successful login... set user_login_attempts to zero...
 254          return array(
 255              'status'        => LOGIN_SUCCESS,
 256              'error_msg'        => false,
 257              'user_row'        => $row,
 258          );
 259      }
 260  
 261      // Password incorrect - increase login attempts
 262      $sql = 'UPDATE ' . USERS_TABLE . '
 263          SET user_login_attempts = user_login_attempts + 1
 264          WHERE user_id = ' . (int) $row['user_id'] . '
 265              AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
 266      $db->sql_query($sql);
 267  
 268      // Give status about wrong password...
 269      return array(
 270          'status'        => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
 271          'error_msg'        => ($show_captcha) ? 'LOGIN_ERROR_ATTEMPTS' : 'LOGIN_ERROR_PASSWORD',
 272          'user_row'        => $row,
 273      );
 274  }
 275  
 276  ?>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1