summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis <d.v.kobozev@gmail.com>2010-04-05 15:41:30 +0200
committerLoui Chang <louipc.ist@gmail.com>2010-04-17 22:50:24 +0200
commit290c436046327d9f04b7d12b5fda19f4dc14f574 (patch)
tree93c9ca0485e5ffb7d87460fbb78218c5f03e830f
parent5b8b0757f4f938f86bed86ae56fa3511704e006f (diff)
downloadaur-290c436046327d9f04b7d12b5fda19f4dc14f574.tar.gz
aur-290c436046327d9f04b7d12b5fda19f4dc14f574.tar.xz
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>
-rw-r--r--support/schema/aur-schema.sql1
-rw-r--r--web/html/passreset.php5
-rw-r--r--web/lib/acctfuncs.inc58
-rw-r--r--web/lib/aur.inc31
4 files changed, 74 insertions, 21 deletions
diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql
index 67e20a7c..250d4058 100644
--- a/support/schema/aur-schema.sql
+++ b/support/schema/aur-schema.sql
@@ -26,6 +26,7 @@ CREATE TABLE Users (
Username CHAR(32) NOT NULL,
Email CHAR(64) NOT NULL,
Passwd CHAR(32) NOT NULL,
+ Salt CHAR(32) NOT NULL DEFAULT '',
ResetKey CHAR(32) NOT NULL DEFAULT '',
RealName CHAR(64) NOT NULL DEFAULT '',
LangPreference CHAR(5) NOT NULL DEFAULT 'en',
diff --git a/web/html/passreset.php b/web/html/passreset.php
index 6fbd1caa..0f98593d 100644
--- a/web/html/passreset.php
+++ b/web/html/passreset.php
@@ -31,10 +31,13 @@ if (isset($_GET['resetkey'], $_POST['email'], $_POST['password'], $_POST['confir
if (empty($error)) {
$dbh = db_connect();
+ $salt = generate_salt();
+ $hash = salted_hash($password, $salt);
# The query below won't affect any records unless the ResetKey
# and Email combination is correct and ResetKey is nonempty
$q = "UPDATE Users
- SET Passwd = '".md5($password)."',
+ SET Passwd = '$hash',
+ Salt = '$salt',
ResetKey = ''
WHERE ResetKey != ''
AND ResetKey = '".mysql_real_escape_string($resetkey)."'
diff --git a/web/lib/acctfuncs.inc b/web/lib/acctfuncs.inc
index 91b6249a..9c172bbb 100644
--- a/web/lib/acctfuncs.inc
+++ b/web/lib/acctfuncs.inc
@@ -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;
diff --git a/web/lib/aur.inc b/web/lib/aur.inc
index e0521abc..8ccce897 100644
--- a/web/lib/aur.inc
+++ b/web/lib/aur.inc
@@ -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);
+}