From e0f7d5328eb0bc7f6eae0e2cbdc2d6d61501c5c2 Mon Sep 17 00:00:00 2001
From: Denis Kobozev <d.v.kobozev@gmail.com>
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..6a0c654
--- /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

