aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Schiessle <schiessle@owncloud.com>2015-03-31 13:48:03 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2015-04-07 13:30:29 +0200
commit4b4aeaa5b2e13ae4272bf8f4b44564e5b8cb046a (patch)
treebc8ece1aaca29577622012920eb0d70020827196
parenta98b7dbf6fc3a190d995326ea97f88296ed89080 (diff)
downloadnextcloud-server-4b4aeaa5b2e13ae4272bf8f4b44564e5b8cb046a.tar.gz
nextcloud-server-4b4aeaa5b2e13ae4272bf8f4b44564e5b8cb046a.zip
fix set recovery key and implement change password
-rw-r--r--apps/encryption/appinfo/routes.php5
-rw-r--r--apps/encryption/controller/recoverycontroller.php54
-rw-r--r--apps/encryption/js/settings-admin.js2
-rw-r--r--apps/encryption/lib/exceptions/privatekeymissingexception.php2
-rw-r--r--apps/encryption/lib/keymanager.php44
-rw-r--r--apps/encryption/lib/recovery.php31
6 files changed, 108 insertions, 30 deletions
diff --git a/apps/encryption/appinfo/routes.php b/apps/encryption/appinfo/routes.php
index b2c00c83349..030e7617816 100644
--- a/apps/encryption/appinfo/routes.php
+++ b/apps/encryption/appinfo/routes.php
@@ -33,6 +33,11 @@ namespace OCA\Encryption\AppInfo;
'name' => 'Recovery#userRecovery',
'url' => '/ajax/userRecovery',
'verb' => 'POST'
+ ],
+ [
+ 'name' => 'Recovery#changeRecoveryPassword',
+ 'url' => '/ajax/changeRecoveryPassword',
+ 'verb' => 'POST'
]
diff --git a/apps/encryption/controller/recoverycontroller.php b/apps/encryption/controller/recoverycontroller.php
index abea8993336..e7bfd374903 100644
--- a/apps/encryption/controller/recoverycontroller.php
+++ b/apps/encryption/controller/recoverycontroller.php
@@ -28,7 +28,7 @@ use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;
use OCP\JSON;
-use Symfony\Component\HttpFoundation\JsonResponse;
+use OCP\AppFramework\Http\DataResponse;
class RecoveryController extends Controller {
/**
@@ -62,32 +62,60 @@ class RecoveryController extends Controller {
// Check if both passwords are the same
if (empty($recoveryPassword)) {
$errorMessage = $this->l->t('Missing recovery key password');
- return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
+ return new DataResponse(['data' => ['message' => $errorMessage]], 500);
}
if (empty($confirmPassword)) {
$errorMessage = $this->l->t('Please repeat the recovery key password');
- return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
+ return new DataResponse(['data' => ['message' => $errorMessage]], 500);
}
if ($recoveryPassword !== $confirmPassword) {
$errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password');
- return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
+ return new DataResponse(['data' => ['message' => $errorMessage]], 500);
}
- // Enable recoveryAdmin
- $recoveryKeyId = $this->config->getAppValue('encryption', 'recoveryKeyId');
-
if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') {
- if ($this->recovery->enableAdminRecovery($recoveryKeyId, $recoveryPassword)) {
- return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully enabled'))]);
+ if ($this->recovery->enableAdminRecovery($recoveryPassword)) {
+ return new DataResponse(['status' =>'success', 'data' => array('message' => $this->l->t('Recovery key successfully enabled'))]);
}
- return new JsonResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]);
+ return new DataResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]);
} elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') {
- if ($this->recovery->disableAdminRecovery($recoveryKeyId, $recoveryPassword)) {
- return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]);
+ if ($this->recovery->disableAdminRecovery($recoveryPassword)) {
+ return new DataResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]);
}
- return new JsonResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]);
+ return new DataResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]);
+ }
+ }
+
+ public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) {
+ //check if both passwords are the same
+ if (empty($oldPassword)) {
+ $errorMessage = $this->l->t('Please provide the old recovery password');
+ return new DataResponse(array('data' => array('message' => $errorMessage)));
+ }
+
+ if (empty($newPassword)) {
+ $errorMessage = $this->l->t('Please provide a new recovery password');
+ return new DataResponse (array('data' => array('message' => $errorMessage)));
+ }
+
+ if (empty($confirmPassword)) {
+ $errorMessage = $this->l->t('Please repeat the new recovery password');
+ return new DataResponse(array('data' => array('message' => $errorMessage)));
+ }
+
+ if ($newPassword !== $confirmPassword) {
+ $errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password');
+ return new DataResponse(array('data' => array('message' => $errorMessage)));
+ }
+
+ $result = $this->recovery->changeRecoveryKeyPassword($newPassword, $oldPassword);
+
+ if ($result) {
+ return new DataResponse(array('status' => 'success' ,'data' => array('message' => $this->l->t('Password successfully changed.'))));
+ } else {
+ return new DataResponse(array('data' => array('message' => $this->l->t('Could not change the password. Maybe the old password was not correct.'))));
}
}
diff --git a/apps/encryption/js/settings-admin.js b/apps/encryption/js/settings-admin.js
index e5d3bebb208..36765adf3e4 100644
--- a/apps/encryption/js/settings-admin.js
+++ b/apps/encryption/js/settings-admin.js
@@ -44,7 +44,7 @@ $(document).ready(function(){
var confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val();
OC.msg.startSaving('#encryptionChangeRecoveryKey .msg');
$.post(
- OC.filePath( 'encryption', 'ajax', 'changeRecoveryPassword.php' )
+ OC.generateUrl('/apps/encryption/ajax/changeRecoveryPassword')
, { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword, confirmPassword: confirmNewPassword }
, function( data ) {
OC.msg.finishedSaving('#encryptionChangeRecoveryKey .msg', data);
diff --git a/apps/encryption/lib/exceptions/privatekeymissingexception.php b/apps/encryption/lib/exceptions/privatekeymissingexception.php
index e06940f7ac8..ddc3d11cdbc 100644
--- a/apps/encryption/lib/exceptions/privatekeymissingexception.php
+++ b/apps/encryption/lib/exceptions/privatekeymissingexception.php
@@ -23,6 +23,6 @@
namespace OCA\Encryption\Exceptions;
-class PrivateKeyMissingException extends GenericEncryptionException{
+class PrivateKeyMissingException extends \Exception{
}
diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php
index 87b19fe35ea..67a32d75908 100644
--- a/apps/encryption/lib/keymanager.php
+++ b/apps/encryption/lib/keymanager.php
@@ -108,6 +108,14 @@ class KeyManager {
$this->config = $config;
$this->recoveryKeyId = $this->config->getAppValue('encryption',
'recoveryKeyId');
+ if (empty($this->recoveryKeyId)) {
+ $this->recoveryKeyId = 'recoveryKey_' . substr(md5(time()), 0, 8);
+ $this->config->setAppValue('encryption',
+ 'recoveryKeyId',
+ $this->recoveryKeyId);
+ }
+
+
$this->publicShareKeyId = $this->config->getAppValue('encryption',
'publicShareKeyId');
$this->log = $log;
@@ -171,7 +179,7 @@ class KeyManager {
* @return bool
*/
public function checkRecoveryPassword($password) {
- $recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId);
+ $recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.privateKey');
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey,
$password);
@@ -202,6 +210,26 @@ class KeyManager {
return false;
}
+ /**
+ * @param string $uid
+ * @param string $password
+ * @param array $keyPair
+ * @return bool
+ */
+ public function setRecoveryKey($password, $keyPair) {
+ // Save Public Key
+ $this->keyStorage->setSystemUserKey($this->getRecoveryKeyId(). '.publicKey', $keyPair['publicKey']);
+
+ $encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
+ $password);
+
+ if ($encryptedKey) {
+ $this->setSystemPrivateKey($this->getRecoveryKeyId(), $encryptedKey);
+ return true;
+ }
+ return false;
+ }
+
/**
* @param $userId
* @param $key
@@ -428,9 +456,19 @@ class KeyManager {
}
/**
+ * @param string $keyId
+ * @return string returns openssl key
+ */
+ public function getSystemPrivateKey($keyId) {
+ return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId);
+ }
+
+ /**
+ * @param string $keyId
+ * @param string $key
* @return string returns openssl key
*/
- public function getSystemPrivateKey() {
- return $this->keyStorage->getSystemUserKey($this->privateKeyId);
+ public function setSystemPrivateKey($keyId, $key) {
+ return $this->keyStorage->setSystemUserKey($keyId . '.' . $this->privateKeyId, $key);
}
}
diff --git a/apps/encryption/lib/recovery.php b/apps/encryption/lib/recovery.php
index 376d3ef83ba..0426c3746ed 100644
--- a/apps/encryption/lib/recovery.php
+++ b/apps/encryption/lib/recovery.php
@@ -88,24 +88,14 @@ class Recovery {
* @param $password
* @return bool
*/
- public function enableAdminRecovery($recoveryKeyId, $password) {
+ public function enableAdminRecovery($password) {
$appConfig = $this->config;
-
- if ($recoveryKeyId === null) {
- $recoveryKeyId = $this->random->getLowStrengthGenerator();
- $appConfig->setAppValue('encryption',
- 'recoveryKeyId',
- $recoveryKeyId);
- }
-
$keyManager = $this->keyManager;
if (!$keyManager->recoveryKeyExists()) {
$keyPair = $this->crypt->createKeyPair();
- return $this->keyManager->storeKeyPair($this->user->getUID(),
- $password,
- $keyPair);
+ $this->keyManager->setRecoveryKey($password, $keyPair);
}
if ($keyManager->checkRecoveryPassword($password)) {
@@ -117,6 +107,23 @@ class Recovery {
}
/**
+ * change recovery key id
+ *
+ * @param string $newPassword
+ * @param string $oldPassword
+ */
+ public function changeRecoveryKeyPassword($newPassword, $oldPassword) {
+ $recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
+ $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword);
+ $encryptedRecoveryKey = $this->crypt->symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword);
+ if ($encryptedRecoveryKey) {
+ $this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $encryptedRecoveryKey);
+ return true;
+ }
+ return false;
+ }
+
+ /**
* @param $recoveryPassword
* @return bool
*/