[Pkg-owncloud-commits] [owncloud] 90/172: backup the encryption key after the encryption was disabled so that the user can restore them if needed

David Prévot taffit at moszumanska.debian.org
Sun May 18 20:09:43 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository owncloud.

commit a9ac11718e62017c70682f99eb35b43b1ef9c498
Author: Bjoern Schiessle <schiessle at owncloud.com>
Date:   Tue Apr 29 15:00:57 2014 +0200

    backup the encryption key after the encryption was disabled so that the user
    can restore them if needed
---
 apps/files_encryption/lib/util.php   |  4 +--
 apps/files_encryption/tests/util.php | 11 +++++++
 lib/private/util.php                 | 36 ++++++++++++++++-----
 settings/ajax/deletekeys.php         | 17 ++++++++++
 settings/ajax/restorekeys.php        | 24 ++++++++++++++
 settings/js/personal.js              | 61 ++++++++++++++++++++++++++++++------
 settings/personal.php                |  6 +++-
 settings/routes.php                  |  4 +++
 settings/templates/personal.php      | 35 +++++++++++++++++++--
 9 files changed, 176 insertions(+), 22 deletions(-)

diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 6372ab3..27b4db9 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -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;
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php
index 88ded7e..fa8e1d7 100755
--- a/apps/files_encryption/tests/util.php
+++ b/apps/files_encryption/tests/util.php
@@ -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');
 
 	}
 
diff --git a/lib/private/util.php b/lib/private/util.php
index e2005d3..96d80be 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -551,6 +551,27 @@ class OC_Util {
 	}
 
 	/**
+	 * @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
 	 * @return array arrays with error messages and hints
@@ -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
index 0000000..1f84452
--- /dev/null
+++ b/settings/ajax/deletekeys.php
@@ -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
index 0000000..68e19c9
--- /dev/null
+++ b/settings/ajax/restorekeys.php
@@ -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'))));
+}
diff --git a/settings/js/personal.js b/settings/js/personal.js
index c1f1ef7..f297e3c 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -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')
diff --git a/settings/personal.php b/settings/personal.php
index 0da14a8..47b2dc1 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -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()));
 
diff --git a/settings/routes.php b/settings/routes.php
index a8bb0d9..21d406b 100644
--- a/settings/routes.php
+++ b/settings/routes.php
@@ -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');
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index cc1fce8..afa3f5d 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -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>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list