Support for storing salted passwords

To upgrade existing databases:

ALTER TABLE Users ADD Salt CHAR(32) NOT NULL DEFAULT '';

Signed-off-by: Loui Chang <louipc.ist@gmail.com>
This commit is contained in:
Denis 2010-04-05 09:41:30 -04:00 committed by Loui Chang
parent 5b8b0757f4
commit 290c436046
4 changed files with 74 additions and 21 deletions

View file

@ -265,17 +265,14 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
} else {
if ($TYPE == "new") {
# no errors, go ahead and create the unprivileged user
# md5hash the password
$P = md5($P);
$q = "INSERT INTO Users (AccountTypeID, Suspended, Username, Email, ";
$q.= "Passwd, RealName, LangPreference, IRCNick, NewPkgNotify) ";
$q.= "VALUES (1, 0, '".mysql_real_escape_string($U)."'";
$q.= ", '".mysql_real_escape_string($E)."'";
$q.= ", '".mysql_real_escape_string($P)."'";
$q.= ", '".mysql_real_escape_string($R)."'";
$q.= ", '".mysql_real_escape_string($L)."'";
$q.= ", '".mysql_real_escape_string($I)."'";
$salt = generate_salt();
$P = salted_hash($P, $salt);
$escaped = array_map(mysql_real_escape_string,
array($U, $E, $P, $salt, $R, $L, $I));
$q = "INSERT INTO Users (" .
"AccountTypeID, Suspended, Username, Email, Passwd, Salt" .
", RealName, LangPreference, IRCNick, NewPkgNotify) " .
"VALUES (1, 0, '" . implode("', '", $escaped) . "'";
if ($N) {
$q.= ", 1)";
} else {
@ -298,7 +295,6 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
} else {
# no errors, go ahead and modify the user account
# md5 hash the password
$q = "UPDATE Users SET ";
$q.= "Username = '".mysql_real_escape_string($U)."'";
if ($T) {
@ -311,7 +307,9 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
}
$q.= ", Email = '".mysql_real_escape_string($E)."'";
if ($P) {
$q.= ", Passwd = '".mysql_real_escape_string(md5($P))."'";
$salt = generate_salt();
$hash = salted_hash($P, $salt);
$q .= ", Passwd = '$hash', Salt = '$salt'";
}
$q.= ", RealName = '".mysql_real_escape_string($R)."'";
$q.= ", LangPreference = '".mysql_real_escape_string($L)."'";
@ -738,14 +736,34 @@ function valid_passwd( $userID, $passwd )
{
if ( strlen($passwd) > 0 ) {
$dbh = db_connect();
$q = "SELECT ID FROM Users".
" WHERE ID = '$userID'" .
" AND Passwd = '" . md5($passwd) . "'";
$result = mysql_fetch_row(db_query($q, $dbh));
if ($result[0]) {
# Is it the right password?
return true;
# get salt for this user
$salt = get_salt($userID);
if ($salt) {
# use salt
$passwd_q = "SELECT ID FROM Users" .
" WHERE ID = '$userID' AND Passwd = '" .
salted_hash($passwd, $salt) . "'";
$passwd_result = mysql_fetch_row(db_query($passwd_q, $dbh));
if ($passwd_result[0]) {
return true;
}
} else {
# check without salt
$nosalt_q = "SELECT ID FROM Users".
" WHERE ID = '$userID'" .
" AND Passwd = '" . md5($passwd) . "'";
$nosalt_result = mysql_fetch_row(db_query($nosalt_q, $dbh));
if ($nosalt_result[0]) {
# password correct, but salt it first
if (!save_salt($userID, $passwd)) {
trigger_error("Unable to salt user's password;" .
" ID $userID", E_USER_WARNING);
return false;
}
return true;
}
}
}
return false;

View file

@ -455,3 +455,34 @@ function mkurl($append) {
return substr($out, 5);
}
function get_salt($user_id)
{
$dbh = db_connect();
$salt_q = "SELECT Salt FROM Users WHERE ID = '$user_id'";
$salt_result = mysql_fetch_row(db_query($salt_q, $dbh));
return $salt_result[0];
}
function save_salt($user_id, $passwd)
{
$dbh = db_connect();
$salt = generate_salt();
$hash = salted_hash($passwd, $salt);
$salting_q = "UPDATE Users SET Salt = '$salt'" .
", Passwd = '$hash' WHERE ID = '$user_id'";
return db_query($salting_q, $dbh);
}
function generate_salt()
{
return md5(uniqid(rand(), true));
}
function salted_hash($passwd, $salt)
{
if (strlen($salt) != 32) {
trigger_error('Salt does not look like an md5 hash', E_USER_WARNING);
}
return md5($salt . $passwd);
}