diff --git a/apps/encryption/appinfo/encryption.php b/apps/encryption/appinfo/encryption.php index d57f1b0b7b..a389abe5da 100644 --- a/apps/encryption/appinfo/encryption.php +++ b/apps/encryption/appinfo/encryption.php @@ -80,7 +80,12 @@ class Encryption extends \OCP\AppFramework\App { $hookManager = new HookManager(); $hookManager->registerHook([ - new UserHooks($container->query('KeyManager'), $server->getLogger(), $container->query('UserSetup'), $server->getUserSession(), new \OCP\Util(), $container->query('Util')), + new UserHooks($container->query('KeyManager'), + $server->getLogger(), + $container->query('UserSetup'), + $server->getUserSession(), + new \OCP\Util(), + $container->query('Util'),), ]); $hookManager->fireHooks(); @@ -126,7 +131,6 @@ class Encryption extends \OCP\AppFramework\App { $server->getConfig(), $server->getUserSession(), $server->getSession(), - $server->getMemCacheFactory(), $server->getLogger() ); }); diff --git a/apps/encryption/css/settings-personal.css b/apps/encryption/css/settings-personal.css new file mode 100644 index 0000000000..8eb5bedcb0 --- /dev/null +++ b/apps/encryption/css/settings-personal.css @@ -0,0 +1,10 @@ +/* Copyright (c) 2013, Sam Tuke, + This file is licensed under the Affero General Public License version 3 or later. + See the COPYING-README file. */ + +#encryptAllError +, #encryptAllSuccess +, #recoveryEnabledError +, #recoveryEnabledSuccess { + display: none; +} diff --git a/apps/encryption/hooks/apphooks.php b/apps/encryption/hooks/apphooks.php deleted file mode 100644 index 713e9cadef..0000000000 --- a/apps/encryption/hooks/apphooks.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @since 2/19/15, 10:02 AM - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Encryption\Hooks; - -use OCA\Encryption\Hooks\Contracts\IHook; -use OCP\Util; - -class AppHooks implements IHook { - /** - * Connects Hooks - * - * @return null - */ - public function addHooks() { - Util::connectHook('OC_App', 'pre_disable', 'OCA\Encryption\Hooks', 'preDisable'); - Util::connectHook('OC_App', 'post_disable', 'OCA\Encryption\Hooks', 'postEnable'); - } -} diff --git a/apps/encryption/hooks/filesystemhooks.php b/apps/encryption/hooks/filesystemhooks.php deleted file mode 100644 index fda6b75b29..0000000000 --- a/apps/encryption/hooks/filesystemhooks.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @since 2/19/15, 10:02 AM - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Encryption\Hooks; - - -use OCA\Encryption\Hooks\Contracts\IHook; -use OCP\Util; - -class FileSystemHooks implements IHook { - - /** - * Connects Hooks - * - * @return null - */ - public function addHooks() { - Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename'); - Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRenameOrCopy'); - Util::connectHook('OC_Filesystem', 'copy', 'OCA\Encryption\Hooks', 'preCopy'); - Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Encryption\Hooks', 'postRenameOrCopy'); - Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete'); - Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); - Util::connectHook('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', 'OCA\Encryption\Hooks', 'postPasswordReset'); - Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUnmount'); - Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUnmount'); - } -} diff --git a/apps/encryption/hooks/sharehooks.php b/apps/encryption/hooks/sharehooks.php deleted file mode 100644 index fc50712b82..0000000000 --- a/apps/encryption/hooks/sharehooks.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @since 2/19/15, 10:02 AM - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -namespace OCA\Encryption\Hooks; - - -use OCA\Encryption\Hooks\Contracts\IHook; -use OCP\Util; - -class ShareHooks implements IHook { - - /** - * Connects Hooks - * - * @return null - */ - public function addHooks() { - Util::connectHook('OCP\Share', 'pre_shared', 'OCA\Encryption\Hooks', 'preShared'); - Util::connectHook('OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared'); - Util::connectHook('OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare'); - } -} diff --git a/apps/encryption/hooks/userhooks.php b/apps/encryption/hooks/userhooks.php index e8c5fb8bfb..1629aca0f5 100644 --- a/apps/encryption/hooks/userhooks.php +++ b/apps/encryption/hooks/userhooks.php @@ -22,6 +22,7 @@ namespace OCA\Encryption\Hooks; +use OCP\ISession; use OCP\Util as OCUtil; use OCA\Encryption\Hooks\Contracts\IHook; use OCA\Encryption\KeyManager; @@ -53,6 +54,10 @@ class UserHooks implements IHook { * @var Util */ private $util; + /** + * @var ISession + */ + private $session; /** * UserHooks constructor. @@ -63,15 +68,22 @@ class UserHooks implements IHook { * @param IUserSession $user * @param OCUtil $ocUtil * @param Util $util + * @param ISession $session */ - public function __construct( - KeyManager $keyManager, ILogger $logger, Setup $userSetup, IUserSession $user, OCUtil $ocUtil, Util $util) { + public function __construct(KeyManager $keyManager, + ILogger $logger, + Setup $userSetup, + IUserSession $user, + OCUtil $ocUtil, + Util $util, + ISession $session) { $this->keyManager = $keyManager; $this->logger = $logger; $this->userSetup = $userSetup; $this->user = $user; $this->util = $util; + $this->session = $session; } /** @@ -132,7 +144,7 @@ class UserHooks implements IHook { * remove keys from session during logout */ public function logout() { - KeyManager::$cacheFactory->clear(); + KeyManager::$session->clear(); } /** diff --git a/apps/encryption/js/detect-migration.js b/apps/encryption/js/detect-migration.js new file mode 100644 index 0000000000..f5627edf4e --- /dev/null +++ b/apps/encryption/js/detect-migration.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2013 + * Bjoern Schiessle + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + + +$(document).ready(function(){ + $('form[name="login"]').on('submit', function() { + var user = $('#user').val(); + var password = $('#password').val(); + $.ajax({ + type: 'POST', + url: OC.linkTo('files_encryption', 'ajax/getMigrationStatus.php'), + dataType: 'json', + data: {user: user, password: password}, + async: false, + success: function(response) { + if (response.data.migrationStatus === OC.Encryption.MIGRATION_OPEN) { + var message = t('files_encryption', 'Initial encryption started... This can take some time. Please wait.'); + $('#messageText').text(message); + $('#message').removeClass('hidden').addClass('update'); + } else if (response.data.migrationStatus === OC.Encryption.MIGRATION_IN_PROGRESS) { + var message = t('files_encryption', 'Initial encryption running... Please try again later.'); + $('#messageText').text(message); + $('#message').removeClass('hidden').addClass('update'); + } + } + }); + }); + +}); diff --git a/apps/encryption/js/encryption.js b/apps/encryption/js/encryption.js new file mode 100644 index 0000000000..d2d1c3a1fc --- /dev/null +++ b/apps/encryption/js/encryption.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2014 + * Bjoern Schiessle + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +/** + * @namespace + * @memberOf OC + */ +OC.Encryption={ + MIGRATION_OPEN:0, + MIGRATION_COMPLETED:1, + MIGRATION_IN_PROGRESS:-1, +}; diff --git a/apps/encryption/js/settings-admin.js b/apps/encryption/js/settings-admin.js new file mode 100644 index 0000000000..2242c1f712 --- /dev/null +++ b/apps/encryption/js/settings-admin.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2013 + * Sam Tuke + * Robin Appelman + * Bjoern Schiessle + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +$(document).ready(function(){ + + $( 'input:radio[name="adminEnableRecovery"]' ).change( + function() { + var recoveryStatus = $( this ).val(); + var oldStatus = (1+parseInt(recoveryStatus)) % 2; + var recoveryPassword = $( '#encryptionRecoveryPassword' ).val(); + var confirmPassword = $( '#repeatEncryptionRecoveryPassword' ).val(); + OC.msg.startSaving('#encryptionSetRecoveryKey .msg'); + $.post( + OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) + , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword, confirmPassword: confirmPassword } + , function( result ) { + OC.msg.finishedSaving('#encryptionSetRecoveryKey .msg', result); + if (result.status === "error") { + $('input:radio[name="adminEnableRecovery"][value="'+oldStatus.toString()+'"]').attr("checked", "true"); + } else { + if (recoveryStatus === "0") { + $('p[name="changeRecoveryPasswordBlock"]').addClass("hidden"); + } else { + $('input:password[name="changeRecoveryPassword"]').val(""); + $('p[name="changeRecoveryPasswordBlock"]').removeClass("hidden"); + } + } + } + ); + } + ); + + // change recovery password + + $('button:button[name="submitChangeRecoveryKey"]').click(function() { + var oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val(); + var newRecoveryPassword = $('#newEncryptionRecoveryPassword').val(); + var confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val(); + OC.msg.startSaving('#encryptionChangeRecoveryKey .msg'); + $.post( + OC.filePath( 'files_encryption', 'ajax', 'changeRecoveryPassword.php' ) + , { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword, confirmPassword: confirmNewPassword } + , function( data ) { + OC.msg.finishedSaving('#encryptionChangeRecoveryKey .msg', data); + } + ); + }); + +}); diff --git a/apps/encryption/js/settings-personal.js b/apps/encryption/js/settings-personal.js new file mode 100644 index 0000000000..b798ba7e4e --- /dev/null +++ b/apps/encryption/js/settings-personal.js @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2013, Sam Tuke + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +function updatePrivateKeyPasswd() { + var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val(); + var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val(); + OC.msg.startSaving('#encryption .msg'); + $.post( + OC.filePath( 'files_encryption', 'ajax', 'updatePrivateKeyPassword.php' ) + , { oldPassword: oldPrivateKeyPassword, newPassword: newPrivateKeyPassword } + , function( data ) { + if (data.status === "error") { + OC.msg.finishedSaving('#encryption .msg', data); + } else { + OC.msg.finishedSaving('#encryption .msg', data); + } + } + ); +} + +$(document).ready(function(){ + + // Trigger ajax on recoveryAdmin status change + $( 'input:radio[name="userEnableRecovery"]' ).change( + function() { + var recoveryStatus = $( this ).val(); + OC.msg.startAction('#userEnableRecovery .msg', 'Updating recovery keys. This can take some time...'); + $.post( + OC.filePath( 'files_encryption', 'ajax', 'userrecovery.php' ) + , { userEnableRecovery: recoveryStatus } + , function( data ) { + OC.msg.finishedAction('#userEnableRecovery .msg', data); + } + ); + // Ensure page is not reloaded on form submit + return false; + } + ); + + $("#encryptAll").click( + function(){ + + // Hide feedback messages in case they're already visible + $('#encryptAllSuccess').hide(); + $('#encryptAllError').hide(); + + var userPassword = $( '#userPassword' ).val(); + var encryptAll = $( '#encryptAll' ).val(); + + $.post( + OC.filePath( 'files_encryption', 'ajax', 'encryptall.php' ) + , { encryptAll: encryptAll, userPassword: userPassword } + , function( data ) { + if ( data.status == "success" ) { + $('#encryptAllSuccess').show(); + } else { + $('#encryptAllError').show(); + } + } + ); + // Ensure page is not reloaded on form submit + return false; + } + + ); + + // update private key password + + $('input:password[name="changePrivateKeyPassword"]').keyup(function(event) { + var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val(); + var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val(); + if (newPrivateKeyPassword !== '' && oldPrivateKeyPassword !== '' ) { + $('button:button[name="submitChangePrivateKeyPassword"]').removeAttr("disabled"); + if(event.which === 13) { + updatePrivateKeyPasswd(); + } + } else { + $('button:button[name="submitChangePrivateKeyPassword"]').attr("disabled", "true"); + } + }); + + $('button:button[name="submitChangePrivateKeyPassword"]').click(function() { + updatePrivateKeyPasswd(); + }); + +}); diff --git a/apps/encryption/l10n/.gitkeep b/apps/encryption/l10n/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php index 43d3b84268..f036ea42cb 100644 --- a/apps/encryption/lib/crypto/encryption.php +++ b/apps/encryption/lib/crypto/encryption.php @@ -77,7 +77,7 @@ class Encryption implements IEncryptionModule { * @param array $header contains the header data read from the file * @param array $accessList who has access to the file contains the key 'users' and 'public' * - * $return array $header contain data as key-value pairs which should be + * @return array $header contain data as key-value pairs which should be * written to the header, in case of a write operation * or if no additional data is needed return a empty array */ diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index 4b898217d6..e03852c1f6 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -37,9 +37,9 @@ use \OCP\ISession; class KeyManager { /** - * @var ICache + * @var ISession */ - public static $cacheFactory; + public static $session; /** * @var IStorage */ @@ -87,24 +87,17 @@ class KeyManager { */ private $log; - /** - * @var \OCP\ISession - */ - private $session; - /** * @param IStorage $keyStorage * @param Crypt $crypt * @param IConfig $config - * @param Session $userSession + * @param IUserSession $userSession * @param \OCP\ISession $session - * @param ICacheFactory $cacheFactory * @param ILogger $log */ - public function __construct(IStorage $keyStorage, Crypt $crypt, IConfig $config, - IUserSession $userSession, ISession $session ,ICacheFactory $cacheFactory, ILogger $log) { + public function __construct(IStorage $keyStorage, Crypt $crypt, IConfig $config, IUserSession $userSession, ISession $session, ILogger $log) { - $this->session = $session; + self::$session = $session; $this->keyStorage = $keyStorage; $this->crypt = $crypt; $this->config = $config; @@ -113,9 +106,6 @@ class KeyManager { $this->publicShareKeyId = $this->config->getAppValue('encryption', 'publicShareKeyId'); $this->keyId = $userSession && $userSession->isLoggedIn() ? $userSession->getUser()->getUID() : false; - - self::$cacheFactory = $cacheFactory; - self::$cacheFactory = self::$cacheFactory->create('encryption'); $this->log = $log; } @@ -211,7 +201,7 @@ class KeyManager { * * @param string $uid userid * @param string $passPhrase users password - * @return ICache + * @return ISession */ public function init($uid, $passPhrase) { try { @@ -225,13 +215,10 @@ class KeyManager { } - $this->session->set('privateKey', $privateKey); - $this->session->set('initStatus', true); - self::$cacheFactory->set('privateKey', $privateKey); - self::$cacheFactory->set('initStatus', true); + self::$session->set('privateKey', $privateKey); + self::$session->set('initStatus', true); - - return self::$cacheFactory; + return self::$session; } /** @@ -256,12 +243,15 @@ class KeyManager { */ public function getFileKey($path, $uid) { $key = ''; - $encryptedFileKey = $this->keyStorage->getFileKey($path, $this->fileKeyId); + $encryptedFileKey = $this->keyStorage->getFileKey($path, + $this->fileKeyId); $shareKey = $this->getShareKey($path, $uid); $privateKey = $this->session->get('privateKey'); if ($encryptedFileKey && $shareKey && $privateKey) { - $key = $this->crypt->multiKeyDecrypt($encryptedFileKey, $shareKey, $privateKey); + $key = $this->crypt->multiKeyDecrypt($encryptedFileKey, + $shareKey, + $privateKey); } return $key; @@ -293,11 +283,13 @@ class KeyManager { if ($params['uid'] === $user->getUser()->getUID() && $privateKey) { // Encrypt private key with new user pwd as passphrase - $encryptedPrivateKey = $this->crypt->symmetricEncryptFileContent($privateKey, $params['password']); + $encryptedPrivateKey = $this->crypt->symmetricEncryptFileContent($privateKey, + $params['password']); // Save private key if ($encryptedPrivateKey) { - $this->setPrivateKey($user->getUser()->getUID(), $encryptedPrivateKey); + $this->setPrivateKey($user->getUser()->getUID(), + $encryptedPrivateKey); } else { $this->log->error('Encryption could not update users encryption password'); } @@ -331,7 +323,8 @@ class KeyManager { $this->setPublicKey($user, $keypair['publicKey']); // Encrypt private key with new password - $encryptedKey = $this->crypt->symmetricEncryptFileContent($keypair['privateKey'], $newUserPassword); + $encryptedKey = $this->crypt->symmetricEncryptFileContent($keypair['privateKey'], + $newUserPassword); if ($encryptedKey) { $this->setPrivateKey($user, $encryptedKey); @@ -431,4 +424,11 @@ class KeyManager { return $keys; } + + /** + * @return string returns openssl key + */ + public function getSystemPrivateKey() { + return $this->keyStorage->getSystemUserKey($this->privateKeyId); + } } diff --git a/apps/encryption/lib/util.php b/apps/encryption/lib/util.php index 5cc658a313..5fc08c6cc7 100644 --- a/apps/encryption/lib/util.php +++ b/apps/encryption/lib/util.php @@ -94,120 +94,6 @@ class Util { $this->config = $config; } - /** - * @param $dirPath - * @param bool $found - * @return array|bool - */ - private function findEncryptedFiles($dirPath, &$found = false) { - - if ($found === false) { - $found = [ - 'plain' => [], - 'encrypted' => [], - 'broken' => [], - ]; - } - - if ($this->files->is_dir($dirPath) && $handle = $this->files->opendir($dirPath)) { - if (is_resource($handle)) { - while (($file = readdir($handle) !== false)) { - if ($file !== '.' && $file !== '..') { - - // Skip stray part files - if ($this->isPartialFilePath($file)) { - continue; - } - - $filePath = $dirPath . '/' . $this->files->getRelativePath('/' . $file); - $relPath = $this->stripUserFilesPath($filePath); - - // If the path is a directory, search its contents - if ($this->files->is_dir($filePath)) { - // Recurse back - $this->findEncryptedFiles($filePath); - - /* - * If the path is a file, - * determine where they got re-enabled :/ - */ - } elseif ($this->files->is_file($filePath)) { - $isEncryptedPath = $this->isEncryptedPath($filePath); - - /** - * If the file is encrypted - * - * @note: if the userId is - * empty or not set, file will - * be detected as plain - * @note: this is inefficient; - * scanning every file like this - * will eat server resources :( - * fixMe: xxx find better way - */ - if ($isEncryptedPath) { - $fileKey = $this->keyManager->getFileKey($relPath); - $shareKey = $this->keyManager->getShareKey($relPath); - // If file is encrypted but now file key is available, throw exception - if (!$fileKey || !$shareKey) { - $this->logger->error('Encryption library, no keys avilable to decrypt the file: ' . $file); - $found['broken'][] = [ - 'name' => $file, - 'path' => $filePath, - ]; - } else { - $found['encrypted'][] = [ - 'name' => $file, - 'path' => $filePath - ]; - } - } else { - $found['plain'][] = [ - 'name' => $file, - 'path' => $filePath - ]; - } - } - } - - } - } - } - - return $found; - } - - /** - * @param $path - * @return bool - */ - private function isPartialFilePath($path) { - $extension = pathinfo($path, PATHINFO_EXTENSION); - - if ($extension === 'part') { - return true; - } - return false; - } - - /** - * @param $filePath - * @return bool|string - */ - private function stripUserFilesPath($filePath) { - $split = $this->splitPath($filePath); - - // It is not a file relative to data/user/files - if (count($split) < 4 || $split[2] !== 'files') { - return false; - } - - $sliced = array_slice($split, 3); - - return implode('/', $sliced); - - } - /** * @param $filePath * @return array @@ -218,41 +104,6 @@ class Util { return explode('/', $normalized); } - /** - * @param $filePath - * @return bool - */ - private function isEncryptedPath($filePath) { - $data = ''; - - // We only need 24 bytes from the last chunck - if ($this->files->file_exists($filePath)) { - $handle = $this->files->fopen($filePath, 'r'); - if (is_resource($handle)) { - // Suppress fseek warning, we handle the case that fseek - // doesn't work in the else branch - if (@fseek($handle, -24, SEEK_END) === 0) { - $data = fgets($handle); - } else { - // if fseek failed on the storage we create a local copy - // from the file and read this one - fclose($handle); - $localFile = $this->files->getLocalFile($filePath); - $handle = fopen($localFile, 'r'); - - if (is_resource($handle) && fseek($handle, - -24, - SEEK_END) === 0 - ) { - $data = fgets($handle); - } - } - fclose($handle); - return $this->crypt->isCatfileContent($data); - } - } - } - /** * @return bool */ @@ -287,8 +138,8 @@ class Util { * @param $recoveryPassword */ public function recoverUsersFiles($recoveryPassword) { - // todo: get system private key here -// $this->keyManager->get + $encryptedKey = $this->keyManager->getSystemPrivateKey(); + $privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword); @@ -329,25 +180,30 @@ class Util { */ private function recoverFile($filePath, $privateKey) { $sharingEnabled = Share::isEnabled(); + $uid = $this->user->getUID(); // Find out who, if anyone, is sharing the file if ($sharingEnabled) { $result = Share::getUsersSharingFile($filePath, - $this->user->getUID(), + $uid, true); $userIds = $result['users']; $userIds[] = 'public'; } else { $userIds = [ - $this->user->getUID(), + $uid, $this->recoveryKeyId ]; } $filteredUids = $this->filterShareReadyUsers($userIds); // Decrypt file key - $encKeyFile = $this->keyManager->getFileKey($filePath); - $shareKey = $this->keyManager->getShareKey($filePath); + $encKeyFile = $this->keyManager->getFileKey($filePath, + $uid); + + $shareKey = $this->keyManager->getShareKey($filePath, + $uid); + $plainKeyFile = $this->crypt->multiKeyDecrypt($encKeyFile, $shareKey, $privateKey); @@ -357,38 +213,12 @@ class Util { $multiEncryptionKey = $this->crypt->multiKeyEncrypt($plainKeyFile, $userPublicKeys); - $this->keyManager->setFileKeys($multiEncryptionKey['data']); - $this->keyManager->setShareKeys($multiEncryptionKey['keys']); - } + $this->keyManager->setFileKey($multiEncryptionKey['data'], + $uid); - /** - * @param $userIds - * @return array - */ - private function filterShareReadyUsers($userIds) { - // This array will collect the filtered IDs - $readyIds = $unreadyIds = []; - - // Loop though users and create array of UIDs that need new keyfiles - foreach ($userIds as $user) { - // Check that the user is encryption capable, or is the - // public system user (for public shares) - if ($this->isUserReady($user)) { - // construct array of ready UIDs for keymanager - $readyIds[] = $user; - } else { - // Construct array of unready UIDs for keymanager - $unreadyIds[] = $user; - - // Log warning; we cant do necessary setup here - // because we don't have the user passphrase - $this->logger->warning('Encryption Library ' . $this->user->getUID() . ' is not setup for encryption'); - } - } - return [ - 'ready' => $readyIds, - 'unready' => $unreadyIds - ]; + $this->keyManager->setShareKey($filePath, + $uid, + $multiEncryptionKey['keys']); } } diff --git a/apps/encryption/settings/settings-admin.php b/apps/encryption/settings/settings-admin.php index d3acdfe2ba..a32359bdfa 100644 --- a/apps/encryption/settings/settings-admin.php +++ b/apps/encryption/settings/settings-admin.php @@ -1,6 +1,6 @@ + * Copyright (c) 2015 Clark Tomlinson * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -16,7 +16,7 @@ $tmpl = new OCP\Template('files_encryption', 'settings-admin'); $recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled', '0'); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); -$tmpl->assign('initStatus', KeyManager::$cacheFactory->get('initStatus')); +$tmpl->assign('initStatus', KeyManager::$session->get('initStatus')); \OCP\Util::addscript('files_encryption', 'settings-admin'); \OCP\Util::addscript('core', 'multiselect'); diff --git a/apps/encryption/settings/settings-personal.php b/apps/encryption/settings/settings-personal.php index fe2d846f50..dc1ef167b1 100644 --- a/apps/encryption/settings/settings-personal.php +++ b/apps/encryption/settings/settings-personal.php @@ -1,17 +1,17 @@ + * Copyright (c) 2015 Clark Tomlinson * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ // Add CSS stylesheet -\OC_Util::addStyle('files_encryption', 'settings-personal'); +\OC_Util::addStyle('encryption', 'settings-personal'); -$tmpl = new OCP\Template('files_encryption', 'settings-personal'); +$tmpl = new OCP\Template('encryption', 'settings-personal'); -$user = \OCP\USER::getUser(); +$user = \OCP\User::getUser(); $view = new \OC\Files\View('/'); $util = new \OCA\Files_Encryption\Util($view, $user); $session = new \OCA\Files_Encryption\Session($view); @@ -20,14 +20,14 @@ $privateKeySet = $session->getPrivateKey() !== false; // did we tried to initialize the keys for this session? $initialized = $session->getInitialized(); -$recoveryAdminEnabled = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryAdminEnabled'); +$recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled'); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); $result = false; if ($recoveryAdminEnabled || !$privateKeySet) { - \OCP\Util::addscript('files_encryption', 'settings-personal'); + \OCP\Util::addscript('encryption', 'settings-personal'); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser); diff --git a/apps/encryption/tests/lib/KeyManagerTest.php b/apps/encryption/tests/lib/KeyManagerTest.php index 01c5e1d2d0..ed6048d764 100644 --- a/apps/encryption/tests/lib/KeyManagerTest.php +++ b/apps/encryption/tests/lib/KeyManagerTest.php @@ -45,10 +45,15 @@ class KeyManagerTest extends TestCase { $userMock ->method('getUID') ->will($this->returnValue('admin')); - $cacheMock = $this->getMock('OCP\ICacheFactory'); + $sessionMock = $this->getMock('OCP\ISession'); $logMock = $this->getMock('OCP\ILogger'); $this->userId = 'admin'; - $this->instance = new KeyManager($keyStorageMock, $cryptMock, $configMock, $userMock, $cacheMock, $logMock); + $this->instance = new KeyManager($keyStorageMock, + $cryptMock, + $configMock, + $userMock, + $sessionMock, + $logMock); $this->dummyKeys = ['public' => 'randomweakpublickeyhere', 'private' => 'randomweakprivatekeyhere']; @@ -87,14 +92,16 @@ class KeyManagerTest extends TestCase { */ public function testSetPublicKey() { - $this->assertTrue($this->instance->setPublicKey($this->userId, $this->dummyKeys['public'])); + $this->assertTrue($this->instance->setPublicKey($this->userId, + $this->dummyKeys['public'])); } /** * */ public function testSetPrivateKey() { - $this->assertTrue($this->instance->setPrivateKey($this->userId, $this->dummyKeys['private'])); + $this->assertTrue($this->instance->setPrivateKey($this->userId, + $this->dummyKeys['private'])); } /**