Commit ca7eb873 by Daniel Ruf

use password_hash and password_verify

parent 3fd0654f
......@@ -25,7 +25,7 @@
exit;
}
define('QA_DB_VERSION_CURRENT', 61);
define('QA_DB_VERSION_CURRENT', 62);
function qa_db_user_column_type_verify()
......@@ -107,7 +107,8 @@
'avatarwidth' => 'SMALLINT UNSIGNED', // pixel width of stored avatar
'avatarheight' => 'SMALLINT UNSIGNED', // pixel height of stored avatar
'passsalt' => 'BINARY(16)', // salt used to calculate passcheck - null if no password set for direct login
'passcheck' => 'BINARY(20)', // checksum from password and passsalt - null if no passowrd set for direct login
'passcheck' => 'BINARY(20)', // checksum from password and passsalt - null if no password set for direct login
'passhash' => 'CHAR(60) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL', // password_hash
'level' => 'TINYINT UNSIGNED NOT NULL', // basic, editor, admin, etc...
'loggedin' => 'DATETIME NOT NULL', // time of last login
'loginip' => 'INT UNSIGNED NOT NULL', // INET_ATON of IP address of last login
......@@ -1461,6 +1462,11 @@
// Up to here: Verison 1.8 alpha
case 62:
qa_db_upgrade_query('ALTER TABLE ^users ADD COLUMN passhash '.$definitions['users']['passhash'].' AFTER passcheck');
qa_db_upgrade_query($locktablesquery);
break;
}
qa_db_set_db_version($newversion);
......
......@@ -1181,7 +1181,7 @@
{
return array(
'columns' => array(
'^users.userid', 'passsalt', 'passcheck' => 'HEX(passcheck)', 'email', 'level', 'emailcode', 'handle',
'^users.userid', 'passsalt', 'passcheck' => 'HEX(passcheck)', 'passhash', 'email', 'level', 'emailcode', 'handle',
'created' => 'UNIX_TIMESTAMP(created)', 'sessioncode', 'sessionsource', 'flags', 'loggedin' => 'UNIX_TIMESTAMP(loggedin)',
'loginip' => 'INET_NTOA(loginip)', 'written' => 'UNIX_TIMESTAMP(written)', 'writeip' => 'INET_NTOA(writeip)',
'avatarblobid' => 'BINARY avatarblobid', // cast to BINARY due to MySQL bug which renders it signed in a union
......
......@@ -36,6 +36,10 @@
return sha1(substr($salt, 0, 8).$password.substr($salt, 8));
}
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
function qa_db_user_create($email, $password, $handle, $level, $ip)
/*
......@@ -47,9 +51,9 @@
$salt=isset($password) ? qa_random_alphanum(16) : null;
qa_db_query_sub(
'INSERT INTO ^users (created, createip, email, passsalt, passcheck, level, handle, loggedin, loginip) '.
'VALUES (NOW(), COALESCE(INET_ATON($), 0), $, $, UNHEX($), #, $, NOW(), COALESCE(INET_ATON($), 0))',
$ip, $email, $salt, isset($password) ? qa_db_calc_passcheck($password, $salt) : null, (int)$level, $handle, $ip
'INSERT INTO ^users (created, createip, email, passsalt, passhash, level, handle, loggedin, loginip) '.
'VALUES (NOW(), COALESCE(INET_ATON($), 0), $, $, $, #, $, NOW(), COALESCE(INET_ATON($), 0))',
$ip, $email, $salt, isset($password) ? password_hash($password, PASSWORD_BCRYPT) : null, (int)$level, $handle, $ip
);
return qa_db_last_insert_id();
......@@ -154,11 +158,9 @@
require_once QA_INCLUDE_DIR.'util/string.php';
$salt=qa_random_alphanum(16);
qa_db_query_sub(
'UPDATE ^users SET passsalt=$, passcheck=UNHEX($) WHERE userid=$',
$salt, qa_db_calc_passcheck($password, $salt), $userid
'UPDATE ^users SET passhash=$, passsalt=NULL, passcheck=NULL WHERE userid=$',
password_hash($password, PASSWORD_BCRYPT), $userid
);
}
......
......@@ -55,7 +55,8 @@
$changehandle=qa_opt('allow_change_usernames') || ((!$userpoints['qposts']) && (!$userpoints['aposts']) && (!$userpoints['cposts']));
$doconfirms=qa_opt('confirm_user_emails') && ($useraccount['level']<QA_USER_LEVEL_EXPERT);
$isconfirmed=($useraccount['flags'] & QA_USER_FLAGS_EMAIL_CONFIRMED) ? true : false;
$haspassword=isset($useraccount['passsalt']) && isset($useraccount['passcheck']);
$haspasswordold=isset($useraccount['passsalt']) && isset($useraccount['passcheck']);
$haspassword=isset($useraccount['passhash']);
$permit_error = qa_user_permit_error();
$isblocked = $permit_error !== false;
$pending_confirmation = $doconfirms && $permit_error == 'confirm';
......@@ -205,7 +206,10 @@
else {
$errors = array();
if ($haspassword && (strtolower(qa_db_calc_passcheck($inoldpassword, $useraccount['passsalt'])) != strtolower($useraccount['passcheck'])))
if (
($haspasswordold && (strtolower(qa_db_calc_passcheck($inoldpassword, $useraccount['passsalt'])) != strtolower($useraccount['passcheck']))) ||
(!$haspasswordold && $haspassword && !password_verify($inoldpassword,$useraccount['passhash']))
)
$errors['oldpassword'] = qa_lang('users/password_wrong');
$useraccount['password'] = $inoldpassword;
......
......@@ -68,9 +68,16 @@
$inuserid=$matchusers[0];
$userinfo=qa_db_select_with_pending(qa_db_user_account_selectspec($inuserid, true));
if (strtolower(qa_db_calc_passcheck($inpassword, $userinfo['passsalt'])) == strtolower($userinfo['passcheck'])) { // login and redirect
require_once QA_INCLUDE_DIR.'app/users.php';
$haspassword=isset($userinfo['passhash']);
$haspasswordold=isset($userinfo['passsalt']) && isset($userinfo['passcheck']);
if (
($haspasswordold && strtolower(qa_db_calc_passcheck($inpassword, $userinfo['passsalt'])) == strtolower($userinfo['passcheck'])) ||
($haspassword && password_verify($inpassword,$userinfo['passhash']))
){ // login and redirect
require_once QA_INCLUDE_DIR.'app/users.php';
if($haspasswordold) qa_db_user_set_password($inuserid, $inpassword);
qa_set_logged_in_user($inuserid, $userinfo['handle'], !empty($inremember));
$topath=qa_get('to');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment