Index: password_change.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/password_change/password_change.module,v
retrieving revision 1.7
diff -u -r1.7 password_change.module
--- password_change.module	Sun Jan 10 03:15:19 2010	1.7
+++ password_change.module	Wed Oct 27 07:15:31 2010
@@ -1,125 +1,179 @@
-<?php
-// $Id: password_change.module,v 1.7 2010/01/10 02:15:19 davereid Exp $
-
-/**
- * Check or set if this is a reset password session using cookies.
- *
- * @param $is_reset
- *   An optional boolean to set if this is a reset password session.
- * @return
- *   If $is_reset was not provided, a boolean if this session is currently a
- *   reset password session or not.
- */
-function password_change_is_reset($is_reset = NULL) {
-  if (!isset($is_reset)) {
-    //return !empty($_SESSION['password_change_reset']);
-    return !empty($_COOKIE['password_change_reset']);
-  }
-  elseif ($is_reset) {
-    //$_SESSION['password_change_reset'] = TRUE;
-    setcookie('password_change_reset', '1', time() + 86400, '/');
-  }
-  else {
-    //unset($_SESSION['password_change_reset']);
-    setcookie('password_change_reset', '', time() - 86400, '/');
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function password_change_form_user_pass_reset_alter(&$form, $form_state) {
-  // We have hit the reset password login form, so set the reset flag to TRUE.
-  password_change_is_reset(TRUE);
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function password_change_form_user_login_form_alter(&$form, $form_state) {
-  // Clear the reset flag since the user has manually logged in.
-  $form['#submit'][] = 'password_change_form_submit_clear_reset';
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function password_change_form_user_login_block_alter(&$form, $form_state) {
-  // Clear the reset flag since the user has manually logged in.
-  $form['#submit'][] = 'password_change_form_submit_clear_reset';
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function password_change_form_user_profile_form_alter(&$form, $form_state) {
-  if ($form['_category']['#value'] == 'account') {
-    $account = $form['_account']['#value'];
-    if ($account->uid == $GLOBALS['user']->uid || variable_get('password_change_all', 0)) {
-      if (password_change_is_reset()) {
-        // Make the normal password field required if the password was just
-        // reset.
-        $form['account']['pass']['#required'] = TRUE;
-      }
-      else {
-        // Add the current password field just below the 'Save' button.
-        $form['pass_current'] = array(
-          '#type' => 'password',
-          '#title' => t('Your current password'),
-          '#description' => t('For security reasons, enter your current password to confirm your changes.'),
-          '#size' => 25,
-          '#weight' => $form['submit']['#weight'] - 0.5,
-          '#required' => TRUE,
-          '#element_validate' => array('password_change_validate_password'),
-        );
-      }
-
-      // Put the submit handler first so we can clear the values before they
-      // could be saved into $user->data.
-      array_unshift($form['#submit'], 'password_change_form_submit_clear_reset');
-    }
-  }
-  //unset($form['locale']);
-  //unset($form['theme_select']);
-  //unset($form['picture']);
-  //unset($form['contact']);
-  //unset($form['timezone']);
-}
-
-function password_change_validate_password($element, $form_state) {
-  if (md5($element['#value']) !== $GLOBALS['user']->pass) {
-    form_error($element, 'Incorrect current password.');
-  }
-}
-
-//function password_change_user_profile_form_validate($form, &$form_state) {
-//  if (md5($form_state['values']['pass_current']) !== $GLOBALS['user']->pass) {
-//    form_set_error('pass_current', 'Incorrect current password.');
-//  }
-//}
-
-/**
- * Submit handler; reset the reset flag and unset the currnet password value.
- */
-function password_change_form_submit_clear_reset($form, &$form_state) {
-  password_change_is_reset(FALSE);
-  unset($form_state['values']['pass_current']);
-}
-
-/**
- * Implements hook_form_FORM_ID_alter().
- */
-function password_change_form_user_admin_settings_alter(&$form, $form_state) {
-  $form += array(
-    'security' => array(
-      '#type' => 'fieldset',
-      '#title' => t('Security'),
-    ),
-  );
-  $form['security']['password_change_all'] = array(
-    '#type' => 'checkbox',
-    '#title' => t("Require the current user to confirm his or her current password when changing any user's account."),
-    '#description' => t('Users will still be required to confirm their password when changing their own account regardless of this setting.'),
-    '#default_value' => variable_get('password_change_all', FALSE),
-  );
-}
+<?php
+// $Id: password_change.module,v 1.7 2010/01/10 02:15:19 davereid Exp $
+
+/**
+ * Check or set if this is a reset password session using cookies.
+ *
+ * @param $is_reset
+ *   An optional boolean to set if this is a reset password session.
+ * @return
+ *   If $is_reset was not provided, a boolean if this session is currently a
+ *   reset password session or not.
+ */
+function password_change_is_reset($is_reset = NULL) {
+  if (!isset($is_reset)) {
+    //return !empty($_SESSION['password_change_reset']);
+    return !empty($_COOKIE['password_change_reset']);
+  }
+  elseif ($is_reset) {
+    //$_SESSION['password_change_reset'] = TRUE;
+    setcookie('password_change_reset', '1', time() + 86400, '/');
+  }
+  else {
+    //unset($_SESSION['password_change_reset']);
+    setcookie('password_change_reset', '', time() - 86400, '/');
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function password_change_form_user_pass_reset_alter(&$form, $form_state) {
+  // We have hit the reset password login form, so set the reset flag to TRUE.
+  password_change_is_reset(TRUE);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function password_change_form_user_login_form_alter(&$form, $form_state) {
+  // Clear the reset flag since the user has manually logged in.
+  $form['#submit'][] = 'password_change_form_submit_clear_reset';
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function password_change_form_user_login_block_alter(&$form, $form_state) {
+  // Clear the reset flag since the user has manually logged in.
+  $form['#submit'][] = 'password_change_form_submit_clear_reset';
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function password_change_form_user_profile_form_alter(&$form, $form_state) {
+  if ($form['_category']['#value'] == 'account') {
+    $account = $form['_account']['#value'];
+    if ($account->uid == $GLOBALS['user']->uid || variable_get('password_change_all', 0)) {
+      if (password_change_is_reset()) {
+        // Make the normal password field required if the password was just
+        // reset.
+        $form['account']['pass']['#required'] = TRUE;
+      }
+      else {
+        // Add the current password field just below the 'Save' button.
+        $form['pass_current'] = array(
+          '#type' => 'password',
+          '#title' => t('Your current password'),
+          '#description' => t('For security reasons, enter your current password to confirm your changes.'),
+          '#size' => 25,
+          '#weight' => $form['submit']['#weight'] - 0.5,
+          '#required' => TRUE,
+          '#element_validate' => array('password_change_validate_password'),
+        );
+      }
+
+      // Put the submit handler first so we can clear the values before they
+      // could be saved into $user->data.
+      array_unshift($form['#submit'], 'password_change_form_submit_clear_reset');
+    }
+  }
+  //unset($form['locale']);
+  //unset($form['theme_select']);
+  //unset($form['picture']);
+  //unset($form['contact']);
+  //unset($form['timezone']);
+}
+
+// based on _phpass_user_authenticate (phpass.module) and _password_load_user, password_user (password.module)
+function password_change_validate_password($element, $form_state) {
+  // map variables
+  $curpass = $element['#value'];
+  $account = user_load(array('name' => $GLOBALS['user']->name, 'status' => 1));
+  // validate with password module method
+  if (module_exists('password')) {
+    // Load in the new password hashes from password table (password)
+    $account->password = db_result(db_query("SELECT pass FROM {password} WHERE uid = %d", $account->uid));
+    // proceed if new hash is not empty
+    if (!empty($account->password)) {
+      // Switch in the new hash into the $account->pass value.
+      $old_pass = $account->pass;
+      $account->pass = $account->password;
+      // Allow alternate password hashing schemes (password.module)
+      _password_include();
+      // compare hashes through function user_check_password (password.inc)
+      $check = user_check_password($curpass, $account);
+      if ($check != 1) {
+        // mismatch password hashes returns error
+        form_error($element, t('Incorrect current password.'));
+      }
+      // Switch $account->pass back to the MD5 hash.
+      $account->pass = $old_pass;
+    }
+  // validate with phpass module method (phpass hash method set as 'phpass')
+  } elseif (module_exists('phpass') && variable_get('user_hash_method', 'phpass') == 'phpass') {
+    // Load in the new password hashes from phpass table (user_phpass)
+    $account->hash = db_result(db_query("SELECT hash FROM {user_phpass} WHERE uid = %d", $account->uid));
+    // proceed if new hash is not empty and old hash matches 'phpass'
+    if (!empty($account->hash) && ($account->pass == 'phpass')) {
+      // check if PasswordHash.php is missing (phpass.module)
+      _phpass_is_passwordhash_php_missing();
+      // Allow alternate password hashing schemes (PasswordHash.php)
+      require_once(drupal_get_path('module', 'phpass') .'/PasswordHash.php');
+      // compare hashes through function CheckPassword (PasswordHash.php)
+      $phpass = new PasswordHash(variable_get('user_hash_strength', 8), variable_get('user_hash_portable', TRUE));
+      $check = $phpass->CheckPassword($curpass, $account->hash);
+      if ($check != 1) {
+        // mismatch password hashes returns error
+        form_error($element, t('Incorrect current password.'));
+      }
+    // else proceed if old has does not match 'phpass' (md5 method)
+    } elseif ($account->pass != 'phpass') {
+      // compare hashes through function md5
+      if ($account->pass !== md5($curpass)) {
+        // mismatch password hashes returns error
+        form_error($element, t('Incorrect current password.'));
+      }
+    }
+  // validate with the old md5 method
+  } else {
+    // compare hashes through function md5
+    if ($account->pass !== md5($curpass)) {
+      // mismatch password hashes returns error
+      form_error($element, t('Incorrect current password.'));
+    }
+  }
+}
+
+//function password_change_user_profile_form_validate($form, &$form_state) {
+//  if (md5($form_state['values']['pass_current']) !== $GLOBALS['user']->pass) {
+//    form_set_error('pass_current', 'Incorrect current password.');
+//  }
+//}
+
+/**
+ * Submit handler; reset the reset flag and unset the currnet password value.
+ */
+function password_change_form_submit_clear_reset($form, &$form_state) {
+  password_change_is_reset(FALSE);
+  unset($form_state['values']['pass_current']);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function password_change_form_user_admin_settings_alter(&$form, $form_state) {
+  $form += array(
+    'security' => array(
+      '#type' => 'fieldset',
+      '#title' => t('Security'),
+    ),
+  );
+  $form['security']['password_change_all'] = array(
+    '#type' => 'checkbox',
+    '#title' => t("Require the current user to confirm his or her current password when changing any user's account."),
+    '#description' => t('Users will still be required to confirm their password when changing their own account regardless of this setting.'),
+    '#default_value' => variable_get('password_change_all', FALSE),
+  );
+}
