Using bcrypt for passwords and added PasswordUtil
authorAlexander Ebert <ebert@woltlab.com>
Thu, 3 Jan 2013 15:10:27 +0000 (16:10 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 3 Jan 2013 15:10:27 +0000 (16:10 +0100)
wcfsetup/install/files/lib/acp/form/MasterPasswordForm.class.php
wcfsetup/install/files/lib/acp/form/MasterPasswordInitForm.class.php
wcfsetup/install/files/lib/data/user/User.class.php
wcfsetup/install/files/lib/data/user/UserEditor.class.php
wcfsetup/install/files/lib/system/user/authentication/DefaultUserAuthentication.class.php
wcfsetup/install/files/lib/util/PasswordUtil.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/util/StringUtil.class.php
wcfsetup/setup/db/install.sql

index 46059b02e0985c9485e91a4fa0f8271d139d3edb..23abbf51314dd6f1a136abe054233ece0ea6f821 100755 (executable)
@@ -5,13 +5,13 @@ use wcf\system\exception\UserInputException;
 use wcf\system\request\LinkHandler;
 use wcf\system\WCF;
 use wcf\util\HeaderUtil;
-use wcf\util\StringUtil;
+use wcf\util\PasswordUtil;
 
 /**
  * Shows the master password form.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2011 WoltLab GmbH
+ * @copyright  2001-2013 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage acp.form
@@ -62,7 +62,7 @@ class MasterPasswordForm extends AbstractForm {
                }
                
                // check password
-               if (StringUtil::getSaltedHash($this->masterPassword, MASTER_PASSWORD_SALT) != MASTER_PASSWORD) {
+               if (PasswordUtil::getSaltedHash($this->masterPassword, MASTER_PASSWORD_SALT) != MASTER_PASSWORD) {
                        throw new UserInputException('masterPassword', 'invalid');
                }
        }
index be25e9e169e43b2d237b3d810758bf38133bbeed..b0c31d7e73cb8fd8a2d6ff3f9a6c31922de48433 100755 (executable)
@@ -6,13 +6,14 @@ use wcf\system\exception\UserInputException;
 use wcf\system\io\File;
 use wcf\system\Regex;
 use wcf\system\WCF;
+use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 
 /**
  * Shows the master password init form.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2012 WoltLab GmbH
+ * @copyright  2001-2013 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage acp.form
@@ -112,14 +113,14 @@ class MasterPasswordInitForm extends MasterPasswordForm {
         */
        public function save() {
                // generate salt
-               $salt = StringUtil::getRandomID();
+               $salt = PasswordUtil::getRandomSalt();
                
                // write master password file
                $file = new File(WCF_DIR.'acp/masterPassword.inc.php');
                $file->write("<?php
 /** MASTER PASSWORD STORAGE
 DO NOT EDIT THIS FILE */
-define('MASTER_PASSWORD', '".StringUtil::getSaltedHash($this->masterPassword, $salt)."');
+define('MASTER_PASSWORD', '".PasswordUtil::getSaltedHash($this->masterPassword, $salt)."');
 define('MASTER_PASSWORD_SALT', '".$salt."');
 ?>");
                $file->close();
@@ -136,7 +137,7 @@ define('MASTER_PASSWORD_SALT', '".$salt."');
                
                WCF::getTPL()->assign(array(
                        'confirmMasterPassword' => $this->confirmMasterPassword,
-                       'exampleMasterPassword' => StringUtil::getRandomPassword(12)
+                       'exampleMasterPassword' => PasswordUtil::getRandomPassword(12)
                ));
        }
 }
index 76422160434ad6d5ebed4a86c262309d38705838..da9e9cc430f035841a57c41562d044d114ab05a9 100644 (file)
@@ -9,7 +9,7 @@ use wcf\system\language\LanguageFactory;
 use wcf\system\request\IRouteController;
 use wcf\system\user\storage\UserStorageHandler;
 use wcf\system\WCF;
-use wcf\util\StringUtil;
+use wcf\util\PasswordUtil;
 
 /**
  * Represents a user.
@@ -87,7 +87,37 @@ final class User extends DatabaseObject implements IRESTfulResponse, IRouteContr
         * @return      boolean         password correct
         */
        public function checkPassword($password) {
-               return ($this->password == StringUtil::getDoubleSaltedHash($password, $this->salt));
+               $isValid = false;
+               $rebuild = false;
+               
+               // check if password is a valid bcrypt hash
+               if (PasswordUtil::isBlowfish($this->password)) {
+                       if (PasswordUtil::isDifferentBlowfish($this->password)) {
+                               $rebuild = true;
+                       }
+                       
+                       // password is correct
+                       if ($this->password == PasswordUtil::getDoubleSaltedHash($password, $this->password)) {
+                               $isValid = true;
+                       }
+               }
+               else {
+                       // different encryption type
+                       if (PasswordUtil::checkPassword($this->username, $password, $this->password)) {
+                               $isValid = true;
+                               $rebuild = true;
+                       }
+               }
+               
+               // create new password hash, either different encryption or different blowfish cost factor
+               if ($rebuild) {
+                       $userEditor = new UserEditor($this);
+                       $userEditor->update(array(
+                               'password' => PasswordUtil::getDoubleSaltedHash($password)
+                       ));
+               }
+               
+               return $isValid;
        }
        
        /**
@@ -97,7 +127,11 @@ final class User extends DatabaseObject implements IRESTfulResponse, IRouteContr
         * @return      boolean         password correct
         */
        public function checkCookiePassword($passwordHash) {
-               return ($this->password == StringUtil::encrypt($this->salt . $passwordHash));
+               if (PasswordUtil::isBlowfish($this->password) && ($this->password == PasswordUtil::getSaltedHash($passwordHash, $this->password))) {
+                       return true;
+               }
+               
+               return false;
        }
        
        /**
index 76dc1907df54b98ae42a175033f021105df1f16b..3da6a73d1bc3794eb2c253ce76e2a2b375b2fa1c 100644 (file)
@@ -7,6 +7,7 @@ use wcf\system\clipboard\ClipboardHandler;
 use wcf\system\language\LanguageFactory;
 use wcf\system\session\SessionHandler;
 use wcf\system\WCF;
+use wcf\util\PasswordUtil;
 use wcf\util\StringUtil;
 
 /**
@@ -30,8 +31,7 @@ class UserEditor extends DatabaseObjectEditor implements IEditableCachedObject {
         */
        public static function create(array $parameters = array()) {
                // create salt and password hash
-               $parameters['salt'] = StringUtil::getRandomID();
-               $parameters['password'] = StringUtil::getDoubleSaltedHash($parameters['password'], $parameters['salt']);
+               $parameters['password'] = PasswordUtil::getDoubleSaltedHash($parameters['password']);
                
                // create accessToken for AbstractAuthedPage
                $parameters['accessToken'] = StringUtil::getRandomID();
@@ -63,17 +63,14 @@ class UserEditor extends DatabaseObjectEditor implements IEditableCachedObject {
        public function update(array $parameters = array()) {
                // update salt and create new password hash
                if (isset($parameters['password']) && $parameters['password'] !== '') {
-                       $parameters['salt'] = StringUtil::getRandomID();
-                       $parameters['password'] = StringUtil::getDoubleSaltedHash($parameters['password'], $parameters['salt']);
-                       
+                       $parameters['password'] = PasswordUtil::getDoubleSaltedHash($parameters['password']);
                        $parameters['accessToken'] = StringUtil::getRandomID();
                        
-                       // update salt and accessToken
-                       $this->salt = $parameters['salt'];
+                       // update accessToken
                        $this->accessToken = $parameters['accessToken'];
                }
                else {
-                       unset($parameters['password'], $parameters['salt'], $parameters['accessToken']);
+                       unset($parameters['password'], $parameters['accessToken']);
                }
                
                parent::update($parameters);
index f0df14ef52655a315562c009c788c216ddaf36b9..2c3d831c4b90580f7e9c6be021dfdf75cab30c13 100644 (file)
@@ -3,13 +3,13 @@ namespace wcf\system\user\authentication;
 use wcf\data\user\User;
 use wcf\system\exception\UserInputException;
 use wcf\util\HeaderUtil;
-use wcf\util\StringUtil;
+use wcf\util\PasswordUtil;
 
 /**
  * Default user authentication implementation that uses the username to identify users.
  * 
  * @author     Marcel Werk
- * @copyright  2001-2012 WoltLab GmbH
+ * @copyright  2001-2013 WoltLab GmbH
  * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package    com.woltlab.wcf
  * @subpackage system.user.authentication
@@ -28,7 +28,7 @@ class DefaultUserAuthentication extends AbstractUserAuthentication {
         */
        public function storeAccessData(User $user, $username, $password) {
                HeaderUtil::setCookie('userID', $user->userID, TIME_NOW + 365 * 24 * 3600);
-               HeaderUtil::setCookie('password', StringUtil::getSaltedHash($password, $user->salt), TIME_NOW + 365 * 24 * 3600);
+               HeaderUtil::setCookie('password', PasswordUtil::getSaltedHash($password, $user->password), TIME_NOW + 365 * 24 * 3600);
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/util/PasswordUtil.class.php b/wcfsetup/install/files/lib/util/PasswordUtil.class.php
new file mode 100644 (file)
index 0000000..81be45a
--- /dev/null
@@ -0,0 +1,387 @@
+<?php
+namespace wcf\util;
+use wcf\system\exception\SystemException;
+use wcf\system\Regex;
+
+/**
+ * Provides functions to compute password hashes.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2013 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage util
+ * @category   Community Framework
+ */
+final class PasswordUtil {
+       /**
+        * concated list of valid blowfish salt characters
+        * @var string
+        */
+       private static $blowfishCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
+       
+       /**
+        * list of supported encryption type by software identifier
+        * @var array<string>
+        */
+       private static $supportedEncryptionTypes = array(
+               'ipb2', // Invision Power Board 2.x
+               'ipb3', // Invision Power Board 3.x
+               'smf1', // Simple Machines Forum 1.x
+               'smf2', // Simple Machines Forum 2.x
+               'vb3',  // vBulletin 3.x
+               'vb4',  // vBulletin 4.x
+               'vb5',  // vBulletin 5.x
+               'wbb2', // WoltLab Burning Board 2.x
+               'wcf1', // WoltLab Community Framework 1.x
+               'wcf2', // WoltLab Community Framework 2.x
+               'xf1'   // XenForo 1.x
+       );
+       
+       /**
+        * blowfish cost factor
+        * @var string
+        */
+       const BCRYPT_COST = '08';
+       
+       /**
+        * blowfish encryption type
+        * @var string
+        */
+       const BCRYPT_TYPE = '2a';
+       
+       /**
+        * Returns true, if given encryption type is supported.
+        * 
+        * @param       string          $type
+        * @return      boolean
+        */
+       public static function isSupported($type) {
+               return in_array($type, self::$supportedEncryptionTypes);
+       }
+       
+       /**
+        * Returns true, if given hash looks like a valid bcrypt hash.
+        * 
+        * @param       string          $hash
+        * @return      boolean
+        */
+       public static function isBlowfish($hash) {
+               return (Regex::compile('^\$2(a|f|x)\$')->match($hash) ? true : false);
+       }
+       
+       /**
+        * Returns true, if given bcrypt hash uses a different cost factor and should be re-computed.
+        * 
+        * @param       string          $hash
+        * @return      boolean
+        */
+       public static function isDifferentBlowfish($hash) {
+               $currentCost = intval(self::BCRYPT_COST);
+               $hashCost = intval(substr($hash, 4, 2));
+               
+               if ($currentCost != $hashCost) {
+                       return true;
+               }
+               
+               return false;
+       }
+       
+       /**
+        * Validates password against stored hash, encryption type is automatically resolved.
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       public static function checkPassword($username, $password, $dbHash) {
+               $type = self::detectEncryption($dbHash);
+               if ($type === 'unknown') {
+                       throw new SystemException("Unable to determine password encryption");
+               }
+               
+               // drop type from hash
+               $dbHash = substr($dbHash, strlen($type));
+               
+               // check for salt
+               $salt = '';
+               if (($pos = strrpos($dbHash, ':')) !== false) {
+                       $salt = substr(substr($dbHash, $pos), 1);
+                       $dbHash = substr($dbHash, 1, ($pos - 1));
+               }
+               
+               // compare hash
+               return call_user_func('\wcf\util\PasswordUtil::'.$type, $username, $password, $salt, $dbHash);
+       }
+       
+       /**
+        * Returns encryption type if possible.
+        * 
+        * @param       string          $hash
+        * @return      string
+        */
+       public static function detectEncryption($hash) {
+               if (($pos = strpos($hash, ':')) !== false) {
+                       $type = substr($hash, 0, $pos);
+                       if (in_array($type, self::$supportedEncryptionTypes)) {
+                               return $type;
+                       }
+               }
+               
+               return 'unknown';
+       }
+       
+       /**
+        * Returns a double salted bcrypt hash.
+        * 
+        * @param       string          $password
+        * @param       string          $salt
+        * @return      string
+        */
+       public static function getDoubleSaltedHash($password, $salt = null) {
+               if ($salt === null) {
+                       $salt = self::getRandomSalt();
+               }
+               
+               return self::getSaltedHash(self::getSaltedHash($password, $salt), $salt);
+       }
+       
+       /**
+        * Returns a simple salted bcrypt hash.
+        * 
+        * @param       string          $password
+        * @param       string          $salt
+        * @return      string
+        */
+       public static function getSaltedHash($password, $salt = null) {
+               if ($salt === null) {
+                       $salt = self::getRandomSalt();
+               }
+               
+               return crypt($password, self::getSalt($salt));
+       }
+       
+       /**
+        * Returns a random blowfish-compatible salt.
+        * 
+        * @return      string
+        */
+       public static function getRandomSalt() {
+               $salt = '';
+               
+               for ($i = 0, $maxIndex = (strlen(self::$blowfishCharacters) - 1); $i < 22; $i++) {
+                       $salt .= self::$blowfishCharacters[mt_rand(0, $maxIndex)];
+               }
+               
+               return $salt;
+       }
+       
+       /**
+        * Generates a random user password with the given character length.
+        * 
+        * @param       integer         $length
+        * @return      string
+        */
+       public static function getRandomPassword($length = 8) {
+               $availableCharacters = array(
+                       'abcdefghijklmnopqrstuvwxyz',
+                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+                       '0123456789',
+                       '+#-.,;:?!'
+               );
+               
+               $password = '';
+               $type = 0;
+               for ($i = 0; $i < $length; $i++) {
+                       $type = ($i % 4 == 0) ? 0 : ($type + 1);
+                       $password .= substr($availableCharacters[$type], MathUtil::getRandomValue(0, strlen($availableCharacters[$type]) - 1), 1);
+               }
+               
+               return str_shuffle($password);
+       }
+       
+       /**
+        * Returns a blowfish salt, e.g. $2a$07$usesomesillystringforsalt$
+        * 
+        * @param       string          $salt
+        * @return      string
+        */
+       protected static function getSalt($salt) {
+               $salt = StringUtil::substring($salt, 0, 22);
+               
+               return '$' . self::BCRYPT_TYPE . '$' . self::BCRYPT_COST . '$' . $salt;
+       }
+       
+       /**
+        * Validates the password hash for Invision Power Board 2.x (ipb2).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function ipb2($username, $password, $salt, $dbHash) {
+               return self::vb3($username, $password, $salt, $dbHash);
+       }
+       
+       /**
+        * Validates the password hash for Invision Power Board 3.x (ipb3).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function ipb3($username, $password, $salt, $dbHash) {
+               return ($dbHash == md5(md5($salt) . md5($password)));
+       }
+       
+       /**
+        * Validates the password hash for MyBB 1.x (mybb1).
+        *
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function mybb1($username, $password, $salt, $dbHash) {
+               return ($dbHash == md5(md5($salt) . md5($password)));
+       }
+       
+       /**
+        * Validates the password hash for Simple Machines Forums 1.x (smf1).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function smf1($username, $password, $salt, $dbHash) {
+               return ($dbHash == sha1(StringUtil::toLowerCase($username) . $password));
+       }
+       
+       /**
+        * Validates the password hash for Simple Machines Forums 2.x (smf2).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function smf2($username, $password, $salt, $dbHash) {
+               return self::smf1($username, $password, $salt, $dbHash);
+       }
+       
+       /**
+        * Validates the password hash for vBulletin 3 (vb3).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function vb3($username, $password, $salt, $dbHash) {
+               return ($dbHash == md5(md5($password) . $salt));
+       }
+       
+       /**
+        * Validates the password hash for vBulletin 4 (vb4).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function vb4($username, $password, $salt, $dbHash) {
+               return self::vb3($username, $password, $salt, $dbHash);
+       }
+       
+       /**
+        * Validates the password hash for vBulletin 5 (vb5).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function vb5($username, $password, $salt, $dbHash) {
+               return self::vb3($username, $password, $salt, $dbHash);
+       }
+       
+       /**
+        * Validates the password hash for WoltLab Burning Board 2 (wbb2).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function wbb2($username, $password, $salt, $dbHash) {
+               if ($dbHash == md5($password)) {
+                       return true;
+               }
+               else if ($dbHash == sha1($password)) {
+                       return true;
+               }
+               
+               return false;
+       }
+       
+       /**
+        * Validates the password hash for WoltLab Community Framework 1.x (wcf1).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function wcf1($username, $password, $salt, $dbHash) {
+               return ($dbHash == sha1($salt . sha1($salt . sha1($password))));
+       }
+       
+       /**
+        * Validates the password hash for WoltLab Community Framework 2.x (wcf2).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function wcf2($username, $password, $salt, $dbHash) {
+               return ($dbHash == self::getDoubleSaltedHash($password, $salt));
+       }
+       
+       /**
+        * Validates the password hash for XenForo 1.x with (xf1).
+        * 
+        * @param       string          $username
+        * @param       string          $password
+        * @param       string          $salt
+        * @param       string          $dbHash
+        * @return      boolean
+        */
+       protected static function xf1($username, $password, $salt, $dbHash) {
+               if ($dbHash == sha1(sha1($password) . $salt)) {
+                       return true;
+               }
+               else if (extension_loaded('hash')) {
+                       return ($dbHash == hash('sha256', hash('sha256', $password) . $salt));
+               }
+               
+               return false;
+       }
+       
+       private function __construct() { }
+}
index ac6fe33f5e2768f251a2d7dc83d8d75f0b151d4b..f2511f764b8bbb43134201802bd825ffde8432ad 100644 (file)
@@ -25,70 +25,6 @@ final class StringUtil {
         */
        const HELLIP = "\xE2\x80\xA6";
        
-       /**
-        * Returns a salted hash of the given value.
-        * 
-        * @param       string          $value
-        * @param       string          $salt
-        * @return      string
-        */
-       public static function getSaltedHash($value, $salt) {
-               if (!defined('ENCRYPTION_ENABLE_SALTING') || ENCRYPTION_ENABLE_SALTING) {
-                       $hash = '';
-                       // salt
-                       if (!defined('ENCRYPTION_SALT_POSITION') || ENCRYPTION_SALT_POSITION == 'before') {
-                               $hash .= $salt;
-                       }
-                       
-                       // value
-                       if (!defined('ENCRYPTION_ENCRYPT_BEFORE_SALTING') || ENCRYPTION_ENCRYPT_BEFORE_SALTING) {
-                               $hash .= self::encrypt($value);
-                       }
-                       else {
-                               $hash .= $value;
-                       }
-                       
-                       // salt
-                       if (defined('ENCRYPTION_SALT_POSITION') && ENCRYPTION_SALT_POSITION == 'after') {
-                               $hash .= $salt;
-                       }
-                       
-                       return self::encrypt($hash);
-               }
-               else {
-                       return self::encrypt($value);
-               }
-       }
-       
-       /**
-        * Returns a double salted hash of the given value.
-        * 
-        * @param       string          $value
-        * @param       string          $salt
-        * @return      string
-        */
-       public static function getDoubleSaltedHash($value, $salt) {
-               return self::encrypt($salt . self::getSaltedHash($value, $salt));
-       }
-       
-       /**
-        * Encrypts the given value.
-        * 
-        * @param       string          $value
-        * @return      string
-        */
-       public static function encrypt($value) {
-               if (defined('ENCRYPTION_METHOD')) {
-                       switch (ENCRYPTION_METHOD) {
-                               case 'sha1': return sha1($value);
-                               case 'md5': return md5($value);
-                               case 'crc32': return crc32($value);
-                               case 'crypt': return crypt($value);
-                       }
-               }
-               return sha1($value);
-       }
-       
        /**
         * Alias to php sha1() function.
         * 
@@ -736,29 +672,5 @@ final class StringUtil {
                return mb_ereg_replace('.{'.$length.'}', "\\0".$break, $string);
        }
        
-       /**
-        * Generates a random user password with the given character length.
-        *
-        * @param       integer         $length
-        * @return      string          new password
-        */
-       public static function getRandomPassword($length = 8) {
-               $availableCharacters = array(
-                       0 => 'abcdefghijklmnopqrstuvwxyz',
-                       1 => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
-                       2 => '0123456789',
-                       3 => '+#-.,;:?!'
-               );
-               
-               $password = '';
-               $type = 0;
-               for ($i = 0; $i < $length; $i++) {
-                       $type = ($i % 4 == 0) ? 0 : ($type + 1);
-                       $password .= substr($availableCharacters[$type], MathUtil::getRandomValue(0, strlen($availableCharacters[$type]) - 1), 1);
-               }
-               
-               return str_shuffle($password);
-       }
-       
        private function __construct() { }
 }
index 6c26a1f323a40e691e69dbbcfcbb9f8d0b614302..3c36af65c1aa38e3603a6331a65af8db95dad46b 100644 (file)
@@ -632,8 +632,7 @@ CREATE TABLE wcf1_user (
        userID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(255) NOT NULL DEFAULT '',
        email VARCHAR(255) NOT NULL DEFAULT '',
-       password VARCHAR(40) NOT NULL DEFAULT '',
-       salt VARCHAR(40) NOT NULL DEFAULT '',
+       password VARCHAR(100) NOT NULL DEFAULT '',
        accessToken CHAR(40) NOT NULL DEFAULT '',
        languageID INT(10) NOT NULL DEFAULT 0,
        registrationDate INT(10) NOT NULL DEFAULT 0,