aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Authentication/Token
diff options
context:
space:
mode:
authorChristoph Wurst <christoph@winzerhof-wurst.at>2023-04-11 17:27:57 +0200
committerChristoph Wurst <christoph@winzerhof-wurst.at>2023-04-12 15:55:42 +0200
commit5eb768ac5eaf0a502a32165b90040edd8c65fcd2 (patch)
tree0d1af0862261f692b7583ee8da0b63ecc8ffb172 /lib/private/Authentication/Token
parent73000175d097a5d04cfa9abcfc964fd641ba2021 (diff)
downloadnextcloud-server-5eb768ac5eaf0a502a32165b90040edd8c65fcd2.tar.gz
nextcloud-server-5eb768ac5eaf0a502a32165b90040edd8c65fcd2.zip
fix(auth): Run token statements in atomic transaction
All or nothing Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib/private/Authentication/Token')
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php106
1 files changed, 55 insertions, 51 deletions
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 824e2e056c8..b1fa509d8c0 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -327,18 +327,20 @@ class PublicKeyTokenProvider implements IProvider {
throw new InvalidTokenException("Invalid token type");
}
- // When changing passwords all temp tokens are deleted
- $this->mapper->deleteTempToken($token);
-
- // Update the password for all tokens
- $tokens = $this->mapper->getTokenByUser($token->getUID());
- $hashedPassword = $this->hashPassword($password);
- foreach ($tokens as $t) {
- $publicKey = $t->getPublicKey();
- $t->setPassword($this->encryptPassword($password, $publicKey));
- $t->setPasswordHash($hashedPassword);
- $this->updateToken($t);
- }
+ $this->atomic(function () use ($password, $token) {
+ // When changing passwords all temp tokens are deleted
+ $this->mapper->deleteTempToken($token);
+
+ // Update the password for all tokens
+ $tokens = $this->mapper->getTokenByUser($token->getUID());
+ $hashedPassword = $this->hashPassword($password);
+ foreach ($tokens as $t) {
+ $publicKey = $t->getPublicKey();
+ $t->setPassword($this->encryptPassword($password, $publicKey));
+ $t->setPasswordHash($hashedPassword);
+ $this->updateToken($t);
+ }
+ }, $this->db);
}
private function hashPassword(string $password): string {
@@ -489,49 +491,51 @@ class PublicKeyTokenProvider implements IProvider {
return;
}
- // Update the password for all tokens
- $tokens = $this->mapper->getTokenByUser($uid);
- $newPasswordHash = null;
-
- /**
- * - true: The password hash could not be verified anymore
- * and the token needs to be updated with the newly encrypted password
- * - false: The hash could still be verified
- * - missing: The hash needs to be verified
- */
- $hashNeedsUpdate = [];
-
- foreach ($tokens as $t) {
- if (!isset($hashNeedsUpdate[$t->getPasswordHash()])) {
- if ($t->getPasswordHash() === null) {
- $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = true;
- } elseif (!$this->hasher->verify(sha1($password) . $password, $t->getPasswordHash())) {
- $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = true;
- } else {
- $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = false;
+ $this->atomic(function () use ($password, $uid) {
+ // Update the password for all tokens
+ $tokens = $this->mapper->getTokenByUser($uid);
+ $newPasswordHash = null;
+
+ /**
+ * - true: The password hash could not be verified anymore
+ * and the token needs to be updated with the newly encrypted password
+ * - false: The hash could still be verified
+ * - missing: The hash needs to be verified
+ */
+ $hashNeedsUpdate = [];
+
+ foreach ($tokens as $t) {
+ if (!isset($hashNeedsUpdate[$t->getPasswordHash()])) {
+ if ($t->getPasswordHash() === null) {
+ $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = true;
+ } elseif (!$this->hasher->verify(sha1($password) . $password, $t->getPasswordHash())) {
+ $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = true;
+ } else {
+ $hashNeedsUpdate[$t->getPasswordHash() ?: ''] = false;
+ }
}
- }
- $needsUpdating = $hashNeedsUpdate[$t->getPasswordHash() ?: ''] ?? true;
-
- if ($needsUpdating) {
- if ($newPasswordHash === null) {
- $newPasswordHash = $this->hashPassword($password);
+ $needsUpdating = $hashNeedsUpdate[$t->getPasswordHash() ?: ''] ?? true;
+
+ if ($needsUpdating) {
+ if ($newPasswordHash === null) {
+ $newPasswordHash = $this->hashPassword($password);
+ }
+
+ $publicKey = $t->getPublicKey();
+ $t->setPassword($this->encryptPassword($password, $publicKey));
+ $t->setPasswordHash($newPasswordHash);
+ $t->setPasswordInvalid(false);
+ $this->updateToken($t);
}
-
- $publicKey = $t->getPublicKey();
- $t->setPassword($this->encryptPassword($password, $publicKey));
- $t->setPasswordHash($newPasswordHash);
- $t->setPasswordInvalid(false);
- $this->updateToken($t);
}
- }
- // If password hashes are different we update them all to be equal so
- // that the next execution only needs to verify once
- if (count($hashNeedsUpdate) > 1) {
- $newPasswordHash = $this->hashPassword($password);
- $this->mapper->updateHashesForUser($uid, $newPasswordHash);
- }
+ // If password hashes are different we update them all to be equal so
+ // that the next execution only needs to verify once
+ if (count($hashNeedsUpdate) > 1) {
+ $newPasswordHash = $this->hashPassword($password);
+ $this->mapper->updateHashesForUser($uid, $newPasswordHash);
+ }
+ }, $this->db);
}
private function logOpensslError() {