]> source.dussan.org Git - nextcloud-server.git/commitdiff
backup the encryption key after the encryption was disabled so that the user
authorBjoern Schiessle <schiessle@owncloud.com>
Tue, 29 Apr 2014 13:00:57 +0000 (15:00 +0200)
committerBjoern Schiessle <schiessle@owncloud.com>
Tue, 13 May 2014 10:35:25 +0000 (12:35 +0200)
can restore them if needed

apps/files_encryption/lib/util.php
apps/files_encryption/tests/util.php
lib/private/util.php
settings/ajax/deletekeys.php [new file with mode: 0644]
settings/ajax/restorekeys.php [new file with mode: 0644]
settings/js/personal.js
settings/personal.php
settings/routes.php
settings/templates/personal.php

index 6372ab31b6ec1c2e111825f26dc0926cd2ad4dd3..27b4db9253a8ba492a9b1bdabb9ce2f5253529f9 100644 (file)
@@ -788,8 +788,8 @@ class Util {
                        }
 
                        if ($successful) {
-                               $this->view->deleteAll($this->keyfilesPath);
-                               $this->view->deleteAll($this->shareKeysPath);
+                               $this->view->rename($this->keyfilesPath, $this->keyfilesPath . '.backup');
+                               $this->view->rename($this->shareKeysPath, $this->shareKeysPath . '.backup');
                        }
 
                        \OC_FileProxy::$enabled = true;
index 88ded7ec40a4b591bf5b5c9359e3ec5950a6b41a..fa8e1d729ddfd89c38a0842b0e08703e6d836e31 100755 (executable)
@@ -413,8 +413,16 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
                // file should no longer be encrypted
                $this->assertEquals(0, $fileInfoUnencrypted['encrypted']);
 
+               // check if the keys where moved to the backup location
+               $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles.backup'));
+               $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keyfiles.backup/' . $filename . '.key'));
+               $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys.backup'));
+               $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/share-keys.backup/' . $filename . '.' . $user . '.shareKey'));
+
                // cleanup
                $this->view->unlink($this->userId . '/files/' . $filename);
+               $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup');
+               $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup');
                OC_App::enable('files_encryption');
 
        }
@@ -485,8 +493,11 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
                $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keyfiles/'));
                $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/'));
 
+               //cleanup
                $this->view->unlink($this->userId . '/files/' . $file1);
                $this->view->unlink($this->userId . '/files/' . $file2);
+               $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup');
+               $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup');
 
        }
 
index e2005d31c381a7aca448cb28dc2a4ab4de3e0aba..96d80beb4d1a4b2959ea51775999669da05ef524 100755 (executable)
@@ -550,6 +550,27 @@ class OC_Util {
                return $encryptedFiles;
        }
 
