Browse Source

use password change logic to userhooks to avoid recursions

remotes/origin/poc-doctrine-migrations
Bjoern Schiessle 11 years ago
committed by Thomas Müller
parent
commit
4843e5ce30
  1. 6
      apps/encryption/appinfo/application.php
  2. 86
      apps/encryption/hooks/userhooks.php
  3. 75
      apps/encryption/lib/keymanager.php
  4. 11
      apps/encryption/lib/session.php

6
apps/encryption/appinfo/application.php

@ -77,7 +77,8 @@ class Application extends \OCP\AppFramework\App {
$container->query('UserSetup'),
$server->getUserSession(),
$container->query('Util'),
new \OCA\Encryption\Session($server->getSession())),
new \OCA\Encryption\Session($server->getSession()),
$container->query('Recovery'))
]);
$hookManager->fireHooks();
@ -126,8 +127,7 @@ class Application extends \OCP\AppFramework\App {
$server->getConfig(),
$server->getUserSession(),
new \OCA\Encryption\Session($server->getSession()),
$server->getLogger(),
$c->query('Recovery')
$server->getLogger()
);
});

86
apps/encryption/hooks/userhooks.php

@ -31,6 +31,7 @@ use OCP\ILogger;
use OCP\IUserSession;
use OCA\Encryption\Util;
use OCA\Encryption\Session;
use OCA\Encryption\Recovery;
class UserHooks implements IHook {
/**
@ -57,6 +58,10 @@ class UserHooks implements IHook {
* @var Session
*/
private $session;
/**
* @var Recovery
*/
private $recovery;
/**
* UserHooks constructor.
@ -67,13 +72,15 @@ class UserHooks implements IHook {
* @param IUserSession $user
* @param Util $util
* @param Session $session
* @param Recovery $recovery
*/
public function __construct(KeyManager $keyManager,
ILogger $logger,
Setup $userSetup,
IUserSession $user,
Util $util,
Session $session) {
Session $session,
Recovery $recovery) {
$this->keyManager = $keyManager;
$this->logger = $logger;
@ -81,6 +88,7 @@ class UserHooks implements IHook {
$this->user = $user;
$this->util = $util;
$this->session = $session;
$this->recovery = $recovery;
}
/**
@ -141,7 +149,7 @@ class UserHooks implements IHook {
* remove keys from session during logout
*/
public function logout() {
KeyManager::$session->clear();
$this->session->clear();
}
/**
@ -180,17 +188,81 @@ class UserHooks implements IHook {
if (App::isEnabled('encryption')) {
if (!$this->user->getUser()->canChangePassword()) {
if (App::isEnabled('encryption') === false) {
return true;
$this->setPassphrase($params);
}
}
}
/**
* Change a user's encryption passphrase
*
* @param array $params keys: uid, password
* @param IUserSession $user
* @param Util $util
* @return bool
*/
public function setPassphrase($params) {
// Get existing decrypted private key
$privateKey = $this->session->getPrivateKey();
if ($params['uid'] === $this->user->getUser()->getUID() && $privateKey) {
// Encrypt private key with new user pwd as passphrase
$encryptedPrivateKey = $this->crypt->symmetricEncryptFileContent($privateKey,
$params['password']);
// Save private key
if ($encryptedPrivateKey) {
$this->setPrivateKey($this->user->getUser()->getUID(),
$encryptedPrivateKey);
} else {
$this->log->error('Encryption could not update users encryption password');
}
// NOTE: Session does not need to be updated as the
// private key has not changed, only the passphrase
// used to decrypt it has changed
} else { // admin changed the password for a different user, create new keys and reencrypt file keys
$user = $params['uid'];
$recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
// we generate new keys if...
// ...we have a recovery password and the user enabled the recovery key
// ...encryption was activated for the first time (no keys exists)
// ...the user doesn't have any files
if (($util->recoveryEnabledForUser() && $recoveryPassword) || !$this->userHasKeys($user) || !$util->userHasFiles($user)
) {
// backup old keys
$this->backupAllKeys('recovery');
$newUserPassword = $params['password'];
$keyPair = $this->crypt->createKeyPair();
// Save public key
$this->setPublicKey($user, $keyPair['publicKey']);
// Encrypt private key with new password
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
$newUserPassword);
if ($encryptedKey) {
$this->setPrivateKey($user, $encryptedKey);
if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
$this->recovery->recoverUsersFiles($recoveryPassword);
}
} else {
$this->log->error('Encryption Could not update users encryption password');
}
$this->keyManager->setPassphrase($params,
$this->user,
$this->util);
}
}
}
/**
* after password reset we create a new key pair for the user
*

75
apps/encryption/lib/keymanager.php

@ -23,7 +23,7 @@ namespace OCA\Encryption;
use OC\Encryption\Exceptions\DecryptionFailedException;
use OC\Encryption\Exceptions\PrivateKeyMissingException;
use OCA\Encryption\Exceptions\PrivateKeyMissingException;
use OC\Encryption\Exceptions\PublicKeyMissingException;
use OCA\Encryption\Crypto\Crypt;
use OCP\Encryption\Keys\IStorage;
@ -92,7 +92,6 @@ class KeyManager {
* @param IUserSession $userSession
* @param Session $session
* @param ILogger $log
* @param Recovery $recovery
*/
public function __construct(
IStorage $keyStorage,
@ -100,8 +99,7 @@ class KeyManager {
IConfig $config,
IUserSession $userSession,
Session $session,
ILogger $log,
Recovery $recovery
ILogger $log
) {
$this->session = $session;
@ -141,7 +139,6 @@ class KeyManager {
$this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false;
$this->log = $log;
$this->recovery = $recovery;
}
/**
@ -329,74 +326,6 @@ class KeyManager {
return $this->keyStorage->getFileKey($path, $keyId);
}
/**
* Change a user's encryption passphrase
*
* @param array $params keys: uid, password
* @param IUserSession $user
* @param Util $util
* @return bool
*/
public function setPassphrase($params, IUserSession $user, Util $util) {
// Get existing decrypted private key
$privateKey = $this->session->getPrivateKey();
if ($params['uid'] === $user->getUser()->getUID() && $privateKey) {
// Encrypt private key with new user pwd as passphrase
$encryptedPrivateKey = $this->crypt->symmetricEncryptFileContent($privateKey,
$params['password']);
// Save private key
if ($encryptedPrivateKey) {
$this->setPrivateKey($user->getUser()->getUID(),
$encryptedPrivateKey);
} else {
$this->log->error('Encryption could not update users encryption password');
}
// NOTE: Session does not need to be updated as the
// private key has not changed, only the passphrase
// used to decrypt it has changed
} else { // admin changed the password for a different user, create new keys and reencrypt file keys
$user = $params['uid'];
$recoveryPassword = isset($params['recoveryPassword']) ? $params['recoveryPassword'] : null;
// we generate new keys if...
// ...we have a recovery password and the user enabled the recovery key
// ...encryption was activated for the first time (no keys exists)
// ...the user doesn't have any files
if (($util->recoveryEnabledForUser() && $recoveryPassword) || !$this->userHasKeys($user) || !$util->userHasFiles($user)
) {
// backup old keys
$this->backupAllKeys('recovery');
$newUserPassword = $params['password'];
$keyPair = $this->crypt->createKeyPair();
// Save public key
$this->setPublicKey($user, $keyPair['publicKey']);
// Encrypt private key with new password
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
$newUserPassword);
if ($encryptedKey) {
$this->setPrivateKey($user, $encryptedKey);
if ($recoveryPassword) { // if recovery key is set we can re-encrypt the key files
$this->recovery->recoverUsersFiles($recoveryPassword);
}
} else {
$this->log->error('Encryption Could not update users encryption password');
}
}
}
}
/**
* @param $userId
* @return bool

11
apps/encryption/lib/session.php

@ -100,4 +100,15 @@ class Session {
$this->session->set('privateKey', $key);
}
/**
* remove keys from session
*/
public function clear() {
$this->session->remove('publicSharePrivateKey');
$this->session->remove('privateKey');
$this->session->remove('encryptionInitialized');
}
}
Loading…
Cancel
Save