From 0fc7cffa66b0c6fe938b8975e74df44eb736d11d Mon Sep 17 00:00:00 2001 From: e107steved Date: Tue, 21 Jul 2009 19:21:27 +0000 Subject: [PATCH] WordPress password validation in alt_auth --- .../alt_auth/alt_auth_login_class.php | 10 +- .../alt_auth/extended_password_handler.php | 268 ++++++++++-------- e107_plugins/alt_auth/importdb_auth.php | 66 ++--- .../languages/English/admin_importdb_conf.php | 25 +- usersettings.php | 5 +- 5 files changed, 195 insertions(+), 179 deletions(-) diff --git a/e107_plugins/alt_auth/alt_auth_login_class.php b/e107_plugins/alt_auth/alt_auth_login_class.php index daafd19fc..485eef66e 100755 --- a/e107_plugins/alt_auth/alt_auth_login_class.php +++ b/e107_plugins/alt_auth/alt_auth_login_class.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_plugins/alt_auth/alt_auth_login_class.php,v $ -| $Revision: 1.8 $ -| $Date: 2009-07-05 18:47:52 $ +| $Revision: 1.9 $ +| $Date: 2009-07-21 19:21:26 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -105,10 +105,10 @@ class alt_login { $newUser = array(); $newUser['data'] = $db_vals; - validatorClass::addFieldTypes($userMethods->userVettingInfo,$allData); + validatorClass::addFieldTypes($userMethods->userVettingInfo,$newUser); $newUser['WHERE'] = '`user_id`='.$row['user_id']; - $aa_sql->db_Update('user',$db_vals); - if (AA_DEBUG1) $admin_log->e_log_event(10,debug_backtrace(),"DEBUG","Alt auth login","User data update: ".print_r($db_vals,TRUE),FALSE,LOG_TO_ROLLING); + $aa_sql->db_Update('user',$newUser); + if (AA_DEBUG1) $admin_log->e_log_event(10,debug_backtrace(),"DEBUG","Alt auth login","User data update: ".print_r($newUser,TRUE),FALSE,LOG_TO_ROLLING); } foreach ($xFields as $k => $v) { diff --git a/e107_plugins/alt_auth/extended_password_handler.php b/e107_plugins/alt_auth/extended_password_handler.php index b0cf9f23f..0b64dbf2f 100644 --- a/e107_plugins/alt_auth/extended_password_handler.php +++ b/e107_plugins/alt_auth/extended_password_handler.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_plugins/alt_auth/extended_password_handler.php,v $ -| $Revision: 1.1 $ -| $Date: 2008-07-25 19:33:03 $ +| $Revision: 1.2 $ +| $Date: 2009-07-21 19:21:27 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -46,10 +46,12 @@ require_once(e_HANDLER.'user_handler.php'); define('PASSWORD_GENERAL_MD5',5); define('PASSWORD_PLAINTEXT',6); define('PASSWORD_GENERAL_SHA1',7); + define('PASSWORD_WORDPRESS_SALT', 8); // Supported formats: define('PASSWORD_PHPBB_ID','$H$'); // PHPBB salted - define('PASSWORD_ORIG_ID','$P$'); // 'Original' code + define('PASSWORD_ORIG_ID','$P$'); // 'Original' code + define('PASSWORD_WORDPRESS_ID', '$P$'); // WordPress 2.8 class ExtendedPasswordHandler extends UserHandler @@ -111,33 +113,48 @@ class ExtendedPasswordHandler extends UserHandler - // Method for PHPBB3-style salted passwords, which begin '$H$' + // Method for PHPBB3-style salted passwords, which begin '$H$', and WordPress-style salted passwords, which begin '$P$' // Given a plaintext password and the complete password/hash function (which includes any salt), calculate hash // Returns FALSE on error - function crypt_private($password, $stored_password) - { - $output = '*0'; - if (substr($stored_password, 0, 2) == $output) + function crypt_private($password, $stored_password, $password_type = PASSWORD_PHPBB_SALT) + { + $output = '*0'; + if (substr($stored_password, 0, 2) == $output) + { $output = '*1'; + } - switch (substr($stored_password, 0, 3)) - { - case PASSWORD_PHPBB_ID : // PHPBB3 encoding - case PASSWORD_ORIG_ID : // Original algorithm's encoding - break; - default : - return $output; - } + $prefix = ''; + switch ($password_type) + { + case PASSWORD_PHPBB_SALT : + $prefix = PASSWORD_PHPBB_ID; + break; + case PASSWORD_WORDPRESS_SALT : + $prefix = PASSWORD_WORDPRESS_ID; + break; + default : + $prefix = ''; + } - $count_log2 = strpos($this->itoa64, $stored_password[3]); // 4th character indicates hash depth count - if ($count_log2 < 7 || $count_log2 > 30) + if ($prefix != substr($stored_password, 0, 3)) + { return $output; + } - $count = 1 << $count_log2; - - $salt = substr($stored_password, 4, 8); // Salt is characters 5..12 - if (strlen($salt) != 8) + $count_log2 = strpos($this->itoa64, $stored_password[3]); // 4th character indicates hash depth count + if ($count_log2 < 7 || $count_log2 > 30) + { return $output; + } + + $count = 1 << $count_log2; + + $salt = substr($stored_password, 4, 8); // Salt is characters 5..12 + if (strlen($salt) != 8) + { + return $output; + } # We're kind of forced to use MD5 here since it's the only # cryptographic primitive available in all versions of PHP @@ -145,120 +162,119 @@ class ExtendedPasswordHandler extends UserHandler # in PHP would result in much worse performance and # consequently in lower iteration counts and hashes that are # quicker to crack (by non-PHP code). - if (PHP_VERSION >= '5') - { // Get raw binary output (always 16 bytes) - $hash = md5($salt . $password, TRUE); - do - { - $hash = md5($hash . $password, TRUE); - } while (--$count); - } - else - { // Use 'pack' to create 16 bytes from the hex string - $hash = pack('H*', md5($salt . $password)); - do - { - $hash = pack('H*', md5($hash . $password)); - } while (--$count); - } + // Get raw binary output (always 16 bytes) - we assume PHP5 here + $hash = md5($salt.$password, TRUE); + do + { + $hash = md5($hash.$password, TRUE); + } while (--$count); $output = substr($setting, 0, 12); // Identifier, shift count and salt - total 12 chars $output .= $this->encode64($hash, 16); // Returns 22-character string return $output; - } - - - // Return array of supported password types - key is used internally, text is displayed - function getPasswordTypes($include_core = FALSE) - { - $vals = array(); - if ($include_core) - { - $vals = array('md5' => IMPORTDB_LAN_7,'e107_salt' => IMPORTDB_LAN_8); // Methods supported in core } - if (is_bool($include_core)) + + + // Return array of supported password types - key is used internally, text is displayed + function getPasswordTypes($include_core = FALSE) { - $vals = array_merge($vals,array( - 'plaintext' => IMPORTDB_LAN_2, - 'joomla_salt' => IMPORTDB_LAN_3, - 'mambo_salt' => IMPORTDB_LAN_4, - 'smf_sha1' => IMPORTDB_LAN_5, - 'sha1' => IMPORTDB_LAN_6, - 'phpbb3_salt' => IMPORTDB_LAN_12 - )); - } - return $vals; - } - - - // Return password type which relates to a specific foreign system - function passwordMapping($ptype) - { - $maps = array( - 'plaintext' => PASSWORD_PLAINTEXT, - 'joomla_salt' => PASSWORD_JOOMLA_SALT, - 'mambo_salt' => PASSWORD_MAMBO_SALT, - 'smf_sha1' => PASSWORD_GENERAL_SHA1, - 'sha1' => PASSWORD_GENERAL_SHA1, - 'mambo' => PASSWORD_GENERAL_MD5, - 'phpbb2' => PASSWORD_GENERAL_MD5, - 'e107' => PASSWORD_GENERAL_MD5, - 'md5' => PASSWORD_GENERAL_MD5, - 'e107_salt' => PASSWORD_E107_SALT, - 'phpbb2_salt' => PASSWORD_PHPBB_SALT - ); - if (isset($maps[$ptype])) return $maps[$ptype]; - return FALSE; - } - - - // Extension of password validation - - function CheckPassword($pword, $login_name, $stored_hash, $password_type = PASSWORD_DEFAULT_TYPE) - { - switch ($password_type) - { - case PASSWORD_GENERAL_MD5 : - case PASSWORD_E107_MD5 : - $pwHash = md5($pword); - break; - - case PASSWORD_GENERAL_SHA1 : - if (strlen($stored_hash) != 40) return PASSWORD_INVALID; - $pwHash = sha1($pword); - break; - - case PASSWORD_JOOMLA_SALT : - case PASSWORD_MAMBO_SALT : - if ((strpos($row['user_password'], ':') === false) || (strlen($row[0]) < 40)) + $vals = array(); + if ($include_core) { - return PASSWORD_INVALID; + $vals = array('md5' => IMPORTDB_LAN_7,'e107_salt' => IMPORTDB_LAN_8); // Methods supported in core } - // Mambo/Joomla salted hash - should be 32-character md5 hash, ':', 16-character salt (but could be 8-char salt, maybe) - list($hash, $salt) = explode(':', $stored_hash); - $pwHash = md5($pword.$salt); - $stored_hash = $hash; - break; - - case PASSWORD_E107_SALT : - return UserHandler::CheckPassword($password, $login_name, $stored_hash); - break; - - case PASSWORD_PHPBB_SALT : - if (strlen($stored_hash) != 34) return PASSWORD_INVALID; - $pwHash = $this->HashPassword($pword, PASSWORD_PHPBB_SALT); - break; - - case PASSWORD_PLAINTEXT : - $pwHash = $pword; - break; - - default : - return PASSWORD_INVALID; + if (is_bool($include_core)) + { + $vals = array_merge($vals,array( + 'plaintext' => IMPORTDB_LAN_2, + 'joomla_salt' => IMPORTDB_LAN_3, + 'mambo_salt' => IMPORTDB_LAN_4, + 'smf_sha1' => IMPORTDB_LAN_5, + 'sha1' => IMPORTDB_LAN_6, + 'phpbb3_salt' => IMPORTDB_LAN_12, + 'wordpress_salt' => IMPORTDB_LAN_13 + )); + } + return $vals; + } + + + // Return password type which relates to a specific foreign system + function passwordMapping($ptype) + { + $maps = array( + 'plaintext' => PASSWORD_PLAINTEXT, + 'joomla_salt' => PASSWORD_JOOMLA_SALT, + 'mambo_salt' => PASSWORD_MAMBO_SALT, + 'smf_sha1' => PASSWORD_GENERAL_SHA1, + 'sha1' => PASSWORD_GENERAL_SHA1, + 'mambo' => PASSWORD_GENERAL_MD5, + 'phpbb2' => PASSWORD_GENERAL_MD5, + 'e107' => PASSWORD_GENERAL_MD5, + 'md5' => PASSWORD_GENERAL_MD5, + 'e107_salt' => PASSWORD_E107_SALT, + 'phpbb2_salt' => PASSWORD_PHPBB_SALT, + 'phpbb3_salt' => PASSWORD_PHPBB_SALT, + 'wordpress_salt' => PASSWORD_WORDPRESS_SALT + ); + if (isset($maps[$ptype])) return $maps[$ptype]; + return FALSE; + } + + + // Extension of password validation - + function CheckPassword($pword, $login_name, $stored_hash, $password_type = PASSWORD_DEFAULT_TYPE) + { + switch ($password_type) + { + case PASSWORD_GENERAL_MD5 : + case PASSWORD_E107_MD5 : + $pwHash = md5($pword); + break; + + case PASSWORD_GENERAL_SHA1 : + if (strlen($stored_hash) != 40) return PASSWORD_INVALID; + $pwHash = sha1($pword); + break; + + case PASSWORD_JOOMLA_SALT : + case PASSWORD_MAMBO_SALT : + if ((strpos($row['user_password'], ':') === false) || (strlen($row[0]) < 40)) + { + return PASSWORD_INVALID; + } + // Mambo/Joomla salted hash - should be 32-character md5 hash, ':', 16-character salt (but could be 8-char salt, maybe) + list($hash, $salt) = explode(':', $stored_hash); + $pwHash = md5($pword.$salt); + $stored_hash = $hash; + break; + + case PASSWORD_E107_SALT : + return UserHandler::CheckPassword($password, $login_name, $stored_hash); + break; + + case PASSWORD_PHPBB_SALT : + case PASSWORD_WORDPRESS_SALT : + if (strlen($stored_hash) != 34) return PASSWORD_INVALID; + $pwHash = $this->crypt_private($pword, $stored_hash, $password_type); + if ($pwHash[0] == '*') + { + return PASSWORD_INVALID; + } + $stored_hash = substr($stored_hash,12); + break; + + case PASSWORD_PLAINTEXT : + $pwHash = $pword; + break; + + default : + return PASSWORD_INVALID; + } + if ($stored_hash != $pwHash) return PASSWORD_INVALID; + return PASSWORD_VALID; } - if ($stored_hash != $pwHash) return PASSWORD_INVALID; - return PASSWORD_VALID; - } } diff --git a/e107_plugins/alt_auth/importdb_auth.php b/e107_plugins/alt_auth/importdb_auth.php index 4bd2959c1..a2a480fea 100644 --- a/e107_plugins/alt_auth/importdb_auth.php +++ b/e107_plugins/alt_auth/importdb_auth.php @@ -11,8 +11,8 @@ | GNU General Public License (http://gnu.org). | | $Source: /cvs_backup/e107_0.8/e107_plugins/alt_auth/importdb_auth.php,v $ -| $Revision: 1.2 $ -| $Date: 2008-09-02 19:39:12 $ +| $Revision: 1.3 $ +| $Date: 2009-07-21 19:21:27 $ | $Author: e107steved $ +----------------------------------------------------------------------------+ */ @@ -34,7 +34,7 @@ class auth_login function auth_login() { - global $sql; + global $sql; $this->ErrorText = ''; $this->conf = array(); if (!$sql -> db_Select("alt_auth", "*", "auth_type = 'importdb' ")) return AUTH_NOCONNECT; // We should get at least one value @@ -54,42 +54,42 @@ class auth_login function login($uname, $pword, &$newvals, $connect_only = FALSE) { - if ($connect_only) return AUTH_SUCCESS; // Big problem if can't connect to our own DB! + if ($connect_only) return AUTH_SUCCESS; // Big problem if can't connect to our own DB! - // See if the user's in the E107 database - otherwise they can go away - global $sql, $tp; - if (!$sql->db_Select("user", "user_loginname, user_password", "user_loginname = '".$tp -> toDB($uname)."'")) - { // Invalid user - $this->makeErrorText('User not found'); - return AUTH_NOUSER; - } + // See if the user's in the E107 database - otherwise they can go away + global $sql, $tp; + if (!$sql->db_Select('user', 'user_loginname, user_password', "user_loginname = '".$tp -> toDB($uname)."'")) + { // Invalid user + $this->makeErrorText('User not found'); + return AUTH_NOUSER; + } - // Now look at their password - we always need to verify it, even if its a core E107 format. - // Higher levels will always convert an authorised password to E107 format and save it for us. - if (!$row = $sql->db_Fetch()) - { - $this->makeErrorText('Error reading DB'); - return AUTH_NOCONNECT; // Debateable return code - really a DB error. But consistent with other handler - } + // Now look at their password - we always need to verify it, even if its a core E107 format. + // Higher levels will always convert an authorised password to E107 format and save it for us. + if (!$row = $sql->db_Fetch()) + { + $this->makeErrorText('Error reading DB'); + return AUTH_NOCONNECT; // Debateable return code - really a DB error. But consistent with other handler + } - require_once(e_PLUGIN.'alt_auth/extended_password_handler.php'); // This auto-loads the 'standard' password handler as well - $pass_check = new ExtendedPasswordHandler(); + require_once(e_PLUGIN.'alt_auth/extended_password_handler.php'); // This auto-loads the 'standard' password handler as well + $pass_check = new ExtendedPasswordHandler(); - $passMethod = $pass_check->passwordMapping($this->conf['importdb_password_method']); - if ($passMethod === FALSE) - { - $this->makeErrorText('Password error - invalid method'); - return AUTH_BADPASSWORD; - } + $passMethod = $pass_check->passwordMapping($this->conf['importdb_password_method']); + if ($passMethod === FALSE) + { + $this->makeErrorText('Password error - invalid method'); + return AUTH_BADPASSWORD; + } - $pwFromDB = $row['user_password']; // Password stored in DB - if ($pass_check->checkPassword($pword, $uname, $pwFromDB, $passMethod) !== PASSWORD_VALID) - { - $this->makeErrorText('Password incorrect'); - return AUTH_BADPASSWORD; - } + $pwFromDB = $row['user_password']; // Password stored in DB + if ($pass_check->checkPassword($pword, $uname, $pwFromDB, $passMethod) !== PASSWORD_VALID) + { + $this->makeErrorText('Password incorrect'); + return LOGIN_CONTINUE; // Could have already changed password to E107 format + } $this->makeErrorText(''); - return AUTH_SUCCESS; + return AUTH_SUCCESS; } } diff --git a/e107_plugins/alt_auth/languages/English/admin_importdb_conf.php b/e107_plugins/alt_auth/languages/English/admin_importdb_conf.php index ca33c236e..f12e489d8 100644 --- a/e107_plugins/alt_auth/languages/English/admin_importdb_conf.php +++ b/e107_plugins/alt_auth/languages/English/admin_importdb_conf.php @@ -1,18 +1,19 @@ only when you have imported a user database into E107, and the password is in an incompatible format. The original password is read from the local database, and validated against the storage format of the original system. If it verifies, its converted to the current E107-compatible format and diff --git a/usersettings.php b/usersettings.php index 97c6d76db..21cd57588 100644 --- a/usersettings.php +++ b/usersettings.php @@ -9,8 +9,8 @@ * User settings modify * * $Source: /cvs_backup/e107_0.8/usersettings.php,v $ - * $Revision: 1.35 $ - * $Date: 2009-06-12 20:41:35 $ + * $Revision: 1.36 $ + * $Date: 2009-07-21 19:21:27 $ * $Author: e107steved $ * */ @@ -398,7 +398,6 @@ if ($dataToSave && !$promptPassword) } } - print_a($changedEUFData); // Save extended field values if (isset($changedEUFData['data']) && count($changedEUFData['data']))