|
|
|
@ -127,11 +127,77 @@ class UserManager |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @param string $raw |
|
|
|
|
* Detects and returns the type of encryption of the given encrypted |
|
|
|
|
* password. |
|
|
|
|
* |
|
|
|
|
* @return string |
|
|
|
|
* @param string $encoded The encrypted password |
|
|
|
|
* @param string $salt The user salt, if any |
|
|
|
|
*/ |
|
|
|
|
public static function detectPasswordEncryption(string $encoded, string $salt): bool |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
$encryption = false; |
|
|
|
|
|
|
|
|
|
$length = strlen($encoded); |
|
|
|
|
|
|
|
|
|
$pattern = '/^\$2y\$04\$[A-Za-z0-9\.\/]{53}$/'; |
|
|
|
|
|
|
|
|
|
if ( $length == 60 && preg_match($pattern, $encoded)) { |
|
|
|
|
$encryption = 'bcrypt'; |
|
|
|
|
} |
|
|
|
|
elseif ( $length == 32 && ctype_xdigit($encoded) ) { |
|
|
|
|
$encryption = 'md5'; |
|
|
|
|
} |
|
|
|
|
elseif ( $length == 40 && ctype_xdigit($encoded) ) { |
|
|
|
|
$encryption = 'sha1'; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$start = strpos($encoded, '{'); |
|
|
|
|
if ($start !== false && substr($encoded, -1, 1) == '}') { |
|
|
|
|
if (substr($encoded,$start + 1,-1) == $salt) { |
|
|
|
|
$encryption = 'none'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $encryption; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Checks if the password is correct for this user. |
|
|
|
|
* If the password_conversion setting is true, also update the password |
|
|
|
|
* in the database to a new encryption method. |
|
|
|
|
* |
|
|
|
|
* @param string $encoded Encrypted password |
|
|
|
|
* @param string $raw Clear password given through login form |
|
|
|
|
* @param string $salt User salt, if any |
|
|
|
|
* @param int $userId The user's internal ID |
|
|
|
|
*/ |
|
|
|
|
public static function checkPassword(string $encoded, string $raw, string $salt, int $userId): bool |
|
|
|
|
{ |
|
|
|
|
$result = false; |
|
|
|
|
|
|
|
|
|
if (true === api_get_configuration_value('password_conversion')) { |
|
|
|
|
$detectedEncryption = self::detectPasswordEncryption($encoded, $salt); |
|
|
|
|
if (self::getPasswordEncryption() != $detectedEncryption) { |
|
|
|
|
$encoder = new \Chamilo\UserBundle\Security\Encoder($detectedEncryption); |
|
|
|
|
$result = $encoder->isPasswordValid($encoded, $raw, $salt); |
|
|
|
|
if ($result) { |
|
|
|
|
self::updatePassword($userId, $raw); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
return self::isPasswordValid($encoded, $raw, $salt); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return $result; |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* Encrypt the password using the current encoder |
|
|
|
|
* |
|
|
|
|
* @param string $raw The clear password |
|
|
|
|
*/ |
|
|
|
|
public static function encryptPassword($raw, User $user) |
|
|
|
|
public static function encryptPassword(string $raw, User $user): string |
|
|
|
|
{ |
|
|
|
|
$encoder = self::getEncoder($user); |
|
|
|
|
|
|
|
|
@ -142,10 +208,11 @@ class UserManager |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @param int $userId |
|
|
|
|
* @param string $password |
|
|
|
|
* Update the password of the given user to the given (in-clear) password |
|
|
|
|
* @param int $userId Internal user ID |
|
|
|
|
* @param string $password Password in clear |
|
|
|
|
*/ |
|
|
|
|
public static function updatePassword($userId, $password) |
|
|
|
|
public static function updatePassword(int $userId, string $password): void |
|
|
|
|
{ |
|
|
|
|
$repository = self::getRepository(); |
|
|
|
|
/** @var User $user */ |
|
|
|
|