From: Hypolite Petovan Date: Sun, 21 Jan 2018 03:29:03 +0000 (-0500) Subject: Use password_hash() for passwords X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=b0a764b14c2f2798f7eb223e58d47530f80609c1;p=friendica.git Use password_hash() for passwords - Use legacy_password to update double-hashed passwords --- diff --git a/src/Model/User.php b/src/Model/User.php index 382ec62cc2..bbe424ecbc 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -112,7 +112,7 @@ class User if (is_object($user_info)) { $user = (array) $user_info; } elseif (is_int($user_info)) { - $user = dba::selectFirst('user', ['uid', 'password'], + $user = dba::selectFirst('user', ['uid', 'password', 'legacy_password'], [ 'uid' => $user_info, 'blocked' => 0, @@ -122,7 +122,7 @@ class User ] ); } elseif (is_string($user_info)) { - $user = dba::fetch_first('SELECT `uid`, `password` + $user = dba::fetch_first('SELECT `uid`, `password`, `legacy_password` FROM `user` WHERE (`email` = ? OR `username` = ? OR `nickname` = ?) AND `blocked` = 0 @@ -138,17 +138,29 @@ class User $user = $user_info; } - if (!DBM::is_result($user) || !isset($user['uid']) || !isset($user['password'])) { - return false; + if (!DBM::is_result($user) + || !isset($user['uid']) + || !isset($user['password']) + || !isset($user['legacy_password']) + ) { + throw new Exception('Not enough information to authenticate'); } - $password_hashed = self::hashPassword($password); + if ($user['legacy_password']) { + if (password_verify(self::hashPasswordLegacy($password), $user['password'])) { + self::updatePassword($user['uid'], $password); - if ($password_hashed !== $user['password']) { - return false; + return $user['uid']; + } + } elseif (password_verify($password, $user['password'])) { + if (password_needs_rehash($user['password'], PASSWORD_DEFAULT)) { + self::updatePassword($user['uid'], $password); + } + + return $user['uid']; } - return $user['uid']; + return false; } /** @@ -162,16 +174,27 @@ class User } /** - * Global user password hashing function + * Legacy hashing function, kept for password migration purposes * * @param string $password * @return string */ - private static function hashPassword($password) + private static function hashPasswordLegacy($password) { return hash('whirlpool', $password); } + /** + * Global user password hashing function + * + * @param string $password + * @return string + */ + public static function hashPassword($password) + { + return password_hash($password, PASSWORD_DEFAULT); + } + /** * Updates a user row with a new plaintext password * @@ -197,7 +220,8 @@ class User $fields = [ 'password' => $pasword_hashed, 'pwdreset' => null, - 'pwdreset_time' => null + 'pwdreset_time' => null, + 'legacy_password' => false ]; return dba::update('user', $fields, ['uid' => $uid]); } diff --git a/src/Util/ExAuth.php b/src/Util/ExAuth.php index 847059d6d7..8940c02055 100644 --- a/src/Util/ExAuth.php +++ b/src/Util/ExAuth.php @@ -226,7 +226,7 @@ class ExAuth if ($a->get_hostname() == $aCommand[2]) { $this->writeLog(LOG_INFO, 'internal auth for ' . $sUser . '@' . $aCommand[2]); - $aUser = dba::selectFirst('user', ['uid', 'password'], ['nickname' => $sUser]); + $aUser = dba::selectFirst('user', ['uid', 'password', 'legacy_password'], ['nickname' => $sUser]); if (DBM::is_result($aUser)) { $uid = $aUser['uid']; $success = User::authenticate($aUser, $aCommand[3]);