+       /**
+        * @brief check if a backup from the encryption keys exists
+        * @return boolean
+        */
+       public static function backupKeysExists() {
+               //check if encryption was enabled in the past
+               $backupExists = false;
+               if (OC_App::isEnabled('files_encryption') === false) {
+                       $view = new OC\Files\View('/' . OCP\User::getUser());
+                       $backupPath = '/files_encryption/keyfiles.backup';
+                       if ($view->is_dir($backupPath)) {
+                               $dircontent = $view->getDirectoryContent($backupPath);
+                               if (!empty($dircontent)) {
+                                       $backupExists = true;
+                               }
+                       }
+               }
+
+               return $backupExists;
+       }
+
        /**
         * @brief Check for correct file permissions of data directory
         * @param string $dataDirectory
@@ -837,7 +858,7 @@ class OC_Util {
                if (!\OC_Config::getValue("check_for_working_htaccess", true)) {
                        return true;
                }
-               
+
                // testdata
                $fileName = '/htaccesstest.txt';
                $testContent = 'testcontent';
@@ -1082,7 +1103,7 @@ class OC_Util {
                        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
                        curl_setopt($curl, CURLOPT_URL, $url);
-                       
+
 
                        curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler");
                        if(OC_Config::getValue('proxy', '') != '') {
@@ -1091,17 +1112,16 @@ class OC_Util {
                        if(OC_Config::getValue('proxyuserpwd', '') != '') {
                                curl_setopt($curl, CURLOPT_PROXYUSERPWD, OC_Config::getValue('proxyuserpwd'));
                        }
-                       
-                       if (ini_get('open_basedir') === '' && ini_get('safe_mode' === 'Off')) { 
+
+                       if (ini_get('open_basedir') === '' && ini_get('safe_mode' === 'Off')) {
                                curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
                                curl_setopt($curl, CURLOPT_MAXREDIRS, $max_redirects);
                                $data = curl_exec($curl);
                        } else {
                                curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
                                $mr = $max_redirects;
-                               if ($mr > 0) { 
+                               if ($mr > 0) {
                                        $newURL = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
-                                       
                                        $rcurl = curl_copy_handle($curl);
                                        curl_setopt($rcurl, CURLOPT_HEADER, true);
                                        curl_setopt($rcurl, CURLOPT_NOBODY, true);
@@ -1125,9 +1145,9 @@ class OC_Util {
                                        curl_close($rcurl);
                                        if ($mr > 0) {
                                                curl_setopt($curl, CURLOPT_URL, $newURL);
-                                       } 
+                                       }
                                }
-                               
+
                                if($mr == 0 && $max_redirects > 0) {
                                        $data = false;
                                } else {
diff --git a/settings/ajax/deletekeys.php b/settings/ajax/deletekeys.php
new file mode 100644 (file)
index 0000000..1f84452
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
+$l = \OC_L10N::get('settings');
+$user = \OC_User::getUser();
+$view = new \OC\Files\View('/' . $user . '/files_encryption');
+
+$keyfilesDeleted = $view->deleteAll('keyfiles.backup');
+$sharekeysDeleted = $view->deleteAll('share-keys.backup');
+
+if ($keyfilesDeleted && $sharekeysDeleted) {
+       \OCP\JSON::success(array('data' => array('message' => $l->t('Encryption keys deleted permanently'))));
+} else {
+       \OCP\JSON::error(array('data' => array('message' => $l->t('Couldn\'t permanently delete your encryption keys, please check your owncloud.log or ask your administrator'))));
+}
diff --git a/settings/ajax/restorekeys.php b/settings/ajax/restorekeys.php
new file mode 100644 (file)
index 0000000..68e19c9
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
+$l = \OC_L10N::get('settings');
+$user = \OC_User::getUser();
+$view = new \OC\Files\View('/' . $user . '/files_encryption');
+
+$keyfilesRestored = $view->rename('keyfiles.backup', 'keyfiles');
+$sharekeysRestored = $view->rename('share-keys.backup' , 'share-keys');
+
+if ($keyfilesRestored && $sharekeysRestored) {
+       \OCP\JSON::success(array('data' => array('message' => $l->t('Backups restored successfully'))));
+} else {
+       // if one of the move operation was succesful we remove the files back to have a consistent state
+       if($keyfilesRestored) {
+               $view->rename('keyfiles', 'keyfiles.backup');
+       }
+       if($sharekeysRestored) {
+               $view->rename('share-keys' , 'share-keys.backup');
+       }
+       \OCP\JSON::error(array('data' => array('message' => $l->t('Couldn\'t restore your encryption keys, please check your owncloud.log or ask your administrator'))));
+}
index c1f1ef7466b9ee3f71469f748cd6835faf1503e9..f297e3c1b1a20531677a136ce85b2baa9d7f3f8f 100644 (file)
@@ -212,17 +212,30 @@ $(document).ready(function(){
                OC.Encryption.decryptAll(privateKeyPassword);
        });
 
+
+       $('button:button[name="submitRestoreKeys"]').click(function() {
+               $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", true);
+               $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", true);
+               OC.Encryption.restoreKeys();
+       });
+
+       $('button:button[name="submitDeleteKeys"]').click(function() {
+               $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", true);
+               $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", true);
+               OC.Encryption.deleteKeys();
+       });
+
        $('#decryptAll input:password[name="privateKeyPassword"]').keyup(function(event) {
                var privateKeyPassword = $('#decryptAll input:password[id="privateKeyPassword"]').val();
                if (privateKeyPassword !== '' ) {
-                       $('#decryptAll button:button[name="submitDecryptAll"]').removeAttr("disabled");
+                       $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", false);
                        if(event.which === 13) {
                                $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
                                $('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", true);
                                OC.Encryption.decryptAll(privateKeyPassword);
                        }
                } else {
-                       $('#decryptAll button:button[name="submitDecryptAll"]').attr("disabled", "true");
+                       $('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
                }
        });
 
@@ -294,29 +307,59 @@ $(document).ready(function(){
 
 OC.Encryption = {
        decryptAll: function(password) {
-               OC.Encryption.msg.startDecrypting('#decryptAll .msg');
+               var message = t('settings', 'Decrypting files... Please wait, this can take some time.');
+               OC.Encryption.msg.start('#decryptAll .msg', message);
                $.post('ajax/decryptall.php', {password:password}, function(data) {
                        if (data.status === "error") {
-                               OC.Encryption.msg.finishedDecrypting('#decryptAll .msg', data);
-                               $('#decryptAll input:password[name="privateKeyPassword"]').removeAttr("disabled");
+                               OC.Encryption.msg.finished('#decryptAll .msg', data);
+                               $('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", false);
+                       } else {
+                               OC.Encryption.msg.finished('#decryptAll .msg', data);
+                       }
+                       $('#restoreBackupKeys').removeClass('hidden');
+               });
+       },
+
+       deleteKeys: function() {
+               var message = t('settings', 'Delete encryptin keys permanently.');
+               OC.Encryption.msg.start('#restoreBackupKeys .msg', message);
+               $.post('ajax/deletekeys.php', null, function(data) {
+                       if (data.status === "error") {
+                               OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
+                               $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", false);
+                               $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", false);
+                       } else {
+                               OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
+                       }
+               });
+       },
+
+       restoreKeys: function() {
+               var message = t('settings', 'Restore encryptin keys.');
+               OC.Encryption.msg.start('#restoreBackupKeys .msg', message);
+               $.post('ajax/restorekeys.php', {}, function(data) {
+                       if (data.status === "error") {
+                               OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
+                               $('#restoreBackupKeys button:button[name="submitDeleteKeys"]').prop("disabled", false);
+                               $('#restoreBackupKeys button:button[name="submitRestoreKeys"]').prop("disabled", false);
                        } else {
-                               OC.Encryption.msg.finishedDecrypting('#decryptAll .msg', data);
+                               OC.Encryption.msg.finished('#restoreBackupKeys .msg', data);
                        }
                });
        }
 };
 
 OC.Encryption.msg={
-       startDecrypting:function(selector){
+       start:function(selector, msg){
                var spinner = '<img src="'+ OC.imagePath('core', 'loading-small.gif') +'">';
                $(selector)
-                       .html( t('settings', 'Decrypting files... Please wait, this can take some time.') + ' ' + spinner )
+                       .html( msg + ' ' + spinner )
                        .removeClass('success')
                        .removeClass('error')
                        .stop(true, true)
                        .show();
        },
-       finishedDecrypting:function(selector, data){
+       finished:function(selector, data){
                if( data.status === "success" ){
                        $(selector).html( data.data.message )
                                .addClass('success')
index 0da14a8c8c4018f8dd1ae15d27b1d80dda125c06..47b2dc1a46a7a1cc763cddbe8b412f1185715c0d 100644 (file)
@@ -33,7 +33,9 @@ $userLang=OC_Preferences::getValue( OC_User::getUser(), 'core', 'lang', OC_L10N:
 $languageCodes=OC_L10N::findAvailableLanguages();
 
 //check if encryption was enabled in the past
-$enableDecryptAll = OC_Util::encryptedFiles();
+$filesStillEncrypted = OC_Util::encryptedFiles();
+$backupKeysExists = OC_Util::backupKeysExists();
+$enableDecryptAll = $filesStillEncrypted || $backupKeysExists;
 
 // array of common languages
 $commonlangcodes = array(
@@ -92,6 +94,8 @@ $tmpl->assign('passwordChangeSupported', OC_User::canUserChangePassword(OC_User:
 $tmpl->assign('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC_User::getUser()));
 $tmpl->assign('displayName', OC_User::getDisplayName());
 $tmpl->assign('enableDecryptAll' , $enableDecryptAll);
+$tmpl->assign('backupKeysExists' , $backupKeysExists);
+$tmpl->assign('filesStillEncrypted' , $filesStillEncrypted);
 $tmpl->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true));
 $tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
 
index a8bb0d981e8a0ede6c5ff61ce331265d5ea8799e..21d406beecad1137c1cff7361948a18cae18ec64 100644 (file)
@@ -54,6 +54,10 @@ $this->create('settings_ajax_setlanguage', '/settings/ajax/setlanguage.php')
        ->actionInclude('settings/ajax/setlanguage.php');
 $this->create('settings_ajax_decryptall', '/settings/ajax/decryptall.php')
        ->actionInclude('settings/ajax/decryptall.php');
+$this->create('settings_ajax_restorekeys', '/settings/ajax/restorekeys.php')
+       ->actionInclude('settings/ajax/restorekeys.php');
+$this->create('settings_ajax_deletekeys', '/settings/ajax/deletekeys.php')
+       ->actionInclude('settings/ajax/deletekeys.php');
 // apps
 $this->create('settings_ajax_apps_ocs', '/settings/ajax/apps/ocs.php')
        ->actionInclude('settings/ajax/apps/ocs.php');
index cc1fce88c9f25ba67d0ac2902f7905aa03fde90e..afa3f5d700a83a39f3e28a5fa85dd8ce5d0b8afd 100644 (file)
@@ -144,10 +144,15 @@ if($_['passwordChangeSupported']) {
 };?>
 
 <?php if($_['enableDecryptAll']): ?>
-<div class="section" id="decryptAll">
+<div class="section">
+
        <h2>
                <?php p( $l->t( 'Encryption' ) ); ?>
        </h2>
+
+       <?php if($_['filesStillEncrypted']): ?>
+
+       <div id="decryptAll">
        <?php p($l->t( "The encryption app is no longer enabled, please decrypt all your files" )); ?>
        <p>
                <input
@@ -164,8 +169,34 @@ if($_['passwordChangeSupported']) {
                <span class="msg"></span>
        </p>
        <br />
+       </div>
+
+       <?php endif; ?>
+
+
+
+       <div id="restoreBackupKeys" <?php $_['backupKeysExists'] ? '' : print_unescaped("class='hidden'") ?>>
+
+       <?php p($l->t( "Your encryption keys are moved to a backup location. If something went wrong you can restore the keys. Only delete them permanently if you are sure that all files are decrypted correctly." )); ?>
+       <p>
+               <button
+                       type="button"
+                       name="submitRestoreKeys"><?php p($l->t( "Restore Encryption Keys" )); ?>
+               </button>
+               <button
+                       type="button"
+                       name="submitDeleteKeys"><?php p($l->t( "Delete Encryption Keys" )); ?>
+               </button>
+               <span class="msg"></span>
+
+       </p>
+       <br />
+
+       </div>
+
+
 </div>
-<?php endif; ?>
+       <?php endif; ?>
 
 <div class="section">
        <h2><?php p($l->t('Version'));?></h2>