summaryrefslogtreecommitdiffstats
path: root/lib/private/Authentication/Token
diff options
context:
space:
mode:
authorRoeland Jago Douma <roeland@famdouma.nl>2018-05-31 21:56:17 +0200
committerRoeland Jago Douma <roeland@famdouma.nl>2018-06-18 22:11:55 +0200
commitf168ecfa7adc484d53a88facdc12a7785583209f (patch)
tree6fae9ca40ba2a853798d3a4defc00350205d7f26 /lib/private/Authentication/Token
parentd03d16a93613337d20dbf68cb0430655d4dadf3e (diff)
downloadnextcloud-server-f168ecfa7adc484d53a88facdc12a7785583209f.tar.gz
nextcloud-server-f168ecfa7adc484d53a88facdc12a7785583209f.zip
Actually convert the token
* When getting the token * When rotating the token * Also store the encrypted password as base64 to avoid weird binary stuff Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'lib/private/Authentication/Token')
-rw-r--r--lib/private/Authentication/Token/Manager.php27
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenMapper.php8
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php99
3 files changed, 94 insertions, 40 deletions
diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index adcd4de3f81..981ea74f568 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -121,8 +121,19 @@ class Manager implements IProvider {
try {
return $this->publicKeyTokenProvider->getToken($tokenId);
} catch (InvalidTokenException $e) {
- return $this->defaultTokenProvider->getToken($tokenId);
+ // No worries we try to convert it to a PublicKey Token
}
+
+ //Convert!
+ $token = $this->defaultTokenProvider->getToken($tokenId);
+
+ try {
+ $password = $this->defaultTokenProvider->getPassword($token, $tokenId);
+ } catch (PasswordlessTokenException $e) {
+ $password = null;
+ }
+
+ return $this->publicKeyTokenProvider->convertToken($token, $tokenId, $password);
}
/**
@@ -149,7 +160,6 @@ class Manager implements IProvider {
try {
$this->publicKeyTokenProvider->renewSessionToken($oldSessionId, $sessionId);
} catch (InvalidTokenException $e) {
- //TODO: Move to new token
$this->defaultTokenProvider->renewSessionToken($oldSessionId, $sessionId);
}
}
@@ -163,7 +173,6 @@ class Manager implements IProvider {
*/
public function getPassword(IToken $savedToken, string $tokenId): string {
if ($savedToken instanceof DefaultToken) {
- //TODO convert to new token type
return $this->defaultTokenProvider->getPassword($savedToken, $tokenId);
}
@@ -173,9 +182,7 @@ class Manager implements IProvider {
}
public function setPassword(IToken $token, string $tokenId, string $password) {
-
if ($token instanceof DefaultToken) {
- //TODO conver to new token
$this->defaultTokenProvider->setPassword($token, $tokenId, $password);
}
@@ -200,10 +207,14 @@ class Manager implements IProvider {
}
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
-
if ($token instanceof DefaultToken) {
- //TODO Migrate to new token
- return $this->defaultTokenProvider->rotate($token, $oldTokenId, $newTokenId);
+ try {
+ $password = $this->defaultTokenProvider->getPassword($token, $oldTokenId);
+ } catch (PasswordlessTokenException $e) {
+ $password = null;
+ }
+
+ return $this->publicKeyTokenProvider->convertToken($token, $newTokenId, $password);
}
if ($token instanceof PublicKeyToken) {
diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
index 6feb176fb68..30349fba31a 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
@@ -159,4 +159,12 @@ class PublicKeyTokenMapper extends QBMapper {
$qb->execute();
}
+ public function deleteTempToken(PublicKeyToken $except) {
+ $qb = $this->db->getQueryBuilder();
+
+ $qb->delete('authtoken')
+ ->where($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN)))
+ ->andWhere($qb->expr()->neq('id', $qb->createNamedParameter($except->getId())))
+ ->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(2, IQueryBuilder::PARAM_INT)));
+ }
}
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 5c97877e730..e512133a962 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -67,36 +67,7 @@ class PublicKeyTokenProvider implements IProvider {
string $name,
int $type = IToken::TEMPORARY_TOKEN,
int $remember = IToken::DO_NOT_REMEMBER): IToken {
- $dbToken = new PublicKeyToken();
- $dbToken->setUid($uid);
- $dbToken->setLoginName($loginName);
-
- $config = [
- 'digest_alg' => 'sha512',
- 'private_key_bits' => 2048,
- ];
-
- // Generate new key
- $res = openssl_pkey_new($config);
- openssl_pkey_export($res, $privateKey);
-
- // Extract the public key from $res to $pubKey
- $publicKey = openssl_pkey_get_details($res);
- $publicKey = $publicKey['key'];
-
- $dbToken->setPublicKey($publicKey);
- $dbToken->setPrivateKey($this->encrypt($privateKey, $token));
-
- if (!is_null($password)) {
- $dbToken->setPassword($this->encryptPassword($password, $publicKey));
- }
-
- $dbToken->setName($name);
- $dbToken->setToken($this->hashToken($token));
- $dbToken->setType($type);
- $dbToken->setRemember($remember);
- $dbToken->setLastActivity($this->time->getTime());
- $dbToken->setLastCheck($this->time->getTime());
+ $dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
$this->mapper->insert($dbToken);
@@ -219,6 +190,9 @@ class PublicKeyTokenProvider implements IProvider {
throw new InvalidTokenException();
}
+ // When changeing passwords all temp tokens are deleted
+ $this->mapper->deleteTempToken($token);
+
// Update the password for all tokens
$tokens = $this->mapper->getTokenByUser($token->getUID());
foreach ($tokens as $t) {
@@ -226,8 +200,6 @@ class PublicKeyTokenProvider implements IProvider {
$t->setPassword($this->encryptPassword($password, $publicKey));
$this->updateToken($t);
}
-
- //TODO: should we also do this for temp tokens?
}
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
@@ -267,11 +239,13 @@ class PublicKeyTokenProvider implements IProvider {
private function encryptPassword(string $password, string $publicKey): string {
openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
+ $encryptedPassword = base64_encode($encryptedPassword);
return $encryptedPassword;
}
private function decryptPassword(string $encryptedPassword, string $privateKey): string {
+ $encryptedPassword = base64_decode($encryptedPassword);
openssl_private_decrypt($encryptedPassword, $password, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
return $password;
@@ -281,4 +255,65 @@ class PublicKeyTokenProvider implements IProvider {
$secret = $this->config->getSystemValue('secret');
return hash('sha512', $token . $secret);
}
+
+ /**
+ * Convert a DefaultToken to a publicKeyToken
+ * This will also be updated directly in the Database
+ */
+ public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken {
+ $pkToken = $this->newToken(
+ $token,
+ $defaultToken->getUID(),
+ $defaultToken->getLoginName(),
+ $password,
+ $defaultToken->getName(),
+ $defaultToken->getType(),
+ $defaultToken->getRemember()
+ );
+
+ $pkToken->setId($defaultToken->getId());
+
+ return $this->mapper->update($pkToken);
+ }
+
+ private function newToken(string $token,
+ string $uid,
+ string $loginName,
+ $password,
+ string $name,
+ int $type,
+ int $remember): PublicKeyToken {
+ $dbToken = new PublicKeyToken();
+ $dbToken->setUid($uid);
+ $dbToken->setLoginName($loginName);
+
+ $config = [
+ 'digest_alg' => 'sha512',
+ 'private_key_bits' => 2048,
+ ];
+
+ // Generate new key
+ $res = openssl_pkey_new($config);
+ openssl_pkey_export($res, $privateKey);
+
+ // Extract the public key from $res to $pubKey
+ $publicKey = openssl_pkey_get_details($res);
+ $publicKey = $publicKey['key'];
+
+ $dbToken->setPublicKey($publicKey);
+ $dbToken->setPrivateKey($this->encrypt($privateKey, $token));
+
+ if (!is_null($password)) {
+ $dbToken->setPassword($this->encryptPassword($password, $publicKey));
+ }
+
+ $dbToken->setName($name);
+ $dbToken->setToken($this->hashToken($token));
+ $dbToken->setType($type);
+ $dbToken->setRemember($remember);
+ $dbToken->setLastActivity($this->time->getTime());
+ $dbToken->setLastCheck($this->time->getTime());
+
+ return $dbToken;
+ }
}