mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-06 10:03:26 -08:00
[Server] Store a scrypt verifier when an admin resets a password (#7679)
The temporary password was written as a legacy salt+hash row, which makes the next login look like an authentication downgrade. A client holding a saved verifier refuses that downgrade, so the reset locked the account out of every modern client. Store the verifier and, where security/legacy_backup_key is configured, keep a sealed legacy hash of the same temporary password as the downgrade backup, so pre-challenge clients keep the credential path the reset used to provide. Without the key no row shape serves both: the verifier and the legacy hash cannot share one column, so those clients have no path at all. Warn at reset time that the new password has no pre-challenge path, and say so in servatrice.ini.example instead of promising that a reset gets them back in. Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
e08402ac94
commit
ef4574d2b9
4 changed files with 91 additions and 16 deletions
|
|
@ -2641,7 +2641,15 @@ Response::ResponseCode AbstractServerSocketInterface::cmdResetUserPassword(const
|
|||
}
|
||||
|
||||
const QString tempPassword = PasswordHasher::generateRandomSalt();
|
||||
if (!sqlInterface->changeUserPassword(userName, tempPassword, true)) {
|
||||
// Store a scrypt verifier rather than a legacy salt+hash: a legacy row makes the next
|
||||
// login look like an authentication downgrade, which modern clients refuse when they
|
||||
// still hold a verifier for the account. Where security/legacy_backup_key is configured,
|
||||
// keep a sealed legacy hash of the same temporary password as the downgrade backup so
|
||||
// pre-challenge clients keep the path the reset used to provide; without the key they
|
||||
// have none, which changeUserPasswordWithLegacyBackup warns about.
|
||||
const QString verifier = PasswordHasher::generatePasswordVerifier(tempPassword);
|
||||
const QString legacyCredential = PasswordHasher::computeHash(tempPassword, PasswordHasher::generateRandomSalt());
|
||||
if (!sqlInterface->changeUserPasswordWithLegacyBackup(userName, verifier, legacyCredential)) {
|
||||
return Response::RespInternalError;
|
||||
}
|
||||
sqlInterface->setForcePasswordChange(userName, true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue