summaryrefslogtreecommitdiffstats
path: root/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Core')
-rw-r--r--Core/Authentication/RememberMe/TokenProviderInterface.php5
-rw-r--r--Core/Authentication/Token/AbstractToken.php4
-rw-r--r--Core/Encoder/BCryptPasswordEncoder.php117
-rw-r--r--Core/Encoder/Pbkdf2PasswordEncoder.php2
-rw-r--r--Core/User/ChainUserProvider.php8
-rw-r--r--Core/Validator/Constraint/UserPassword.php29
-rw-r--r--Core/Validator/Constraint/UserPasswordValidator.php29
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);
- }
-}