Merge pull request #8398 from owncloud/enc_backup_keys
backup the encryption key after the encryption was disabled
This commit is contained in:
commit
b8de1e5d71
|
@ -788,8 +788,8 @@ class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($successful) {
|
if ($successful) {
|
||||||
$this->view->deleteAll($this->keyfilesPath);
|
$this->view->rename($this->keyfilesPath, $this->keyfilesPath . '.backup');
|
||||||
$this->view->deleteAll($this->shareKeysPath);
|
$this->view->rename($this->shareKeysPath, $this->shareKeysPath . '.backup');
|
||||||
}
|
}
|
||||||
|
|
||||||
\OC_FileProxy::$enabled = true;
|
\OC_FileProxy::$enabled = true;
|
||||||
|
|
|
@ -413,8 +413,16 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
|
||||||
// file should no longer be encrypted
|
// file should no longer be encrypted
|
||||||
$this->assertEquals(0, $fileInfoUnencrypted['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
|
// cleanup
|
||||||
$this->view->unlink($this->userId . '/files/' . $filename);
|
$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');
|
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/keyfiles/'));
|
||||||
$this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/'));
|
$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/' . $file1);
|
||||||
$this->view->unlink($this->userId . '/files/' . $file2);
|
$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');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -550,6 +550,27 @@ class OC_Util {
|
||||||
return $encryptedFiles;
|
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
|
* @brief Check for correct file permissions of data directory
|
||||||
* @param string $dataDirectory
|
* @param string $dataDirectory
|
||||||
|
@ -1101,7 +1122,6 @@ class OC_Util {
|
||||||
$mr = $max_redirects;
|
$mr = $max_redirects;
|
||||||
if ($mr > 0) {
|
if ($mr > 0) {
|
||||||
$newURL = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
|
$newURL = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
|
||||||
|
|
||||||
$rcurl = curl_copy_handle($curl);
|
$rcurl = curl_copy_handle($curl);
|
||||||
curl_setopt($rcurl, CURLOPT_HEADER, true);
|
curl_setopt($rcurl, CURLOPT_HEADER, true);
|
||||||
curl_setopt($rcurl, CURLOPT_NOBODY, true);
|
curl_setopt($rcurl, CURLOPT_NOBODY, true);
|
||||||
|
|
|
@ -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'))));
|
||||||
|
}
|
|
@ -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'))));
|
||||||
|
}
|
|
@ -212,17 +212,30 @@ $(document).ready(function(){
|
||||||
OC.Encryption.decryptAll(privateKeyPassword);
|
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) {
|
$('#decryptAll input:password[name="privateKeyPassword"]').keyup(function(event) {
|
||||||
var privateKeyPassword = $('#decryptAll input:password[id="privateKeyPassword"]').val();
|
var privateKeyPassword = $('#decryptAll input:password[id="privateKeyPassword"]').val();
|
||||||
if (privateKeyPassword !== '' ) {
|
if (privateKeyPassword !== '' ) {
|
||||||
$('#decryptAll button:button[name="submitDecryptAll"]').removeAttr("disabled");
|
$('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", false);
|
||||||
if(event.which === 13) {
|
if(event.which === 13) {
|
||||||
$('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
|
$('#decryptAll button:button[name="submitDecryptAll"]').prop("disabled", true);
|
||||||
$('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", true);
|
$('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", true);
|
||||||
OC.Encryption.decryptAll(privateKeyPassword);
|
OC.Encryption.decryptAll(privateKeyPassword);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 = {
|
OC.Encryption = {
|
||||||
decryptAll: function(password) {
|
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) {
|
$.post('ajax/decryptall.php', {password:password}, function(data) {
|
||||||
if (data.status === "error") {
|
if (data.status === "error") {
|
||||||
OC.Encryption.msg.finishedDecrypting('#decryptAll .msg', data);
|
OC.Encryption.msg.finished('#decryptAll .msg', data);
|
||||||
$('#decryptAll input:password[name="privateKeyPassword"]').removeAttr("disabled");
|
$('#decryptAll input:password[name="privateKeyPassword"]').prop("disabled", false);
|
||||||
} else {
|
} else {
|
||||||
OC.Encryption.msg.finishedDecrypting('#decryptAll .msg', data);
|
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.finished('#restoreBackupKeys .msg', data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
OC.Encryption.msg={
|
OC.Encryption.msg={
|
||||||
startDecrypting:function(selector){
|
start:function(selector, msg){
|
||||||
var spinner = '<img src="'+ OC.imagePath('core', 'loading-small.gif') +'">';
|
var spinner = '<img src="'+ OC.imagePath('core', 'loading-small.gif') +'">';
|
||||||
$(selector)
|
$(selector)
|
||||||
.html( t('settings', 'Decrypting files... Please wait, this can take some time.') + ' ' + spinner )
|
.html( msg + ' ' + spinner )
|
||||||
.removeClass('success')
|
.removeClass('success')
|
||||||
.removeClass('error')
|
.removeClass('error')
|
||||||
.stop(true, true)
|
.stop(true, true)
|
||||||
.show();
|
.show();
|
||||||
},
|
},
|
||||||
finishedDecrypting:function(selector, data){
|
finished:function(selector, data){
|
||||||
if( data.status === "success" ){
|
if( data.status === "success" ){
|
||||||
$(selector).html( data.data.message )
|
$(selector).html( data.data.message )
|
||||||
.addClass('success')
|
.addClass('success')
|
||||||
|
|
|
@ -33,7 +33,9 @@ $userLang=OC_Preferences::getValue( OC_User::getUser(), 'core', 'lang', OC_L10N:
|
||||||
$languageCodes=OC_L10N::findAvailableLanguages();
|
$languageCodes=OC_L10N::findAvailableLanguages();
|
||||||
|
|
||||||
//check if encryption was enabled in the past
|
//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
|
// array of common languages
|
||||||
$commonlangcodes = array(
|
$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('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC_User::getUser()));
|
||||||
$tmpl->assign('displayName', OC_User::getDisplayName());
|
$tmpl->assign('displayName', OC_User::getDisplayName());
|
||||||
$tmpl->assign('enableDecryptAll' , $enableDecryptAll);
|
$tmpl->assign('enableDecryptAll' , $enableDecryptAll);
|
||||||
|
$tmpl->assign('backupKeysExists' , $backupKeysExists);
|
||||||
|
$tmpl->assign('filesStillEncrypted' , $filesStillEncrypted);
|
||||||
$tmpl->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true));
|
$tmpl->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true));
|
||||||
$tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
|
$tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,10 @@ $this->create('settings_ajax_setlanguage', '/settings/ajax/setlanguage.php')
|
||||||
->actionInclude('settings/ajax/setlanguage.php');
|
->actionInclude('settings/ajax/setlanguage.php');
|
||||||
$this->create('settings_ajax_decryptall', '/settings/ajax/decryptall.php')
|
$this->create('settings_ajax_decryptall', '/settings/ajax/decryptall.php')
|
||||||
->actionInclude('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
|
// apps
|
||||||
$this->create('settings_ajax_apps_ocs', '/settings/ajax/apps/ocs.php')
|
$this->create('settings_ajax_apps_ocs', '/settings/ajax/apps/ocs.php')
|
||||||
->actionInclude('settings/ajax/apps/ocs.php');
|
->actionInclude('settings/ajax/apps/ocs.php');
|
||||||
|
|
|
@ -144,10 +144,15 @@ if($_['passwordChangeSupported']) {
|
||||||
};?>
|
};?>
|
||||||
|
|
||||||
<?php if($_['enableDecryptAll']): ?>
|
<?php if($_['enableDecryptAll']): ?>
|
||||||
<div class="section" id="decryptAll">
|
<div class="section">
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<?php p( $l->t( 'Encryption' ) ); ?>
|
<?php p( $l->t( 'Encryption' ) ); ?>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<?php if($_['filesStillEncrypted']): ?>
|
||||||
|
|
||||||
|
<div id="decryptAll">
|
||||||
<?php p($l->t( "The encryption app is no longer enabled, please decrypt all your files" )); ?>
|
<?php p($l->t( "The encryption app is no longer enabled, please decrypt all your files" )); ?>
|
||||||
<p>
|
<p>
|
||||||
<input
|
<input
|
||||||
|
@ -164,8 +169,34 @@ if($_['passwordChangeSupported']) {
|
||||||
<span class="msg"></span>
|
<span class="msg"></span>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<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>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2><?php p($l->t('Version'));?></h2>
|
<h2><?php p($l->t('Version'));?></h2>
|
||||||
|
|
Loading…
Reference in New Issue