Here's a patch with a script to salt passwords in the database. It assumes that there already a Salt field in the Users table. Hopefully it will integrated with Linas's patches.
Linas, I think salted_hash() should not call md5() internally, otherwise it's not very useful to the script. You can take a look at the patch if I'm being ambiguous. Best, Denis.
From da269cc1adfb58046867549e5e25b24935308ef3 Mon Sep 17 00:00:00 2001 From: Denis Kobozev <[email protected]> Date: Fri, 25 Jun 2010 08:17:08 -0400 Subject: [PATCH] Script for salting passwords in the database --- scripts/addsalt | 46 ++++++++++++++++++++++++++++++++++++++++++++++ web/html/passreset.php | 2 +- web/lib/acctfuncs.inc | 6 +++--- web/lib/aur.inc | 7 ++++--- 4 files changed, 54 insertions(+), 7 deletions(-) create mode 100755 scripts/addsalt diff --git a/scripts/addsalt b/scripts/addsalt new file mode 100755 index 0000000..a6b2d18 --- /dev/null +++ b/scripts/addsalt @@ -0,0 +1,46 @@ +#!/usr/bin/php +<?php +# addsalt - salt user passwords +# +# Run this script by providing it with the top path of AUR. +# In that path you should see a file lib/aur.inc +# +# ex: php addsalt dev/aur/web + +$dir = $argv[1]; + +if (empty($dir)) { + echo "Please specify AUR directory.\n"; + exit; +} + +set_include_path(get_include_path() . PATH_SEPARATOR . "$dir/lib"); +include("aur.inc"); + + +function update_user($dbh, $id, $md5) +{ + $salt = generate_salt(); + // salted_hash() expects md5($plain_password) + $hash = salted_hash($md5, $salt); + $q = "UPDATE Users SET Passwd=\"$hash\", Salt=\"$salt\" WHERE ID=$id"; + db_query($q, $dbh) or die('MySQL error: ' . mysql_error($dbh)); +} + +function addsalt() +{ + $dbh = db_connect(); + $q = 'SELECT ID, Passwd, Salt FROM Users'; + $res = db_query($q, $dbh) or die('MySQL error: ' . mysql_error($dbh)); + $users_total = mysql_num_rows($res); + $updates = 0; + while ($row = mysql_fetch_assoc($res)) { + if (empty($row['Salt'])) { + update_user($dbh, $row['ID'], $row['Passwd']); + $updates++; + } + } + echo "Salted passwords for $updates out of $users_total users\n"; +} + +addsalt(); diff --git a/web/html/passreset.php b/web/html/passreset.php index 0f98593..30b0386 100644 --- a/web/html/passreset.php +++ b/web/html/passreset.php @@ -32,7 +32,7 @@ if (isset($_GET['resetkey'], $_POST['email'], $_POST['password'], $_POST['confir if (empty($error)) { $dbh = db_connect(); $salt = generate_salt(); - $hash = salted_hash($password, $salt); + $hash = salted_hash(md5($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 diff --git a/web/lib/acctfuncs.inc b/web/lib/acctfuncs.inc index 9c172bb..9712186 100644 --- a/web/lib/acctfuncs.inc +++ b/web/lib/acctfuncs.inc @@ -266,7 +266,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", if ($TYPE == "new") { # no errors, go ahead and create the unprivileged user $salt = generate_salt(); - $P = salted_hash($P, $salt); + $P = salted_hash(md5($P), $salt); $escaped = array_map(mysql_real_escape_string, array($U, $E, $P, $salt, $R, $L, $I)); $q = "INSERT INTO Users (" . @@ -308,7 +308,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="", $q.= ", Email = '".mysql_real_escape_string($E)."'"; if ($P) { $salt = generate_salt(); - $hash = salted_hash($P, $salt); + $hash = salted_hash(md5($P), $salt); $q .= ", Passwd = '$hash', Salt = '$salt'"; } $q.= ", RealName = '".mysql_real_escape_string($R)."'"; @@ -743,7 +743,7 @@ function valid_passwd( $userID, $passwd ) # use salt $passwd_q = "SELECT ID FROM Users" . " WHERE ID = '$userID' AND Passwd = '" . - salted_hash($passwd, $salt) . "'"; + salted_hash(md5($passwd), $salt) . "'"; $passwd_result = mysql_fetch_row(db_query($passwd_q, $dbh)); if ($passwd_result[0]) { return true; diff --git a/web/lib/aur.inc b/web/lib/aur.inc index 37f18f8..19380f6 100644 --- a/web/lib/aur.inc +++ b/web/lib/aur.inc @@ -468,7 +468,7 @@ function save_salt($user_id, $passwd) { $dbh = db_connect(); $salt = generate_salt(); - $hash = salted_hash($passwd, $salt); + $hash = salted_hash(md5($passwd), $salt); $salting_q = "UPDATE Users SET Salt = '$salt'" . ", Passwd = '$hash' WHERE ID = '$user_id'"; return db_query($salting_q, $dbh); @@ -479,10 +479,11 @@ function generate_salt() return md5(uniqid(mt_rand(), true)); } -function salted_hash($passwd, $salt) +// Expects md5($password) for backward compatibility with plain md5 hashes +function salted_hash($passwd_md5, $salt) { if (strlen($salt) != 32) { trigger_error('Salt does not look like an md5 hash', E_USER_WARNING); } - return md5($salt . $passwd); + return md5($salt . $passwd_md5); } -- 1.7.1
