diff options
Diffstat (limited to 'Core')
-rw-r--r-- | Core/Authentication/RememberMe/TokenProviderInterface.php | 5 | ||||
-rw-r--r-- | Core/Authentication/Token/AbstractToken.php | 4 | ||||
-rw-r--r-- | Core/Encoder/BCryptPasswordEncoder.php | 117 | ||||
-rw-r--r-- | Core/Encoder/Pbkdf2PasswordEncoder.php | 2 | ||||
-rw-r--r-- | Core/User/ChainUserProvider.php | 8 | ||||
-rw-r--r-- | Core/Validator/Constraint/UserPassword.php | 29 | ||||
-rw-r--r-- | Core/Validator/Constraint/UserPasswordValidator.php | 29 |
7 files changed, 40 insertions, 154 deletions
diff --git a/Core/Authentication/RememberMe/TokenProviderInterface.php b/Core/Authentication/RememberMe/TokenProviderInterface.php index 0c6f75e..44bf4b0 100644 --- a/Core/Authentication/RememberMe/TokenProviderInterface.php +++ b/Core/Authentication/RememberMe/TokenProviderInterface.php @@ -21,11 +21,11 @@ interface TokenProviderInterface /** * Loads the active token for the given series. * - * @throws TokenNotFoundException if the token is not found - * * @param string $series * * @return PersistentTokenInterface + * + * @throws TokenNotFoundException if the token is not found */ public function loadTokenBySeries($series); @@ -42,6 +42,7 @@ interface TokenProviderInterface * @param string $series * @param string $tokenValue * @param \DateTime $lastUsed + * @throws TokenNotFoundException if the token is not found */ public function updateToken($series, $tokenValue, \DateTime $lastUsed); diff --git a/Core/Authentication/Token/AbstractToken.php b/Core/Authentication/Token/AbstractToken.php index f21aa76..1d65819 100644 --- a/Core/Authentication/Token/AbstractToken.php +++ b/Core/Authentication/Token/AbstractToken.php @@ -91,7 +91,7 @@ abstract class AbstractToken implements TokenInterface public function setUser($user) { if (!($user instanceof UserInterface || (is_object($user) && method_exists($user, '__toString')) || is_string($user))) { - throw new \InvalidArgumentException('$user must be an instanceof of UserInterface, an object implementing a __toString method, or a primitive string.'); + throw new \InvalidArgumentException('$user must be an instanceof UserInterface, an object implementing a __toString method, or a primitive string.'); } if (null === $this->user) { @@ -190,7 +190,7 @@ abstract class AbstractToken implements TokenInterface } /** - * Returns a attribute value. + * Returns an attribute value. * * @param string $name The attribute name * diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php index 1b7572d..a355421 100644 --- a/Core/Encoder/BCryptPasswordEncoder.php +++ b/Core/Encoder/BCryptPasswordEncoder.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Security\Core\Encoder; use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; -use Symfony\Component\Security\Core\Util\SecureRandomInterface; /** * @author Elnur Abdurrakhimov <elnur@elnur.pro> @@ -21,128 +20,64 @@ use Symfony\Component\Security\Core\Util\SecureRandomInterface; class BCryptPasswordEncoder extends BasePasswordEncoder { /** - * @var SecureRandomInterface - */ - private $secureRandom; - - /** * @var string */ private $cost; - private static $prefix = null; - /** * Constructor. * - * @param SecureRandomInterface $secureRandom A SecureRandomInterface instance - * @param integer $cost The algorithmic cost that should be used + * @param integer $cost The algorithmic cost that should be used * * @throws \InvalidArgumentException if cost is out of range */ - public function __construct(SecureRandomInterface $secureRandom, $cost) + public function __construct($cost) { - $this->secureRandom = $secureRandom; + if (!function_exists('password_hash')) { + throw new \RuntimeException('To use the BCrypt encoder, you need to upgrade to PHP 5.5 or install the "ircmaxell/password-compat" via Composer.'); + } $cost = (int) $cost; if ($cost < 4 || $cost > 31) { throw new \InvalidArgumentException('Cost must be in the range of 4-31.'); } - $this->cost = sprintf('%02d', $cost); - - if (!self::$prefix) { - self::$prefix = '$'.(version_compare(phpversion(), '5.3.7', '>=') ? '2y' : '2a').'$'; - } - } - - /** - * {@inheritdoc} - */ - public function encodePassword($raw, $salt) - { - if (function_exists('password_hash')) { - return password_hash($raw, PASSWORD_BCRYPT, array('cost' => $this->cost)); - } - - $salt = self::$prefix.$this->cost.'$'.$this->encodeSalt($this->getRawSalt()); - $encoded = crypt($raw, $salt); - if (!is_string($encoded) || strlen($encoded) <= 13) { - return false; - } - - return $encoded; - } - - /** - * {@inheritdoc} - */ - public function isPasswordValid($encoded, $raw, $salt) - { - if (function_exists('password_verify')) { - return password_verify($raw, $encoded); - } - $crypted = crypt($raw, $encoded); - if (strlen($crypted) <= 13) { - return false; - } - - return $this->comparePasswords($encoded, $crypted); + $this->cost = sprintf('%02d', $cost); } /** - * Encodes the salt to be used by Bcrypt. + * Encodes the raw password. * - * The blowfish/bcrypt algorithm used by PHP crypt expects a different - * set and order of characters than the usual base64_encode function. - * Regular b64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ - * Bcrypt b64: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 - * We care because the last character in our encoded string will - * only represent 2 bits. While two known implementations of - * bcrypt will happily accept and correct a salt string which - * has the 4 unused bits set to non-zero, we do not want to take - * chances and we also do not want to waste an additional byte - * of entropy. + * It doesn't work with PHP versions lower than 5.3.7, since + * the password compat library uses CRYPT_BLOWFISH hash type with + * the "$2y$" salt prefix (which is not available in the early PHP versions). + * @see https://github.com/ircmaxell/password_compat/issues/10#issuecomment-11203833 * - * @param bytes $random a string of 16 random bytes + * It is almost best to **not** pass a salt and let PHP generate one for you. * - * @return string Properly encoded salt to use with php crypt function + * @param string $raw The password to encode + * @param string $salt The salt * - * @throws \InvalidArgumentException if string of random bytes is too short + * @return string The encoded password + * + * @link http://lxr.php.net/xref/PHP_5_5/ext/standard/password.c#111 */ - protected function encodeSalt($random) + public function encodePassword($raw, $salt) { - $len = strlen($random); - if ($len < 16) { - throw new \InvalidArgumentException('The bcrypt salt needs 16 random bytes.'); - } - if ($len > 16) { - $random = substr($random, 0, 16); - } + $options = array('cost' => $this->cost); - $base64raw = str_replace('+', '.', base64_encode($random)); - $salt128bit = substr($base64raw, 0, 21); - $lastchar = substr($base64raw, 21, 1); - $lastchar = strtr($lastchar, 'AQgw', '.Oeu'); - $salt128bit .= $lastchar; + if ($salt) { + $options['salt'] = $salt; + } - return $salt128bit; + return password_hash($raw, PASSWORD_BCRYPT, $options); } /** - * @return bytes 16 random bytes to be used in the salt + * {@inheritdoc} */ - protected function getRawSalt() + public function isPasswordValid($encoded, $raw, $salt) { - $rawSalt = false; - $numBytes = 16; - if (function_exists('mcrypt_create_iv')) { - $rawSalt = mcrypt_create_iv($numBytes, MCRYPT_DEV_URANDOM); - } - if (!$rawSalt) { - $rawSalt = $this->secureRandom->nextBytes($numBytes); - } - - return $rawSalt; + return password_verify($raw, $encoded); } } diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php index 656545f..4f37ba3 100644 --- a/Core/Encoder/Pbkdf2PasswordEncoder.php +++ b/Core/Encoder/Pbkdf2PasswordEncoder.php @@ -82,7 +82,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder $digest = ''; for ($i = 1; $i <= $blocks; $i++) { - $ib = $block = hash_hmac($algorithm, $salt . pack('N', $i), $password, true); + $ib = $block = hash_hmac($algorithm, $salt.pack('N', $i), $password, true); // Iterations for ($j = 1; $j < $iterations; $j++) { diff --git a/Core/User/ChainUserProvider.php b/Core/User/ChainUserProvider.php index 3ff1ea9..fc72074 100644 --- a/Core/User/ChainUserProvider.php +++ b/Core/User/ChainUserProvider.php @@ -32,6 +32,14 @@ class ChainUserProvider implements UserProviderInterface } /** + * @return array + */ + public function getProviders() + { + return $this->providers; + } + + /** * {@inheritDoc} */ public function loadUserByUsername($username) diff --git a/Core/Validator/Constraint/UserPassword.php b/Core/Validator/Constraint/UserPassword.php deleted file mode 100644 index 93ca24d..0000000 --- a/Core/Validator/Constraint/UserPassword.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Validator\Constraint; - -use Symfony\Component\Security\Core\Validator\Constraints\UserPassword as BaseUserPassword; - -/** - * @Annotation - * - * @deprecated Deprecated since version 2.2, to be removed in 2.3. - */ -class UserPassword extends BaseUserPassword -{ - public function __construct($options = null) - { - trigger_error('UserPassword class in Symfony\Component\Security\Core\Validator\Constraint namespace is deprecated since version 2.2 and will be removed in 2.3. Use the Symfony\Component\Security\Core\Validator\Constraints\UserPassword class instead.', E_USER_DEPRECATED); - - parent::__construct($options); - } -} diff --git a/Core/Validator/Constraint/UserPasswordValidator.php b/Core/Validator/Constraint/UserPasswordValidator.php deleted file mode 100644 index 0195fe5..0000000 --- a/Core/Validator/Constraint/UserPasswordValidator.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Core\Validator\Constraint; - -use Symfony\Component\Security\Core\SecurityContextInterface; -use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; -use Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator as BaseUserPasswordValidator; - -/** - * @deprecated Deprecated since version 2.2, to be removed in 2.3. - */ -class UserPasswordValidator extends BaseUserPasswordValidator -{ - public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory) - { - trigger_error('UserPasswordValidator class in Symfony\Component\Security\Core\Validator\Constraint namespace is deprecated since version 2.2 and will be removed in 2.3. Use the Symfony\Component\Security\Core\Validator\Constraints\UserPasswordValidator class instead.', E_USER_DEPRECATED); - - parent::__construct($securityContext, $encoderFactory); - } -} |