Changeset 18889


Ignore:
Timestamp:
Nov 2, 2012, 2:59:07 PM (11 years ago)
Author:
plg
Message:

feature 2727: improve password security with the use of PasswordHash class.
This class performs salt and multiple iterations. Already used in Wordpress,
Drupal, phpBB and many other web applications.

$confpass_convert is replaced by $confpassword_hash + $confpassword_verify

Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/include/functions_upgrade.php

    r15678 r18889  
    248248  $row = pwg_db_fetch_assoc(pwg_query($query));
    249249
    250   if (!isset($conf['pass_convert']))
    251   {
    252     $conf['pass_convert'] = create_function('$s', 'return md5($s);');
    253   }
    254 
    255   if ($row['password'] != $conf['pass_convert']($password))
     250  if (!$conf['password_verify']($password, $row['password']))
    256251  {
    257252    array_push($page['errors'], l10n('Invalid password!'));
  • trunk/include/config_default.inc.php

    r18850 r18889  
    507507  );
    508508
    509 // pass_convert : function to crypt or hash the clear user password to store
    510 // it in the database
    511 $conf['pass_convert'] = create_function('$s', 'return md5($s);');
     509// password_hash: function hash the clear user password to store it in the
     510// database. The function takes only one parameter: the clear password.
     511$conf['password_hash'] = 'pwg_password_hash';
     512
     513// password_verify: function that checks the password against its hash. The
     514// function takes 2 mandatory parameter : clear password, hashed password +
     515// an optional parameter user_id. The user_id is used to update the password
     516// with the new hash introduced in Piwigo 2.5. See function
     517// pwg_password_verify in include/functions_user.inc.php
     518$conf['password_verify'] = 'pwg_password_verify';
    512519
    513520// guest_id : id of the anonymous user
    514521$conf['guest_id'] = 2;
     522
    515523// default_user_id : id of user used for default value
    516524$conf['default_user_id'] = $conf['guest_id'];
  • trunk/include/functions_user.inc.php

    r18629 r18889  
    183183        $conf['user_fields']['id'] => $next_id,
    184184        $conf['user_fields']['username'] => pwg_db_real_escape_string($login),
    185         $conf['user_fields']['password'] => $conf['pass_convert']($password),
     185        $conf['user_fields']['password'] => $conf['password_hash']($password),
    186186        $conf['user_fields']['email'] => $mail_address
    187187        );
     
    10961096
    10971097/**
     1098 * hashes a password, with the PasswordHash class from phpass security
     1099 * library. We use an "pwg_" prefix because function password_hash is
     1100 * planned for PHP 5.5. Code inspired from Wordpress.
     1101 *
     1102 * @param string $password Plain text user password to hash
     1103 * @return string The hash string of the password
     1104 */
     1105function pwg_password_hash($password)
     1106{
     1107  global $pwg_hasher;
     1108
     1109  if (empty($pwg_hasher))
     1110  {
     1111    require_once(PHPWG_ROOT_PATH.'include/passwordhash.class.php');
     1112   
     1113    // We use the portable hash feature from phpass because we can't be sure
     1114    // Piwigo runs on PHP 5.3+ (and won't run on an older version in the
     1115    // future)
     1116    $pwg_hasher = new PasswordHash(13, true);
     1117  }
     1118 
     1119  return $pwg_hasher->HashPassword($password);
     1120}
     1121
     1122/**
     1123 * Verifies a password, with the PasswordHash class from phpass security
     1124 * library. We use an "pwg_" prefix because function password_verify is
     1125 * planned for PHP 5.5. Code inspired from Wordpress.
     1126 *
     1127 * @param string $password Plain text user password to hash
     1128 * @param string $hash may be md5 or phpass hashed password
     1129 * @param integer $account_id only useful to update password hash from md5 to phpass
     1130 * @return string The hash string of the password
     1131 */
     1132function pwg_password_verify($password, $hash, $user_id=null)
     1133{
     1134  global $conf, $pwg_hasher;
     1135
     1136  // If the hash is still md5...
     1137  if (strlen($hash) <= 32)
     1138  {
     1139    $check = ($hash == md5($password));
     1140   
     1141    if ($check and isset($user_id) and !$conf['external_authentification'])
     1142    {
     1143      // Rehash using new hash.
     1144      $hash = pwg_password_hash($password);
     1145
     1146      single_update(
     1147        USERS_TABLE,
     1148        array('password' => $hash),
     1149        array('id' => $user_id)
     1150        );
     1151    }
     1152  }
     1153
     1154  // If the stored hash is longer than an MD5, presume the
     1155  // new style phpass portable hash.
     1156  if (empty($pwg_hasher))
     1157  {
     1158    require_once(PHPWG_ROOT_PATH.'include/passwordhash.class.php');
     1159   
     1160    // We use the portable hash feature
     1161    $pwg_hasher = new PasswordHash(13, true);
     1162  }
     1163
     1164  return $pwg_hasher->CheckPassword($password, $hash);
     1165}
     1166
     1167/**
    10981168 * Tries to login a user given username and password (must be MySql escaped)
    10991169 * return true on success
     
    11131183;';
    11141184  $row = pwg_db_fetch_assoc(pwg_query($query));
    1115   if ($row['password'] == $conf['pass_convert']($password))
     1185  if ($conf['password_verify']($password, $row['password'], $row['id']))
    11161186  {
    11171187    log_user($row['id'], $remember_me);
  • trunk/install/piwigo_structure-mysql.sql

    r18164 r18889  
    442442  `id` smallint(5) NOT NULL auto_increment,
    443443  `username` varchar(100) binary NOT NULL default '',
    444   `password` varchar(32) default NULL,
     444  `password` varchar(255) default NULL,
    445445  `mail_address` varchar(255) default NULL,
    446446  PRIMARY KEY  (`id`),
  • trunk/password.php

    r18700 r18889  
    222222  single_update(
    223223    USERS_TABLE,
    224     array($conf['user_fields']['password'] => $conf['pass_convert']($_POST['use_new_pwd'])),
     224    array($conf['user_fields']['password'] => $conf['password_hash']($_POST['use_new_pwd'])),
    225225    array($conf['user_fields']['id'] => $user_id)
    226226    );
  • trunk/profile.php

    r15578 r18889  
    178178      list($current_password) = pwg_db_fetch_row(pwg_query($query));
    179179
    180       if ($conf['pass_convert']($_POST['password']) != $current_password)
     180      if (!$conf['password_verify']($_POST['password'], $current_password))
    181181      {
    182182        $errors[] = l10n('Current password is wrong');
     
    203203      {
    204204        array_push($fields, $conf['user_fields']['password']);
    205         // password is encrpyted with function $conf['pass_convert']
    206         $data{$conf['user_fields']['password']} = $conf['pass_convert']($_POST['use_new_pwd']);
     205        // password is hashed with function $conf['password_hash']
     206        $data{$conf['user_fields']['password']} = $conf['password_hash']($_POST['use_new_pwd']);
    207207      }
    208208     
Note: See TracChangeset for help on using the changeset viewer.