### Eclipse Workspace Patch 1.0
#P contributions-5
Index: modules/password_reset/password_reset.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/password_reset/password_reset.module,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 password_reset.module
--- modules/password_reset/password_reset.module	17 May 2008 20:19:21 -0000	1.1.2.3
+++ modules/password_reset/password_reset.module	24 Feb 2010 17:00:44 -0000
@@ -111,7 +111,22 @@
       break;
     case 2:
       $uid = password_reset_uid_get($form_values['username']);
-      if ($question = password_reset_user_question_get($uid)) {
+      // try to retrieve question
+      $question = password_reset_user_question_get($uid);
+
+      if ($question === FALSE) {
+        // question not found, user does not exist or doesn't have a quuestion
+        // selected we don't want to give any information away, so we select a
+        // question using a checksum over the name for consistency (if we do a
+        // random select, submitting the form twice will tell an attacker it's
+        // an invalid username)
+        $questions = array_values(password_reset_questions_get());
+        if (count($questions) > 0) {
+          $chksum = crc32(drupal_strtolower($form_state['values']['username']));
+          $question = (object) array('question' => $questions[abs($chksum % count($questions))]);
+        }
+      }
+      if ($question) {
         $form['username'] = array('#type' => 'hidden', '#value' => $form_values['username']);
         $form['question'] = array('#value' => t('<strong>Security question:</strong> %question', array('%question' => $question->question)));
         $form['answer'] = array(
@@ -153,16 +168,14 @@
 function password_reset_form_validate($form_id, $form_values) {
   switch ($form_values['step']) {
     case 1:
-      $uid = password_reset_uid_get($form_values['username']);
-      if (!$uid) {
-        form_set_error('username', t('Username not found. Please check and try again.'));
-      }
+      // Do not validate the username here, as we don't want to give away the
+      // information that a username is (in)valid
       break;
     case 2:
       $uid = password_reset_uid_get($form_values['username']);
       $question = password_reset_user_question_get($uid);
-      if (!$question || trim(strtolower($question->answer)) != trim(strtolower($form_values['answer']))) {
-        form_set_error('answer', t('Answer incorrect. Please check and try again.'));
+      if (!$question || trim(drupal_strtolower($question->answer)) != trim(drupal_strtolower($form_values['answer']))) {
+        form_set_error('answer', t('Username or answer incorrect. Please check and try again.'));
       }
       break;
   }
@@ -360,7 +373,7 @@
  * user_load calls and / or JOINs on each step.
  */
 function password_reset_uid_get($username) {
-  $uid = db_result(db_query("SELECT u.uid FROM {users} u WHERE u.status = 1 AND LOWER(u.name) = '%s'", trim(strtolower($username))));
+  $uid = db_result(db_query("SELECT u.uid FROM {users} u WHERE u.status = 1 AND LOWER(u.name) = '%s'", trim(drupal_strtolower($username))));
 
   return $uid;
 }
