backup the encryption key after the encryption was disabledtags/v7.0.0alpha2
@@ -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; |
@@ -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'); | |||
} | |||
@@ -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 { |
@@ -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); | |||
}); | |||
$('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') |
@@ -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())); | |||
@@ -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'); |
@@ -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> |