public static function setUpBeforeClass() { parent::setUpBeforeClass(); // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); \OC_Hook::clear('OC_Filesystem'); \OC_Hook::clear('OC_User'); \OC_Hook::clear('OCP\\Share'); // trashbin hooks \OCA\Files_Trashbin\Trashbin::registerHooks(); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // register share hooks \OC::registerShareHooks(); \OCA\Files_Sharing\Helper::registerHooks(); // Sharing related hooks \OCA\Encryption\Helper::registerShareHooks(); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Files\Share\Proxy()); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user self::loginHelper(self::TEST_ENCRYPTION_TRASHBIN_USER2, true); self::loginHelper(self::TEST_ENCRYPTION_TRASHBIN_USER1, true); }
public static function setUpBeforeClass() { parent::setUpBeforeClass(); // note: not using a data provider because these // files all need to coexist to make sure the // share keys are found properly (pattern matching) self::$testFiles = array('t est.txt', 't est_.txt', 't est.doc.txt', 't est(.*).txt', 'multiple.dots.can.happen.too.txt', 't est.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.txt', 't est_.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey.txt', 'who would upload their.shareKey', 'user ones file.txt', 'user ones file.txt.backup', '.t est.txt'); // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); \OC_Hook::clear('OC_Filesystem'); \OC_Hook::clear('OC_User'); // clear share hooks \OC_Hook::clear('OCP\\Share'); \OC::registerShareHooks(); \OCP\Util::connectHook('OC_Filesystem', 'setup', '\\OC\\Files\\Storage\\Shared', 'setup'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // Sharing related hooks \OCA\Encryption\Helper::registerShareHooks(); // clear and register proxies \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true); self::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true); }
function testGetPathToRealFile() { // the relative path to /user/files/ that's what we want to get from getPathToRealFile() $relativePath = "foo/bar/test.txt"; // test paths $versionPath = "/user/files_versions/foo/bar/test.txt.v456756835"; $cachePath = "/user/cache/transferid636483/foo/bar/test.txt"; $this->assertEquals($relativePath, Encryption\Helper::getPathToRealFile($versionPath)); $this->assertEquals($relativePath, Encryption\Helper::getPathToRealFile($cachePath)); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user \Test_Encryption_Util::loginHelper(\Test_Encryption_Stream::TEST_ENCRYPTION_STREAM_USER1, true); }
public static function setUpBeforeClass() { parent::setUpBeforeClass(); // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); \OC_Hook::clear('OC_Filesystem'); \OC_Hook::clear('OC_User'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user self::loginHelper(\Test_Encryption_Proxy::TEST_ENCRYPTION_PROXY_USER1, true); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // disable file proxy by default \OC_FileProxy::$enabled = false; // create test user \OC_User::deleteUser(\Test_Encryption_Keymanager::TEST_USER); \Test_Encryption_Util::loginHelper(\Test_Encryption_Keymanager::TEST_USER, true); }
function testGetUser() { $path1 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/files/foo/bar.txt"; $path2 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/cache/foo/bar.txt"; $path3 = "/" . self::TEST_ENCRYPTION_HELPER_USER1 . "/thumbnails/foo"; $path4 = "/" . "/" . self::TEST_ENCRYPTION_HELPER_USER1; // if we are logged-in every path should return the currently logged-in user $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path3)); // now log out \Test_Encryption_Util::logoutHelper(); // now we should only get the user from /user/files and user/cache paths $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path1)); $this->assertEquals(self::TEST_ENCRYPTION_HELPER_USER1, Encryption\Helper::getUser($path2)); $this->assertFalse(Encryption\Helper::getUser($path3)); $this->assertFalse(Encryption\Helper::getUser($path4)); // Log-in again \Test_Encryption_Util::loginHelper(\Test_Encryption_Helper::TEST_ENCRYPTION_HELPER_USER1); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1, true); \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER2, true); \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_LEGACY_USER, true); // create groups \OC_Group::createGroup(self::TEST_ENCRYPTION_UTIL_GROUP1); \OC_Group::createGroup(self::TEST_ENCRYPTION_UTIL_GROUP2); // add user 1 to group1 \OC_Group::addToGroup(self::TEST_ENCRYPTION_UTIL_USER1, self::TEST_ENCRYPTION_UTIL_GROUP1); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // disable file proxy by default \OC_FileProxy::$enabled = false; // remember files_trashbin state self::$stateFilesTrashbin = OC_App::isEnabled('files_trashbin'); // we don't want to tests with app files_trashbin enabled \OC_App::disable('files_trashbin'); // create test user \OC_User::deleteUser(\Test_Encryption_Keymanager::TEST_USER); \Test_Encryption_Util::loginHelper(\Test_Encryption_Keymanager::TEST_USER, true); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); \OC_Hook::clear('OC_Filesystem'); \OC_Hook::clear('OC_User'); // clear share hooks \OC_Hook::clear('OCP\\Share'); \OC::registerShareHooks(); \OCP\Util::connectHook('OC_Filesystem', 'setup', '\\OC\\Files\\Storage\\Shared', 'setup'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // Sharing related hooks \OCA\Encryption\Helper::registerShareHooks(); // clear and register proxies \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // create test user \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER1, true); \Test_Encryption_Util::loginHelper(\Test_Encryption_Hooks::TEST_ENCRYPTION_HOOKS_USER2, true); }
public static function setUpBeforeClass() { // reset backend \OC_User::clearBackends(); \OC_User::useBackend('database'); // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); // disable file proxy by default \OC_FileProxy::$enabled = false; // setup filesystem \OC_Util::tearDownFS(); \OC_User::setUserId(''); \OC\Files\Filesystem::tearDown(); \OC_Util::setupFS('admin'); \OC_User::setUserId('admin'); // login admin $params['uid'] = 'admin'; $params['password'] = '******'; OCA\Encryption\Hooks::login($params); }
/** * @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); }
/** * @brief Gets user or public share private key from session * @returns string $privateKey The user's plaintext private key * */ public function getPrivateKey() { // return the public share private key if this is a public access if (\OCA\Encryption\Helper::isPublicAccess()) { return $this->getPublicSharePrivateKey(); } else { if (!is_null(\OC::$session->get('privateKey'))) { return \OC::$session->get('privateKey'); } else { return false; } } }
/** * Tests whether share keys can be found * * @dataProvider userNamesProvider */ function testFindShareKeys($userName) { self::setUpUsers(); // note: not using dataProvider as we want to make // sure that the correct keys are match and not any // other ones that might happen to have similar names self::setupHooks(); self::loginHelper($userName, true); $testDir = 'testFindShareKeys' . $this->getUniqueID() . '/'; $baseDir = $userName . '/files/' . $testDir; $fileList = array('t est.txt', 't est_.txt', 't est.doc.txt', 't est(.*).txt', 'multiple.dots.can.happen.too.txt', 't est.' . $userName . '.txt', 't est_.' . $userName . '.shareKey.txt', 'who would upload their.shareKey', 'user ones file.txt', 'user ones file.txt.backup', '.t est.txt'); $rootView = new \OC\Files\View('/'); $rootView->mkdir($baseDir); foreach ($fileList as $fileName) { $rootView->file_put_contents($baseDir . $fileName, 'dummy'); } $shareKeysDir = $userName . '/files_encryption/share-keys/' . $testDir; foreach ($fileList as $fileName) { // make sure that every file only gets its correct respective keys $result = Encryption\Helper::findShareKeys($baseDir . $fileName, $shareKeysDir . $fileName, $rootView); $this->assertEquals(array($shareKeysDir . $fileName . '.' . $userName . '.shareKey'), $result); } self::cleanUpUsers(); }
/** * @brief Gets user or public share private key from session * @returns string $privateKey The user's plaintext private key * */ public function getPrivateKey() { // return the public share private key if this is a public access if (\OCA\Encryption\Helper::isPublicAccess()) { return $this->getPublicSharePrivateKey(); } else { if (isset($_SESSION['privateKey']) && !empty($_SESSION['privateKey'])) { return $_SESSION['privateKey']; } else { return false; } } }
/** * Find, sanitise and format users sharing a file * @note This wraps other methods into a portable bundle * @param boolean $sharingEnabled * @param string $filePath path relativ to current users files folder */ public function getSharingUsersArray($sharingEnabled, $filePath) { $appConfig = \OC::$server->getAppConfig(); // Check if key recovery is enabled if ($appConfig->getValue('files_encryption', 'recoveryAdminEnabled') && $this->recoveryEnabledForUser()) { $recoveryEnabled = true; } else { $recoveryEnabled = false; } // Make sure that a share key is generated for the owner too list($owner, $ownerPath) = $this->getUidAndFilename($filePath); $ownerPath = \OCA\Encryption\Helper::stripPartialFileExtension($ownerPath); // always add owner to the list of users with access to the file $userIds = array($owner); if ($sharingEnabled) { // Find out who, if anyone, is sharing the file $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner); $userIds = \array_merge($userIds, $result['users']); if ($result['public']) { $userIds[] = $this->publicShareKeyId; } } // If recovery is enabled, add the // Admin UID to list of users to share to if ($recoveryEnabled) { // Find recoveryAdmin user ID $recoveryKeyId = $appConfig->getValue('files_encryption', 'recoveryKeyId'); // Add recoveryAdmin to list of users sharing $userIds[] = $recoveryKeyId; } // check if it is a group mount if (\OCP\App::isEnabled("files_external")) { $mounts = \OC_Mount_Config::getSystemMountPoints(); foreach ($mounts as $mount) { if ($mount['mountpoint'] == substr($ownerPath, 1, strlen($mount['mountpoint']))) { $userIds = array_merge($userIds, $this->getUserWithAccessToMountPoint($mount['applicable']['users'], $mount['applicable']['groups'])); } } } // Remove duplicate UIDs $uniqueUserIds = array_unique($userIds); return $uniqueUserIds; }
/** * @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing * @param array with oldpath and newpath * * This function is connected to the rename signal of OC_Filesystem and adjust the name and location * of the stored versions along the actual file */ public static function postRename($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); // Format paths to be relative to user files dir if ($util->isSystemWideMountPoint($params['oldpath'])) { $baseDir = 'files_encryption/'; $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath']; } else { $baseDir = $userId . '/' . 'files_encryption/'; $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath']; } if ($util->isSystemWideMountPoint($params['newpath'])) { $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath']; } else { $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath']; } // add key ext if this is not an folder if (!$view->is_dir($oldKeyfilePath)) { $oldKeyfilePath .= '.key'; $newKeyfilePath .= '.key'; // handle share-keys $localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']); $escapedPath = Helper::escapeGlobPattern($localKeyPath); $matches = glob($escapedPath . '*.shareKey'); foreach ($matches as $src) { $dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src)); // create destination folder if not exists if (!file_exists(dirname($dst))) { mkdir(dirname($dst), 0750, true); } rename($src, $dst); } } else { // handle share-keys folders $oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath']; $newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath']; // create destination folder if not exists if (!$view->file_exists(dirname($newShareKeyfilePath))) { $view->mkdir(dirname($newShareKeyfilePath), 0750, true); } $view->rename($oldShareKeyfilePath, $newShareKeyfilePath); } // Rename keyfile so it isn't orphaned if ($view->file_exists($oldKeyfilePath)) { // create destination folder if not exists if (!$view->file_exists(dirname($newKeyfilePath))) { $view->mkdir(dirname($newKeyfilePath), 0750, true); } $view->rename($oldKeyfilePath, $newKeyfilePath); } // build the path to the file $newPath = '/' . $userId . '/files' . $params['newpath']; $newPathRelative = $params['newpath']; if ($util->fixFileSize($newPath)) { // get sharing app state $sharingEnabled = \OCP\Share::isEnabled(); // get users $usersSharing = $util->getSharingUsersArray($sharingEnabled, $newPathRelative); // update sharing-keys $util->setSharedFileKeyfiles($session, $usersSharing, $newPathRelative); } \OC_FileProxy::$enabled = $proxyStatus; }
/** * @medium * test if stream wrapper can read files outside from the data folder */ function testStreamFromLocalFile() { $filename = '/' . $this->userId . '/files/' . 'tmp-' . uniqid() . '.txt'; $tmpFilename = "/tmp/" . uniqid() . ".txt"; // write an encrypted file $cryptedFile = $this->view->file_put_contents($filename, $this->dataShort); // Test that data was successfully written $this->assertTrue(is_int($cryptedFile)); // create a copy outside of the data folder in /tmp $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $encryptedContent = $this->view->file_get_contents($filename); \OC_FileProxy::$enabled = $proxyStatus; file_put_contents($tmpFilename, $encryptedContent); \OCA\Encryption\Helper::addTmpFileToMapper($tmpFilename, $filename); // try to read the file from /tmp $handle = fopen("crypt://" . $tmpFilename, "r"); $contentFromTmpFile = stream_get_contents($handle); // check if it was successful $this->assertEquals($this->dataShort, $contentFromTmpFile); // clean up unlink($tmpFilename); $this->view->unlink($filename); }
* 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::checkAdminUser(); \OCP\JSON::checkAppEnabled('files_encryption'); \OCP\JSON::callCheck(); $l = OC_L10N::get('files_encryption'); $return = false; // Enable recoveryAdmin $recoveryKeyId = \OC::$server->getAppConfig()->getValue('files_encryption', 'recoveryKeyId'); if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] === '1') { $return = \OCA\Encryption\Helper::adminEnableRecovery($recoveryKeyId, $_POST['recoveryPassword']); // Return success or failure if ($return) { \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully enabled')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not enable recovery key. Please check your recovery key password!')))); } // Disable recoveryAdmin } elseif (isset($_POST['adminEnableRecovery']) && '0' === $_POST['adminEnableRecovery']) { $return = \OCA\Encryption\Helper::adminDisableRecovery($_POST['recoveryPassword']); // Return success or failure if ($return) { \OCP\JSON::success(array('data' => array('message' => $l->t('Recovery key successfully disabled')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not disable recovery key. Please check your recovery key password!')))); } }
/** * after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing * @param array $params array with oldpath and newpath * * This function is connected to the rename signal of OC_Filesystem and adjust the name and location * of the stored versions along the actual file */ public static function postRename($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); if (isset(self::$renamedFiles[$params['oldpath']]['uid']) && isset(self::$renamedFiles[$params['oldpath']]['path'])) { $ownerOld = self::$renamedFiles[$params['oldpath']]['uid']; $pathOld = self::$renamedFiles[$params['oldpath']]['path']; } else { \OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG); return false; } list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']); // Format paths to be relative to user files dir if ($util->isSystemWideMountPoint($pathOld)) { $oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld; } else { $oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld; } if ($util->isSystemWideMountPoint($pathNew)) { $newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = 'files_encryption/share-keys/' . $pathNew; } else { $newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew; } // create new key folders if it doesn't exists if (!$view->file_exists(dirname($newShareKeyPath))) { $view->mkdir(dirname($newShareKeyPath)); } if (!$view->file_exists(dirname($newKeyfilePath))) { $view->mkdir(dirname($newKeyfilePath)); } // handle share keys if (!$view->is_dir($oldKeyfilePath)) { $oldKeyfilePath .= '.key'; $newKeyfilePath .= '.key'; // handle share-keys $matches = Helper::findShareKeys($oldShareKeyPath, $view); foreach ($matches as $src) { $dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src)); $view->rename($src, $dst); } } else { // handle share-keys folders $view->rename($oldShareKeyPath, $newShareKeyPath); } // Rename keyfile so it isn't orphaned if ($view->file_exists($oldKeyfilePath)) { $view->rename($oldKeyfilePath, $newKeyfilePath); } // update share keys $sharingEnabled = \OCP\Share::isEnabled(); // get users $usersSharing = $util->getSharingUsersArray($sharingEnabled, $pathNew); // update sharing-keys $util->setSharedFileKeyfiles($session, $usersSharing, $pathNew); \OC_FileProxy::$enabled = $proxyStatus; }
\OCP\JSON::checkAppEnabled('files_encryption'); \OCP\JSON::callCheck(); $l = \OC::$server->getL10N('core'); $return = false; $oldPassword = $_POST['oldPassword']; $newPassword = $_POST['newPassword']; $view = new \OC\Files\View('/'); $session = new \OCA\Encryption\Session($view); $user = \OCP\User::getUser(); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key'; $encryptedKey = $view->file_get_contents($keyPath); $decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword); if ($decryptedKey) { $cipher = \OCA\Encryption\Helper::getCipher(); $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword, $cipher); if ($encryptedKey) { \OCA\Encryption\Keymanager::setPrivateKey($encryptedKey, $user); $session->setPrivateKey($decryptedKey); $return = true; } } \OC_FileProxy::$enabled = $proxyStatus; // success or failure if ($return) { $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.')))); }
/** * Move encryption keys to trash so that they can be restored later * * @param $file_path path to original file * @param $filename of deleted file * @param $timestamp when the file was deleted * * @return size of encryption keys */ private static function retainEncryptionKeys($file_path, $filename, $timestamp) { $size = 0; if (\OCP\App::isEnabled('files_encryption')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); list($owner, $ownerPath) = self::getUidAndFilename($file_path); // file has been deleted in between if (empty($ownerPath)) { return 0; } $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user); // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($util->isSystemWideMountPoint($ownerPath)) { $baseDir = '/files_encryption/'; } else { $baseDir = $owner . '/files_encryption/'; } $keyfile = \OC\Files\Filesystem::normalizePath($baseDir . '/keyfiles/' . $ownerPath); if ($rootView->is_dir($keyfile) || $rootView->file_exists($keyfile . '.key')) { // move keyfiles if ($rootView->is_dir($keyfile)) { $size += self::calculateSize(new \OC\Files\View($keyfile)); if ($owner !== $user) { self::copy_recursive($keyfile, $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.d' . $timestamp, $rootView); } $rootView->rename($keyfile, $user . '/files_trashbin/keyfiles/' . $filename . '.d' . $timestamp); } else { $size += $rootView->filesize($keyfile . '.key'); if ($owner !== $user) { $rootView->copy($keyfile . '.key', $owner . '/files_trashbin/keyfiles/' . basename($ownerPath) . '.key.d' . $timestamp); } $rootView->rename($keyfile . '.key', $user . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp); } } // retain share keys $sharekeys = \OC\Files\Filesystem::normalizePath($baseDir . '/share-keys/' . $ownerPath); if ($rootView->is_dir($sharekeys)) { $size += self::calculateSize(new \OC\Files\View($sharekeys)); if ($owner !== $user) { self::copy_recursive($sharekeys, $owner . '/files_trashbin/share-keys/' . basename($ownerPath) . '.d' . $timestamp, $rootView); } $rootView->rename($sharekeys, $user . '/files_trashbin/share-keys/' . $filename . '.d' . $timestamp); } else { // handle share-keys $matches = \OCA\Encryption\Helper::findShareKeys($ownerPath, $sharekeys, $rootView); foreach ($matches as $src) { // get source file parts $pathinfo = pathinfo($src); // we only want to keep the users key so we can access the private key $userShareKey = $filename . '.' . $user . '.shareKey'; // if we found the share-key for the owner, we need to move it to files_trashbin if ($pathinfo['basename'] == $userShareKey) { // calculate size $size += $rootView->filesize($sharekeys . '.' . $user . '.shareKey'); // move file $rootView->rename($sharekeys . '.' . $user . '.shareKey', $user . '/files_trashbin/share-keys/' . $userShareKey . '.d' . $timestamp); } elseif ($owner !== $user) { $ownerShareKey = basename($ownerPath) . '.' . $owner . '.shareKey'; if ($pathinfo['basename'] == $ownerShareKey) { $rootView->rename($sharekeys . '.' . $owner . '.shareKey', $owner . '/files_trashbin/share-keys/' . $ownerShareKey . '.d' . $timestamp); } } else { // don't keep other share-keys unlink($src); } } } // enable proxy \OC_FileProxy::$enabled = $proxyStatus; } return $size; }
/** * @param string $path * @param int $size * @return int|bool */ public function postFileSize($path, $size, $fileInfo = null) { $view = new \OC\Files\View('/'); $userId = Helper::getUser($path); $util = new Util($view, $userId); // if encryption is no longer enabled or if the files aren't migrated yet // we return the default file size if (!\OCP\App::isEnabled('files_encryption') || $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { return $size; } // if path is a folder do nothing if ($view->is_dir($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; if (isset($fileInfo['unencrypted_size']) && $fileInfo['unencrypted_size'] > 0) { return $fileInfo['unencrypted_size']; } return $size; } // get relative path $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); // if path is empty we cannot resolve anything if (empty($relativePath)) { return $size; } // get file info from database/cache if not .part file if (empty($fileInfo) && !Helper::isPartialFilePath($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; } // if file is encrypted return real file size if (isset($fileInfo['encrypted']) && $fileInfo['encrypted'] === true) { // try to fix unencrypted file size if it doesn't look plausible if ((int) $fileInfo['size'] > 0 && (int) $fileInfo['unencrypted_size'] === 0) { $fixSize = $util->getFileSize($path); $fileInfo['unencrypted_size'] = $fixSize; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, array('unencrypted_size' => $fixSize)); } } $size = $fileInfo['unencrypted_size']; } else { $fileInfoUpdates = array(); $fixSize = $util->getFileSize($path); if ($fixSize > 0) { $size = $fixSize; $fileInfoUpdates['encrypted'] = true; $fileInfoUpdates['unencrypted_size'] = $size; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, $fileInfoUpdates); } } } return $size; }
/** * generate header for encrypted file */ public static function generateHeader() { $cipher = Helper::getCipher(); $header = self::HEADERSTART . ':cipher:' . $cipher . ':' . self::HEADEREND; return $header; }
/** * enable recovery * * @param string $recoveryKeyId * @param string $recoveryPassword * @internal param \OCA\Encryption\Util $util * @internal param string $password * @return bool */ public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) { $view = new \OC\Files\View('/'); $appConfig = \OC::$server->getAppConfig(); if ($recoveryKeyId === null) { $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); $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']); $cipher = \OCA\Encryption\Helper::getCipher(); $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword, $cipher); if ($encryptedKey) { Keymanager::setPrivateSystemKey($encryptedKey, $recoveryKeyId . '.private.key'); // Set recoveryAdmin as enabled $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1); $return = true; } \OC_FileProxy::$enabled = true; } else { // get recovery key and check the password $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1); } } return $return; }
/** * @return bool */ public function stream_close() { $this->flush(); // if there is no valid private key return false if ($this->privateKey === false) { // cleanup if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && !$this->isLocalTmpFile) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) { $this->rootView->unlink($this->rawPath); } // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; } // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session); } if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && $this->isLocalTmpFile === false && $this->size > 0 && $this->unencryptedSize > 0) { // only write keyfiles if it was a new file if ($this->newFile === true) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Fetch user's public key $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->keyId); // Check if OC sharing api is enabled $sharingEnabled = \OCP\Share::isEnabled(); $util = new Util($this->rootView, $this->userId); // Get all users sharing the file includes current user $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath); $checkedUserIds = $util->filterShareReadyUsers($uniqueUserIds); // Fetch public keys for all sharing users $publicKeys = Keymanager::getPublicKeys($this->rootView, $checkedUserIds['ready']); // Encrypt enc key for all sharing users $this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys); // Save the new encrypted file key Keymanager::setFileKey($this->rootView, $util, $this->relPath, $this->encKeyfiles['data']); // Save the sharekeys Keymanager::setShareKeys($this->rootView, $util, $this->relPath, $this->encKeyfiles['keys']); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; } // we need to update the file info for the real file, not for the // part file. $path = Helper::stripPartialFileExtension($this->rawPath); $fileInfo = array('encrypted' => true, 'size' => $this->size, 'unencrypted_size' => $this->unencryptedSize); // set fileinfo $this->rootView->putFileInfo($path, $fileInfo); } $result = fclose($this->handle); if ($result === false) { \OCP\Util::writeLog('Encryption library', 'Could not close stream, file could be corrupted', \OCP\Util::FATAL); } return $result; }
/** * @param $path */ public function handleFile($path) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($view); $userId = Helper::getUser($path); $util = new Util($view, $userId); // split the path parts $pathParts = explode('/', $path); // get relative path $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); // only if file is on 'files' folder fix file size and sharing if (isset($pathParts[2]) && $pathParts[2] === 'files' && $util->fixFileSize($path)) { // get sharing app state $sharingEnabled = \OCP\Share::isEnabled(); // get users $usersSharing = $util->getSharingUsersArray($sharingEnabled, $relativePath); // update sharing-keys $util->setSharedFileKeyfiles($session, $usersSharing, $relativePath); } \OC_FileProxy::$enabled = $proxyStatus; }
/** * @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')); }
/** * after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing * * @param array $params array with oldpath and newpath */ public static function postRenameOrCopy($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/'); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); if (isset(self::$renamedFiles[$params['oldpath']]['uid']) && isset(self::$renamedFiles[$params['oldpath']]['path'])) { $ownerOld = self::$renamedFiles[$params['oldpath']]['uid']; $pathOld = self::$renamedFiles[$params['oldpath']]['path']; $type = self::$renamedFiles[$params['oldpath']]['type']; $operation = self::$renamedFiles[$params['oldpath']]['operation']; unset(self::$renamedFiles[$params['oldpath']]); } else { \OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG); \OC_FileProxy::$enabled = $proxyStatus; return false; } list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']); // Format paths to be relative to user files dir if ($util->isSystemWideMountPoint($pathOld)) { $oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld; } else { $oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld; } if ($util->isSystemWideMountPoint($pathNew)) { $newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = 'files_encryption/share-keys/' . $pathNew; } else { $newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew; } // add key ext if this is not an folder if ($type === 'file') { $oldKeyfilePath .= '.key'; $newKeyfilePath .= '.key'; // create destination folder if not exists $localKeyPath = $view->getLocalFile($oldShareKeyPath); $newLocalKeyPath = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $localKeyPath)); if (!file_exists(dirname($newLocalKeyPath))) { mkdir(dirname($newLocalKeyPath), 0750, true); } // handle share-keys $matches = Helper::findShareKeys($pathOld, $oldShareKeyPath, $view); if (count($matches) === 0) { \OC_Log::write('Encryption library', 'No share keys found for "' . $pathOld . '"', \OC_Log::WARN); } foreach ($matches as $src) { $dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src)); $view->{$operation}($src, $dst); } } else { // handle share-keys folders // create destination folder if not exists if (!$view->file_exists(dirname($newShareKeyPath))) { mkdir($view->getLocalFile($newShareKeyPath), 0750, true); } $view->{$operation}($oldShareKeyPath, $newShareKeyPath); } // Rename keyfile so it isn't orphaned if ($view->file_exists($oldKeyfilePath)) { // create destination folder if not exists if (!$view->file_exists(dirname($newKeyfilePath))) { mkdir(dirname($view->getLocalFile($newKeyfilePath)), 0750, true); } $view->{$operation}($oldKeyfilePath, $newKeyfilePath); } // build the path to the file $newPath = '/' . $ownerNew . '/files' . $pathNew; // update sharing-keys self::updateKeyfiles($params['newpath'], $type); \OC_FileProxy::$enabled = $proxyStatus; }
public static function setupHooks() { // Filesystem related hooks \OCA\Encryption\Helper::registerFilesystemHooks(); // clear and register hooks \OC_FileProxy::clearProxies(); \OC_FileProxy::register(new OCA\Encryption\Proxy()); }