/** * restore encryption keys from trash bin * * @param \OC\Files\View $view * @param string $file complete path to file * @param string $filename name of file * @param string $uniqueFilename new file name to restore the file without overwriting existing files * @param string $location location of file * @param int $timestamp deleteion time * */ private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp) { // Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!) if (\OCP\App::isEnabled('files_encryption')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); list($owner, $ownerPath) = self::getUidAndFilename($target); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user); if ($util->isSystemWideMountPoint($ownerPath)) { $baseDir = '/files_encryption/'; } else { $baseDir = $owner . '/files_encryption/'; } $path_parts = pathinfo($file); $source_location = $path_parts['dirname']; if ($view->is_dir('/files_trashbin/keyfiles/' . $file)) { if ($source_location != '.') { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename); } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $filename); } } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename . '.key'); } if ($timestamp) { $keyfile .= '.d' . $timestamp; } // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($rootView->file_exists($keyfile)) { // handle directory if ($rootView->is_dir($keyfile)) { // handle keyfiles $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath); // handle share-keys if ($timestamp) { $sharekey .= '.d' . $timestamp; } $rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath); } else { // handle keyfiles $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key'); // handle share-keys $ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey'); if ($timestamp) { $ownerShareKey .= '.d' . $timestamp; } // move only owners key $rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey'); // try to re-share if file is shared $filesystemView = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($filesystemView); $util = new \OCA\Encryption\Util($filesystemView, $user); // fix the file size $absolutePath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files/' . $ownerPath); $util->fixFileSize($absolutePath); // get current sharing state $sharingEnabled = \OCP\Share::isEnabled(); // get users sharing this file $usersSharing = $util->getSharingUsersArray($sharingEnabled, $target); // Attempt to set shareKey $util->setSharedFileKeyfiles($session, $usersSharing, $target); } } // enable proxy \OC_FileProxy::$enabled = $proxyStatus; } }
<?php OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); //encryption app needs to be loaded OC_App::loadApp('files_encryption'); // init encryption app $params = array('uid' => \OCP\User::getUser(), 'password' => $_POST['password']); $view = new OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, \OCP\User::getUser()); $l = \OC_L10N::get('settings'); $result = $util->initEncryption($params); if ($result !== false) { try { $successful = $util->decryptAll(); } catch (\Exception $ex) { \OCP\Util::writeLog('encryption library', "Decryption finished unexpected: " . $ex->getMessage(), \OCP\Util::ERROR); $successful = false; } $util->closeEncryptionSession(); if ($successful === true) { \OCP\JSON::success(array('data' => array('message' => $l->t('Files decrypted successfully')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Couldn\'t decrypt your files, please check your owncloud.log or ask your administrator')))); } } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Couldn\'t decrypt your files, check your password and try again')))); }
/** * @large */ function testRecoveryForUser() { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $result = \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); $this->assertTrue($result); $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // enable recovery for admin $this->assertTrue($util->setRecoveryForUser(1)); // add recovery keys for existing files (e.g. the auto-generated welcome.txt) $util->addRecoveryKeys(); // create folder structure $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1); $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder); $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder . $this->subsubfolder); // save file with content $cryptedFile1 = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename, $this->dataShort); $cryptedFile2 = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile1)); $this->assertTrue(is_int($cryptedFile2)); // check if share key for user and recovery exists $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // change password \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123'); $params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'password' => 'test', 'recoveryPassword' => 'test123'); \OCA\Encryption\Hooks::setPassphrase($params); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test'); // get file contents $retrievedCryptedFile1 = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); $retrievedCryptedFile2 = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedCryptedFile1); $this->assertEquals($this->dataShort, $retrievedCryptedFile2); // cleanup $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/'); $this->view->unlink($this->folder1); $this->view->unlink($this->filename); $this->view->chroot('/'); // check if share key for user and recovery exists $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // disable recovery for admin $this->assertTrue($util->setRecoveryForUser(0)); \OCA\Encryption\Helper::adminDisableRecovery('test123'); $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')); //clean up, reset passwords \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test123'); $params = array('uid' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'password' => \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'recoveryPassword' => 'test123'); \OCA\Encryption\Hooks::setPassphrase($params); }
<?php $session = new \OCA\Encryption\Session(\OC::$server->getSession()); $userSession = \OC::$server->getUserSession(); $template = new OCP\Template('encryption', 'settings-personal'); $crypt = new \OCA\Encryption\Crypto\Crypt(\OC::$server->getLogger(), $userSession, \OC::$server->getConfig()); $util = new \OCA\Encryption\Util(new \OC\Files\View(), $crypt, \OC::$server->getLogger(), $userSession, \OC::$server->getConfig(), \OC::$server->getUserManager()); $keyManager = new \OCA\Encryption\KeyManager(\OC::$server->getEncryptionKeyStorage(), $crypt, \OC::$server->getConfig(), $userSession, $session, \OC::$server->getLogger(), $util); $user = $userSession->getUser()->getUID(); $view = new \OC\Files\View('/'); $privateKeySet = $session->isPrivateKeySet(); // did we tried to initialize the keys for this session? $initialized = $session->getStatus(); $recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled'); $recoveryEnabledForUser = $util->isRecoveryEnabledForUser($user); $result = false; if ($recoveryAdminEnabled || !$privateKeySet) { $template->assign('recoveryEnabled', $recoveryAdminEnabled); $template->assign('recoveryEnabledForUser', $recoveryEnabledForUser); $template->assign('privateKeySet', $privateKeySet); $template->assign('initialized', $initialized); $result = $template->fetchPage(); } return $result;
/** * @brief enable recovery * * @param $recoveryKeyId * @param $recoveryPassword * @internal param \OCA\Encryption\Util $util * @internal param string $password * @return bool */ public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) { $view = new \OC\Files\View('/'); if ($recoveryKeyId === null) { $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); } if (!$view->is_dir('/owncloud_private_key')) { $view->mkdir('/owncloud_private_key'); } if (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key") || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key")) { $keypair = \OCA\Encryption\Crypt::createKeypair(); \OC_FileProxy::$enabled = false; // Save public key if (!$view->is_dir('/public-keys')) { $view->mkdir('/public-keys'); } $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']); // Encrypt private key empty passphrase $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword); // Save private key $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey); \OC_FileProxy::$enabled = true; // Set recoveryAdmin as enabled \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); $return = true; } else { // get recovery key and check the password $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); } } return $return; }
* @author Lukas Reschke <*****@*****.**> * @author Thomas Müller <*****@*****.**> * * @copyright Copyright (c) 2016, 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 <http://www.gnu.org/licenses/> * */ \OC_Util::checkAdminUser(); $tmpl = new OCP\Template('encryption', 'settings-admin'); $crypt = new \OCA\Encryption\Crypto\Crypt(\OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig()); $util = new \OCA\Encryption\Util(new \OC\Files\View(), $crypt, \OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig(), \OC::$server->getUserManager()); // Check if an adminRecovery account is enabled for recovering files after lost pwd $recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled', '0'); $session = new \OCA\Encryption\Session(\OC::$server->getSession()); $encryptHomeStorage = $util->shouldEncryptHomeStorage(); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('initStatus', $session->getStatus()); $tmpl->assign('encryptHomeStorage', $encryptHomeStorage); return $tmpl->fetchPage();
if (OC_User::isAdminUser(OC_User::getUser())) { $userstatus = 'admin'; } if (OC_SubAdmin::isUserAccessible(OC_User::getUser(), $username)) { $userstatus = 'subadmin'; } if (OC_User::getUser() === $username && OC_User::checkPassword($username, $oldPassword)) { $userstatus = 'user'; } if (is_null($userstatus)) { OC_JSON::error(array('data' => array('message' => 'Authentication error'))); exit; } if (\OCP\App::isEnabled('files_encryption') && $userstatus !== 'user') { //handle the recovery case $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $username); $recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); $validRecoveryPassword = false; $recoveryPasswordSupported = false; if ($recoveryAdminEnabled) { $validRecoveryPassword = $util->checkRecoveryPassword($recoveryPassword); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); } if ($recoveryEnabledForUser && $recoveryPassword === '') { OC_JSON::error(array('data' => array('message' => 'Please provide a admin recovery password, otherwise all user data will be lost'))); } elseif ($recoveryEnabledForUser && !$validRecoveryPassword) { OC_JSON::error(array('data' => array('message' => 'Wrong admin recovery password. Please check the password and try again.'))); } else { // now we know that everything is fine regarding the recovery password, let's try to change the password $result = OC_User::setPassword($username, $password, $recoveryPassword); if (!$result && $recoveryPasswordSupported) {
/** * test if all keys get moved to the backup folder correctly */ function testBackupAllKeys() { self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1); // create some dummy key files $encPath = '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '/files_encryption'; $this->view->file_put_contents($encPath . '/keyfiles/foo.key', 'key'); $this->view->file_put_contents($encPath . '/share-keys/foo.user1.shareKey', 'share key'); $this->view->mkdir($encPath . '/keyfiles/subfolder/'); $this->view->mkdir($encPath . '/share-keys/subfolder/'); $this->view->file_put_contents($encPath . '/keyfiles/subfolder/foo.key', 'key'); $this->view->file_put_contents($encPath . '/share-keys/subfolder/foo.user1.shareKey', 'share key'); $util = new \OCA\Encryption\Util($this->view, self::TEST_ENCRYPTION_UTIL_USER1); $util->backupAllKeys('testing'); $encFolderContent = $this->view->getDirectoryContent($encPath); $backupPath = ''; foreach ($encFolderContent as $c) { $name = $c['name']; if (substr($name, 0, strlen('backup')) === 'backup') { $backupPath = $encPath . '/' . $c['name']; break; } } $this->assertTrue($backupPath !== ''); // check backupDir Content $this->assertTrue($this->view->is_dir($backupPath . '/keyfiles')); $this->assertTrue($this->view->is_dir($backupPath . '/share-keys')); $this->assertTrue($this->view->file_exists($backupPath . '/keyfiles/foo.key')); $this->assertTrue($this->view->file_exists($backupPath . '/share-keys/foo.user1.shareKey')); $this->assertTrue($this->view->file_exists($backupPath . '/keyfiles/subfolder/foo.key')); $this->assertTrue($this->view->file_exists($backupPath . '/share-keys/subfolder/foo.user1.shareKey')); $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.private.key')); $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.public.key')); //cleanup $this->view->deleteAll($backupPath); $this->view->unlink($encPath . '/keyfiles/foo.key', 'key'); $this->view->unlink($encPath . '/share-keys/foo.user1.shareKey', 'share key'); }
/** * Copyright (c) 2013, Sam Tuke <*****@*****.**> * This file is licensed under the Affero General Public License version 3 or later. * See the COPYING-README file. * * Script to handle admin settings for encrypted key recovery */ use OCA\Encryption; \OCP\JSON::checkLoggedIn(); \OCP\JSON::checkAppEnabled('files_encryption'); \OCP\JSON::callCheck(); $l = \OC::$server->getL10N('files_encryption'); if (isset($_POST['userEnableRecovery']) && (0 == $_POST['userEnableRecovery'] || '1' === $_POST['userEnableRecovery'])) { $userId = \OCP\USER::getUser(); $view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, $userId); // Save recovery preference to DB $return = $util->setRecoveryForUser($_POST['userEnableRecovery']); if ($_POST['userEnableRecovery'] === '1') { $util->addRecoveryKeys(); } else { $util->removeRecoveryKeys(); } } else { $return = false; } // Return success or failure if ($return) { \OCP\JSON::success(array('data' => array('message' => $l->t('File recovery settings updated')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update file recovery'))));
public static function changeUserPassword($args) { // Check if we are an user \OC_JSON::callCheck(); \OC_JSON::checkLoggedIn(); // Manually load apps to ensure hooks work correctly (workaround for issue 1503) \OC_App::loadApps(); if (isset($_POST['username'])) { $username = $_POST['username']; } else { $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('No user supplied')))); exit; } $password = isset($_POST['password']) ? $_POST['password'] : null; $recoveryPassword = isset($_POST['recoveryPassword']) ? $_POST['recoveryPassword'] : null; if (\OC_User::isAdminUser(\OC_User::getUser())) { $userstatus = 'admin'; } elseif (\OC_SubAdmin::isUserAccessible(\OC_User::getUser(), $username)) { $userstatus = 'subadmin'; } else { $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('Authentication error')))); exit; } if (\OC_App::isEnabled('files_encryption')) { //handle the recovery case $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $username); $recoveryAdminEnabled = \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); $validRecoveryPassword = false; $recoveryPasswordSupported = false; if ($recoveryAdminEnabled) { $validRecoveryPassword = $util->checkRecoveryPassword($recoveryPassword); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); } if ($recoveryEnabledForUser && $recoveryPassword === '') { $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('Please provide an admin recovery password, otherwise all user data will be lost')))); } elseif ($recoveryEnabledForUser && !$validRecoveryPassword) { $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('Wrong admin recovery password. Please check the password and try again.')))); } else { // now we know that everything is fine regarding the recovery password, let's try to change the password $result = \OC_User::setPassword($username, $password, $recoveryPassword); if (!$result && $recoveryPasswordSupported) { $l = new \OC_L10n('settings'); \OC_JSON::error(array("data" => array("message" => $l->t("Back-end doesn't support password change, but the users encryption key was successfully updated.")))); } elseif (!$result && !$recoveryPasswordSupported) { $l = new \OC_L10n('settings'); \OC_JSON::error(array("data" => array("message" => $l->t("Unable to change password")))); } else { \OC_JSON::success(array("data" => array("username" => $username))); } } } else { // if encryption is disabled, proceed if (!is_null($password) && \OC_User::setPassword($username, $password)) { \OC_JSON::success(array('data' => array('username' => $username))); } else { $l = new \OC_L10n('settings'); \OC_JSON::error(array('data' => array('message' => $l->t('Unable to change password')))); } } }
* @author Thomas Müller <*****@*****.**> * * @copyright Copyright (c) 2016, 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 <http://www.gnu.org/licenses/> * */ \OC_Util::checkAdminUser(); $tmpl = new OCP\Template('encryption', 'settings-admin'); $crypt = new \OCA\Encryption\Crypto\Crypt(\OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig(), \OC::$server->getL10N('encryption')); $util = new \OCA\Encryption\Util(new \OC\Files\View(), $crypt, \OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig(), \OC::$server->getUserManager()); // Check if an adminRecovery account is enabled for recovering files after lost pwd $recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled', '0'); $session = new \OCA\Encryption\Session(\OC::$server->getSession()); $encryptHomeStorage = $util->shouldEncryptHomeStorage(); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('initStatus', $session->getStatus()); $tmpl->assign('encryptHomeStorage', $encryptHomeStorage); $tmpl->assign('masterKeyEnabled', $util->isMasterKeyEnabled()); return $tmpl->fetchPage();
/** * @large */ function testRecoveryForUser() { $this->markTestIncomplete('This test drives Jenkins crazy - "Cannot modify header information - headers already sent" - line 811'); // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123'); $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); // enable recovery for admin $this->assertTrue($util->setRecoveryForUser(1)); // create folder structure $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1); $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder); $this->view->mkdir('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder . $this->subsubfolder); // save file with content $cryptedFile1 = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename, $this->dataShort); $cryptedFile2 = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile1)); $this->assertTrue(is_int($cryptedFile2)); // check if share key for user and recovery exists $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // change password \OC_User::setPassword(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, 'test', 'test123'); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, false, 'test'); // get file contents $retrievedCryptedFile1 = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); $retrievedCryptedFile2 = file_get_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedCryptedFile1); $this->assertEquals($this->dataShort, $retrievedCryptedFile2); // cleanup $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->folder1); $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files' . $this->filename); // check if share key for user and recovery exists $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder . '/' . $this->filename . '.' . $recoveryKeyId . '.shareKey')); // enable recovery for admin $this->assertTrue($util->setRecoveryForUser(0)); \OCA\Encryption\Helper::adminDisableRecovery('test123'); $this->assertEquals(0, \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled')); }
$errorMessage = $l->t('Please provide a new recovery password'); \OCP\JSON::error(array('data' => array('message' => $errorMessage))); exit; } if (empty($_POST['confirmPassword'])) { $errorMessage = $l->t('Please repeat the new recovery password'); \OCP\JSON::error(array('data' => array('message' => $errorMessage))); exit; } if ($_POST['newPassword'] !== $_POST['confirmPassword']) { $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password'); \OCP\JSON::error(array('data' => array('message' => $errorMessage))); exit; } $view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser()); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $keyId = $util->getRecoveryKeyId(); $keyPath = '/owncloud_private_key/' . $keyId . '.private.key'; $encryptedRecoveryKey = $view->file_get_contents($keyPath); $decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword); if ($decryptedRecoveryKey) { $cipher = \OCA\Encryption\Helper::getCipher(); $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword, $cipher); if ($encryptedKey) { \OCA\Encryption\Keymanager::setPrivateSystemKey($encryptedKey, $keyId . '.private.key'); $return = true; } } \OC_FileProxy::$enabled = $proxyStatus;
function testDecryptAll() { $filename = "/decryptAll" . uniqid() . ".txt"; $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/'); $userdir = $datadir . '/' . $this->userId . '/files/'; $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort); $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); $this->assertTrue($fileInfoEncrypted instanceof \OC\Files\FileInfo); $this->assertEquals($fileInfoEncrypted['encrypted'], 1); $encContent = file_get_contents($userdir . $filename); \OC_App::disable('files_encryption'); $user = \OCP\User::getUser(); $this->logoutHelper(); $this->loginHelper($user, false, false, false); $content = file_get_contents($userdir . $filename); //content should be encrypted $this->assertSame($encContent, $content); // now we load the encryption app again OC_App::loadApp('files_encryption'); // init encryption app $params = array('uid' => \OCP\User::getUser(), 'password' => \OCP\User::getUser()); $view = new OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, \OCP\User::getUser()); $result = $util->initEncryption($params); $this->assertTrue($result instanceof \OCA\Encryption\Session); $successful = $util->decryptAll(); $this->assertTrue($successful); $this->logoutHelper(); $this->loginHelper($user, false, false, false); // file should be unencrypted and fileInfo should contain the correct values $content = file_get_contents($userdir . $filename); // now we should get the plain data $this->assertSame($this->dataShort, $content); $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); $this->assertTrue($fileInfoUnencrypted instanceof \OC\Files\FileInfo); // check if mtime and etags unchanged $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); // 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'); }
<?php /** * Copyright (c) 2013 Sam Tuke <*****@*****.**> * 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'); $tmpl = new OCP\Template('files_encryption', 'settings-personal'); $user = \OCP\USER::getUser(); $view = new \OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, $user); $session = new \OCA\Encryption\Session($view); $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'); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); $result = false; if ($recoveryAdminEnabled || !$privateKeySet) { \OCP\Util::addscript('files_encryption', 'settings-personal'); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser); $tmpl->assign('privateKeySet', $privateKeySet); $tmpl->assign('initialized', $initialized); $result = $tmpl->fetchPage(); } return $result;
* @author Clark Tomlinson <*****@*****.**> * @author Thomas Müller <*****@*****.**> * * @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 <http://www.gnu.org/licenses/> * */ \OC_Util::checkAdminUser(); $tmpl = new OCP\Template('encryption', 'settings-admin'); $crypt = new \OCA\Encryption\Crypto\Crypt(\OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig()); $util = new \OCA\Encryption\Util(new \OC\Files\View(), $crypt, \OC::$server->getLogger(), \OC::$server->getUserSession(), \OC::$server->getConfig(), \OC::$server->getUserManager()); // Check if an adminRecovery account is enabled for recovering files after lost pwd $recoveryAdminEnabled = \OC::$server->getConfig()->getAppValue('encryption', 'recoveryAdminEnabled', '0'); $session = new \OCA\Encryption\Session(\OC::$server->getSession()); $encryptHomeStorage = $util->shouldEncryptHomeStorage($user); $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('initStatus', $session->getStatus()); $tmpl->assign('encryptHomeStorage', $encryptHomeStorage); return $tmpl->fetchPage();