/** * Generates an encrypted random token. * @param \Member $user * @throws \PasswordEncryptor_NotFoundException * @return string */ public static function generate_token($user) { $generator = new \RandomGenerator(); $tokenString = $generator->randomToken(); $e = \PasswordEncryptor::create_for_algorithm('blowfish'); $salt = $e->salt($tokenString); $token = sha1($e->encrypt($tokenString, $salt)) . substr(md5($user->Created . $user->LastEdited . $user->ID), 7); return $token; }
/** * See http://open.silverstripe.org/ticket/3004 * * Handy command for reproducing via CLI on different architectures: * php -r "echo(base_convert(sha1('mypassword'), 16, 36));" */ function testEncrytorLegacyPHPHashCompare() { Config::inst()->update('PasswordEncryptor', 'encryptors', array('test_sha1legacy'=>array('PasswordEncryptor_LegacyPHPHash'=>'sha1'))); $e = PasswordEncryptor::create_for_algorithm('test_sha1legacy'); // precomputed hashes for 'mypassword' from different architectures $amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s'; $intelHash = 'h1fj0a6m4o0g04ocg00o4kwoc4wowws'; $wrongHash = 'h1fjxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $this->assertTrue($e->compare($amdHash, $intelHash)); $this->assertFalse($e->compare($amdHash, $wrongHash)); }
/** * See http://open.silverstripe.org/ticket/3004 * * Handy command for reproducing via CLI on different architectures: * php -r "echo(base_convert(sha1('mypassword'), 16, 36));" */ function testEncrytorLegacyPHPHashCompare() { PasswordEncryptor::register('test_sha1legacy', 'PasswordEncryptor_LegacyPHPHash("sha1")'); $e = PasswordEncryptor::create_for_algorithm('test_sha1legacy'); // precomputed hashes for 'mypassword' from different architectures $amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s'; $intelHash = 'h1fj0a6m4o0g04ocg00o4kwoc4wowws'; $wrongHash = 'h1fjxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $this->assertTrue($e->compare($amdHash, $intelHash)); $this->assertFalse($e->compare($amdHash, $wrongHash)); }
function testNoLegacyPasswordHashMigrationOnIncompatibleAlgorithm() { PasswordEncryptor::register('crc32', 'PasswordEncryptor_PHPHash("crc32")'); $field = Member::get_unique_identifier_field(); $member = new Member(); $member->{$field} = '*****@*****.**'; $member->PasswordEncryption = "crc32"; $member->Password = "******"; $member->write(); $data = array('Email' => $member->{$field}, 'Password' => 'mypassword'); MemberAuthenticator::authenticate($data); $member = DataObject::get_by_id('Member', $member->ID); $this->assertEquals($member->PasswordEncryption, "crc32"); $result = $member->checkPassword('mypassword'); $this->assertTrue($result->valid()); }
/** * Changes a users password * @param {stdClass} $data Data passed from ActionScript * @return {array} Returns a standard response array */ public function changePassword($data) { $response = CodeBank_ClientAPI::responseBase(); try { $member = Member::currentUser(); $e = PasswordEncryptor::create_for_algorithm($member->PasswordEncryption); if (!$e->check($member->Password, $data->currPassword, $member->Salt, $member)) { $response['status'] = 'EROR'; $response['message'] = _t('CodeBankAPI.CURRENT_PASSWORD_MATCH', '_Current password does not match'); return $response; } if (!$member->changePassword($data->password)) { $response['status'] = 'EROR'; $response['message'] = _t('CodeBankAPI.NEW_PASSWORD_NOT_VALID', '_New password is not valid'); return $response; } $response['status'] = 'HELO'; $response['message'] = _t('CodeBankAPI.PASSWORD_CHANGED', '_User\'s password changed successfully'); } catch (Exception $e) { $response['status'] = 'EROR'; $response['message'] = _t('CodeBankAPI.SERVER_ERROR', '_Server error has occured, please try again later'); } return $response; }
/** * Utility for generating secure password hashes for this member. */ public function encryptWithUserSettings($string) { if (!$string) { return null; } // If the algorithm or salt is not available, it means we are operating // on legacy account with unhashed password. Do not hash the string. if (!$this->PasswordEncryption) { return $string; } // We assume we have PasswordEncryption and Salt available here. $e = PasswordEncryptor::create_for_algorithm($this->PasswordEncryption); return $e->encrypt($string, $this->Salt); }
/** * Encrypt a password according to the current password encryption settings. * If the settings are so that passwords shouldn't be encrypted, the * result is simple the clear text password with an empty salt except when * a custom algorithm ($algorithm parameter) was passed. * * @param string $password The password to encrypt * @param string $salt Optional: The salt to use. If it is not passed, but * needed, the method will automatically create a * random salt that will then be returned as return value. * @param string $algorithm Optional: Use another algorithm to encrypt the * password (so that the encryption algorithm can be changed over the time). * @param Member $member Optional * @return mixed Returns an associative array containing the encrypted * password and the used salt in the form: * <code> * array( * 'password' => string, * 'salt' => string, * 'algorithm' => string, * 'encryptor' => PasswordEncryptor instance * ) * </code> * If the passed algorithm is invalid, FALSE will be returned. * * @see encrypt_passwords() */ public static function encrypt_password($password, $salt = null, $algorithm = null, $member = null) { // Fall back to the default encryption algorithm if (!$algorithm) { $algorithm = self::config()->password_encryption_algorithm; } $e = PasswordEncryptor::create_for_algorithm($algorithm); // New salts will only need to be generated if the password is hashed for the first time $salt = $salt ? $salt : $e->salt($password); return array('password' => $e->encrypt($password, $salt, $member), 'salt' => $salt, 'algorithm' => $algorithm, 'encryptor' => $e); }
/** * Check if the given password is the same as the one stored in this record. * See {@link Member->checkPassword()}. * * @param String $password Cleartext password * @return Boolean */ public function checkPassword($password) { $e = PasswordEncryptor::create_for_algorithm($this->PasswordEncryption); return $e->check($this->Password, $password, $this->Salt, $this->Member()); }
/** * Generates an encrypted random token * and an expiry date * * @param boolean $expired Set to true to generate an outdated token * @return array token data array('token' => HASH, 'expire' => EXPIRY_DATE) */ private function generateToken($expired = false) { $life = $this->tokenConfig['life']; if (!$expired) { $expire = time() + $life; } else { $expire = time() - $life * 2; } $generator = new RandomGenerator(); $tokenString = $generator->randomToken(); $e = PasswordEncryptor::create_for_algorithm('blowfish'); //blowfish isn't URL safe and maybe too long? $salt = $e->salt($tokenString); $token = $e->encrypt($tokenString, $salt); return array('token' => substr($token, 7), 'expire' => $expire); }
/** * Encrypt a password according to the current password encryption settings. * If the settings are so that passwords shouldn't be encrypted, the * result is simple the clear text password with an empty salt except when * a custom algorithm ($algorithm parameter) was passed. * * @param string $password The password to encrypt * @param string $salt Optional: The salt to use. If it is not passed, but * needed, the method will automatically create a * random salt that will then be returned as return value. * @param string $algorithm Optional: Use another algorithm to encrypt the * password (so that the encryption algorithm can be changed over the time). * @param Member $member Optional * @return mixed Returns an associative array containing the encrypted * password and the used salt in the form: * <code> * array( * 'password' => string, * 'salt' => string, * 'algorithm' => string, * 'encryptor' => PasswordEncryptor instance * ) * </code> * If the passed algorithm is invalid, FALSE will be returned. * * @see encrypt_passwords() * @see set_password_encryption_algorithm() */ static function encrypt_password($password, $salt = null, $algorithm = null, $member = null) { if (strlen(trim($password)) == 0 || !$algorithm && self::$encryptPasswords == false) { $algorithm = 'none'; } else { // Fall back to the default encryption algorithm if (!$algorithm) { $algorithm = self::$encryptionAlgorithm; } } $e = PasswordEncryptor::create_for_algorithm($algorithm); // New salts will only need to be generated if the password is hashed for the first time $salt = $salt ? $salt : $e->salt($password); return array('password' => $e->encrypt($password, $salt, $member), 'salt' => $salt, 'algorithm' => $algorithm, 'encryptor' => $e); }
/** * Check if the passed password matches the stored one (if the member is not locked out). * * @param string $password * @return ValidationResult */ public function checkPassword($password) { $result = $this->canLogIn(); $e = PasswordEncryptor::create_for_algorithm($this->PasswordEncryption); if (!$e->check($this->Password, $password, $this->Salt, $this)) { $result->error(_t('Member.ERRORWRONGCRED', 'That doesn\'t seem to be the right e-mail address or password. Please try again.')); } return $result; }
*/ define('MCE_ROOT', 'sapphire/thirdparty/tinymce/'); /** * The secret key that needs to be sent along with pings to /Email_BounceHandler * * Change this to something different for increase security (you can * override it in mysite/_config.php to ease upgrades). * For more information see: * {@link http://doc.silverstripe.org/doku.php?id=email_bouncehandler} */ if (!defined('EMAIL_BOUNCEHANDLER_KEY')) { define('EMAIL_BOUNCEHANDLER_KEY', '1aaaf8fb60ea253dbf6efa71baaacbb3'); } PasswordEncryptor::register('none', 'PasswordEncryptor_None'); PasswordEncryptor::register('md5', 'PasswordEncryptor_LegacyPHPHash("md5")'); PasswordEncryptor::register('sha1', 'PasswordEncryptor_LegacyPHPHash("sha1")'); PasswordEncryptor::register('md5_v2.4', 'PasswordEncryptor_PHPHash("md5")'); PasswordEncryptor::register('sha1_v2.4', 'PasswordEncryptor_PHPHash("sha1")'); // Zend_Cache temp directory setting $_ENV['TMPDIR'] = TEMP_FOLDER; // for *nix $_ENV['TMP'] = TEMP_FOLDER; // for Windows $aggregatecachedir = TEMP_FOLDER . DIRECTORY_SEPARATOR . 'aggregate_cache'; if (!is_dir($aggregatecachedir)) { mkdir($aggregatecachedir); } SS_Cache::add_backend('aggregatestore', 'File', array('cache_dir' => $aggregatecachedir)); SS_Cache::pick_backend('aggregatestore', 'aggregate', 1000); // TODO Remove once new ManifestBuilder with submodule support is in place require_once 'admin/_config.php';
/** * Encrypt a password according to the current password encryption settings. * If the settings are so that passwords shouldn't be encrypted, the * result is simple the clear text password with an empty salt except when * a custom algorithm ($algorithm parameter) was passed. * * @param string $password The password to encrypt * @param string $salt Optional: The salt to use. If it is not passed, but * needed, the method will automatically create a * random salt that will then be returned as return value. * @param string $algorithm Optional: Use another algorithm to encrypt the * password (so that the encryption algorithm can be changed over the time). * @param Member $member Optional * @return mixed Returns an associative array containing the encrypted * password and the used salt in the form: * <code> * array( * 'password' => string, * 'salt' => string, * 'algorithm' => string, * 'encryptor' => PasswordEncryptor instance * ) * </code> * If the passed algorithm is invalid, FALSE will be returned. * * @see encrypt_passwords() * @see set_password_encryption_algorithm() */ static function encrypt_password($password, $salt = null, $algorithm = null, $member = null) { if( // if the password is empty, don't encrypt strlen(trim($password)) == 0 // if no algorithm is provided and no default is set, don't encrypt || (!$algorithm) ) { $algorithm = 'none'; } else { // Fall back to the default encryption algorithm if(!$algorithm) $algorithm = self::$encryptionAlgorithm; } $e = PasswordEncryptor::create_for_algorithm($algorithm); // New salts will only need to be generated if the password is hashed for the first time $salt = ($salt) ? $salt : $e->salt($password); return array( 'password' => $e->encrypt($password, $salt, $member), 'salt' => $salt, 'algorithm' => $algorithm, 'encryptor' => $e ); }