]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix set recovery key and implement change password
authorBjoern Schiessle <schiessle@owncloud.com>
Tue, 31 Mar 2015 11:48:03 +0000 (13:48 +0200)
committerThomas Müller <thomas.mueller@tmit.eu>
Tue, 7 Apr 2015 11:30:29 +0000 (13:30 +0200)
apps/encryption/appinfo/routes.php
apps/encryption/controller/recoverycontroller.php
apps/encryption/js/settings-admin.js
apps/encryption/lib/exceptions/privatekeymissingexception.php
apps/encryption/lib/keymanager.php
apps/encryption/lib/recovery.php

index b2c00c8334932da05e6b1e3d5cb5a4a0f8a2b037..030e7617816856c047da032f8d48aefe27b6ea34 100644 (file)
@@ -33,6 +33,11 @@ namespace OCA\Encryption\AppInfo;
                'name' => 'Recovery#userRecovery',
                'url' => '/ajax/userRecovery',
                'verb' => 'POST'
+       ],
+       [
+               'name' => 'Recovery#changeRecoveryPassword',
+               'url' => '/ajax/changeRecoveryPassword',
+               'verb' => 'POST'
        ]
 
 
index abea899333640529f1eac8d82ee2dd612f355db3..e7bfd37490387690ac7de7d52c6cb39ac17aa544 100644 (file)
@@ -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.'))));
                }
        }
 
index e5d3bebb2089d2c610159692594e707531d94b19..36765adf3e4283245d839a1c025b661e977580e7 100644 (file)
@@ -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);
index e06940f7ac8509f8f1adf589ae572c26b7842400..ddc3d11cdbccf7678ecbba97bbfb3cd3e5035fd7 100644 (file)
@@ -23,6 +23,6 @@
 namespace OCA\Encryption\Exceptions;
 
 
-class PrivateKeyMissingException extends GenericEncryptionException{
+class PrivateKeyMissingException extends \Exception{
 
 }
index 87b19fe35ea36561dfb3d24cad435c4fbeb9e2eb..67a32d75908d3fca6dced596692d875e84c9054e 100644 (file)
@@ -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);
        }
 }
index 376d3ef83bab80d7529f82fb73c38b44ac5c83c3..0426c3746eda6dc748f276294f6484a53a7f95b8 100644 (file)
@@ -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)) {
@@ -116,6 +106,23 @@ class Recovery {
                return false;
        }
 
+       /**
+        * 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