diff options
Diffstat (limited to 'lib/private/encryption')
16 files changed, 0 insertions, 2017 deletions
diff --git a/lib/private/encryption/decryptall.php b/lib/private/encryption/decryptall.php deleted file mode 100644 index 7a965a5f227..00000000000 --- a/lib/private/encryption/decryptall.php +++ /dev/null @@ -1,276 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * - * @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/> - * - */ - - -namespace OC\Encryption; - -use OC\Encryption\Exceptions\DecryptionFailedException; -use OC\Files\View; -use \OCP\Encryption\IEncryptionModule; -use OCP\IUserManager; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class DecryptAll { - - /** @var OutputInterface */ - protected $output; - - /** @var InputInterface */ - protected $input; - - /** @var Manager */ - protected $encryptionManager; - - /** @var IUserManager */ - protected $userManager; - - /** @var View */ - protected $rootView; - - /** @var array files which couldn't be decrypted */ - protected $failed; - - /** - * @param Manager $encryptionManager - * @param IUserManager $userManager - * @param View $rootView - */ - public function __construct( - Manager $encryptionManager, - IUserManager $userManager, - View $rootView - ) { - $this->encryptionManager = $encryptionManager; - $this->userManager = $userManager; - $this->rootView = $rootView; - $this->failed = []; - } - - /** - * start to decrypt all files - * - * @param InputInterface $input - * @param OutputInterface $output - * @param string $user which users data folder should be decrypted, default = all users - * @return bool - * @throws \Exception - */ - public function decryptAll(InputInterface $input, OutputInterface $output, $user = '') { - - $this->input = $input; - $this->output = $output; - - if (!empty($user) && $this->userManager->userExists($user) === false) { - $this->output->writeln('User "' . $user . '" does not exist. Please check the username and try again'); - return false; - } - - $this->output->writeln('prepare encryption modules...'); - if ($this->prepareEncryptionModules($user) === false) { - return false; - } - $this->output->writeln(' done.'); - - $this->decryptAllUsersFiles($user); - - if (empty($this->failed)) { - $this->output->writeln('all files could be decrypted successfully!'); - } else { - $this->output->writeln('Files for following users couldn\'t be decrypted, '); - $this->output->writeln('maybe the user is not set up in a way that supports this operation: '); - foreach ($this->failed as $uid => $paths) { - $this->output->writeln(' ' . $uid); - } - $this->output->writeln(''); - } - - return true; - } - - /** - * prepare encryption modules to perform the decrypt all function - * - * @param $user - * @return bool - */ - protected function prepareEncryptionModules($user) { - // prepare all encryption modules for decrypt all - $encryptionModules = $this->encryptionManager->getEncryptionModules(); - foreach ($encryptionModules as $moduleDesc) { - /** @var IEncryptionModule $module */ - $module = call_user_func($moduleDesc['callback']); - $this->output->writeln(''); - $this->output->writeln('Prepare "' . $module->getDisplayName() . '"'); - $this->output->writeln(''); - if ($module->prepareDecryptAll($this->input, $this->output, $user) === false) { - $this->output->writeln('Module "' . $moduleDesc['displayName'] . '" does not support the functionality to decrypt all files again or the initialization of the module failed!'); - return false; - } - } - - return true; - } - - /** - * iterate over all user and encrypt their files - * @param string $user which users files should be decrypted, default = all users - */ - protected function decryptAllUsersFiles($user = '') { - - $this->output->writeln("\n"); - - $userList = []; - if (empty($user)) { - - $fetchUsersProgress = new ProgressBar($this->output); - $fetchUsersProgress->setFormat(" %message% \n [%bar%]"); - $fetchUsersProgress->start(); - $fetchUsersProgress->setMessage("Fetch list of users..."); - $fetchUsersProgress->advance(); - - foreach ($this->userManager->getBackends() as $backend) { - $limit = 500; - $offset = 0; - do { - $users = $backend->getUsers('', $limit, $offset); - foreach ($users as $user) { - $userList[] = $user; - } - $offset += $limit; - $fetchUsersProgress->advance(); - } while (count($users) >= $limit); - $fetchUsersProgress->setMessage("Fetch list of users... finished"); - $fetchUsersProgress->finish(); - } - } else { - $userList[] = $user; - } - - $this->output->writeln("\n\n"); - - $progress = new ProgressBar($this->output); - $progress->setFormat(" %message% \n [%bar%]"); - $progress->start(); - $progress->setMessage("starting to decrypt files..."); - $progress->advance(); - - $numberOfUsers = count($userList); - $userNo = 1; - foreach ($userList as $uid) { - $userCount = "$uid ($userNo of $numberOfUsers)"; - $this->decryptUsersFiles($uid, $progress, $userCount); - $userNo++; - } - - $progress->setMessage("starting to decrypt files... finished"); - $progress->finish(); - - $this->output->writeln("\n\n"); - - } - - /** - * encrypt files from the given user - * - * @param string $uid - * @param ProgressBar $progress - * @param string $userCount - */ - protected function decryptUsersFiles($uid, ProgressBar $progress, $userCount) { - - $this->setupUserFS($uid); - $directories = array(); - $directories[] = '/' . $uid . '/files'; - - while($root = array_pop($directories)) { - $content = $this->rootView->getDirectoryContent($root); - foreach ($content as $file) { - $path = $root . '/' . $file['name']; - if ($this->rootView->is_dir($path)) { - $directories[] = $path; - continue; - } else { - try { - $progress->setMessage("decrypt files for user $userCount: $path"); - $progress->advance(); - if ($this->decryptFile($path) === false) { - $progress->setMessage("decrypt files for user $userCount: $path (already decrypted)"); - $progress->advance(); - } - } catch (\Exception $e) { - if (isset($this->failed[$uid])) { - $this->failed[$uid][] = $path; - } else { - $this->failed[$uid] = [$path]; - } - } - } - } - } - } - - /** - * encrypt file - * - * @param string $path - * @return bool - */ - protected function decryptFile($path) { - - $source = $path; - $target = $path . '.decrypted.' . $this->getTimestamp(); - - try { - $this->rootView->copy($source, $target); - $this->rootView->rename($target, $source); - } catch (DecryptionFailedException $e) { - if ($this->rootView->file_exists($target)) { - $this->rootView->unlink($target); - } - return false; - } - - return true; - } - - /** - * get current timestamp - * - * @return int - */ - protected function getTimestamp() { - return time(); - } - - - /** - * setup user file system - * - * @param string $uid - */ - protected function setupUserFS($uid) { - \OC_Util::tearDownFS(); - \OC_Util::setupFS($uid); - } - -} diff --git a/lib/private/encryption/encryptionwrapper.php b/lib/private/encryption/encryptionwrapper.php deleted file mode 100644 index 11beb0cd6b1..00000000000 --- a/lib/private/encryption/encryptionwrapper.php +++ /dev/null @@ -1,124 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * - * @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/> - * - */ - - -namespace OC\Encryption; - - -use OC\Memcache\ArrayCache; -use OC\Files\Filesystem; -use OC\Files\Storage\Wrapper\Encryption; -use OCP\Files\Mount\IMountPoint; -use OC\Files\View; -use OCP\Files\Storage; -use OCP\ILogger; - -/** - * Class EncryptionWrapper - * - * applies the encryption storage wrapper - * - * @package OC\Encryption - */ -class EncryptionWrapper { - - /** @var ArrayCache */ - private $arrayCache; - - /** @var Manager */ - private $manager; - - /** @var ILogger */ - private $logger; - - /** - * EncryptionWrapper constructor. - * - * @param ArrayCache $arrayCache - * @param Manager $manager - * @param ILogger $logger - */ - public function __construct(ArrayCache $arrayCache, - Manager $manager, - ILogger $logger - ) { - $this->arrayCache = $arrayCache; - $this->manager = $manager; - $this->logger = $logger; - } - - /** - * Wraps the given storage when it is not a shared storage - * - * @param string $mountPoint - * @param Storage $storage - * @param IMountPoint $mount - * @return Encryption|Storage - */ - public function wrapStorage($mountPoint, Storage $storage, IMountPoint $mount) { - $parameters = [ - 'storage' => $storage, - 'mountPoint' => $mountPoint, - 'mount' => $mount - ]; - - if (!$storage->instanceOfStorage('OC\Files\Storage\Shared') - && !$storage->instanceOfStorage('OCA\Files_Sharing\External\Storage') - && !$storage->instanceOfStorage('OC\Files\Storage\OwnCloud')) { - - $user = \OC::$server->getUserSession()->getUser(); - $mountManager = Filesystem::getMountManager(); - $uid = $user ? $user->getUID() : null; - $fileHelper = \OC::$server->getEncryptionFilesHelper(); - $keyStorage = \OC::$server->getEncryptionKeyStorage(); - - $util = new Util( - new View(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager(), - \OC::$server->getConfig() - ); - $update = new Update( - new View(), - $util, - Filesystem::getMountManager(), - $this->manager, - $fileHelper, - $uid - ); - return new Encryption( - $parameters, - $this->manager, - $util, - $this->logger, - $fileHelper, - $uid, - $keyStorage, - $update, - $mountManager, - $this->arrayCache - ); - } else { - return $storage; - } - } - -} diff --git a/lib/private/encryption/exceptions/decryptionfailedexception.php b/lib/private/encryption/exceptions/decryptionfailedexception.php deleted file mode 100644 index a0cbbc5cce0..00000000000 --- a/lib/private/encryption/exceptions/decryptionfailedexception.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class DecryptionFailedException extends GenericEncryptionException { - -} diff --git a/lib/private/encryption/exceptions/emptyencryptiondataexception.php b/lib/private/encryption/exceptions/emptyencryptiondataexception.php deleted file mode 100644 index 2c90c2db7df..00000000000 --- a/lib/private/encryption/exceptions/emptyencryptiondataexception.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class EmptyEncryptionDataException extends GenericEncryptionException{ - -} diff --git a/lib/private/encryption/exceptions/encryptionfailedexception.php b/lib/private/encryption/exceptions/encryptionfailedexception.php deleted file mode 100644 index 98e92eb199c..00000000000 --- a/lib/private/encryption/exceptions/encryptionfailedexception.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class EncryptionFailedException extends GenericEncryptionException{ - -} diff --git a/lib/private/encryption/exceptions/encryptionheaderkeyexistsexception.php b/lib/private/encryption/exceptions/encryptionheaderkeyexistsexception.php deleted file mode 100644 index ab1a166018c..00000000000 --- a/lib/private/encryption/exceptions/encryptionheaderkeyexistsexception.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class EncryptionHeaderKeyExistsException extends GenericEncryptionException { - - /** - * @param string $key - */ - public function __construct($key) { - parent::__construct('header key "'. $key . '" already reserved by ownCloud'); - } -} diff --git a/lib/private/encryption/exceptions/encryptionheadertolargeexception.php b/lib/private/encryption/exceptions/encryptionheadertolargeexception.php deleted file mode 100644 index 7b706e621de..00000000000 --- a/lib/private/encryption/exceptions/encryptionheadertolargeexception.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class EncryptionHeaderToLargeException extends GenericEncryptionException { - - public function __construct() { - parent::__construct('max header size exceeded'); - } - -} diff --git a/lib/private/encryption/exceptions/modulealreadyexistsexception.php b/lib/private/encryption/exceptions/modulealreadyexistsexception.php deleted file mode 100644 index fcd08679acc..00000000000 --- a/lib/private/encryption/exceptions/modulealreadyexistsexception.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class ModuleAlreadyExistsException extends GenericEncryptionException { - - /** - * @param string $id - * @param string $name - */ - public function __construct($id, $name) { - parent::__construct('Id "' . $id . '" already used by encryption module "' . $name . '"'); - } - -} diff --git a/lib/private/encryption/exceptions/moduledoesnotexistsexception.php b/lib/private/encryption/exceptions/moduledoesnotexistsexception.php deleted file mode 100644 index 282c9ec080b..00000000000 --- a/lib/private/encryption/exceptions/moduledoesnotexistsexception.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class ModuleDoesNotExistsException extends GenericEncryptionException { - -} diff --git a/lib/private/encryption/exceptions/unknowncipherexception.php b/lib/private/encryption/exceptions/unknowncipherexception.php deleted file mode 100644 index beb4cb7f2e5..00000000000 --- a/lib/private/encryption/exceptions/unknowncipherexception.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - - -namespace OC\Encryption\Exceptions; - -use OCP\Encryption\Exceptions\GenericEncryptionException; - -class UnknownCipherException extends GenericEncryptionException { - -} diff --git a/lib/private/encryption/file.php b/lib/private/encryption/file.php deleted file mode 100644 index ec55c2cea00..00000000000 --- a/lib/private/encryption/file.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption; - -class File implements \OCP\Encryption\IFile { - - /** @var Util */ - protected $util; - - /** - * cache results of already checked folders - * - * @var array - */ - protected $cache; - - public function __construct(Util $util) { - $this->util = $util; - } - - - /** - * get list of users with access to the file - * - * @param string $path to the file - * @return array ['users' => $uniqueUserIds, 'public' => $public] - */ - public function getAccessList($path) { - - // Make sure that a share key is generated for the owner too - list($owner, $ownerPath) = $this->util->getUidAndFilename($path); - - // always add owner to the list of users with access to the file - $userIds = array($owner); - - if (!$this->util->isFile($owner . '/' . $ownerPath)) { - return array('users' => $userIds, 'public' => false); - } - - $ownerPath = substr($ownerPath, strlen('/files')); - $ownerPath = $this->util->stripPartialFileExtension($ownerPath); - - - // first get the shares for the parent and cache the result so that we don't - // need to check all parents for every file - $parent = dirname($ownerPath); - if (isset($this->cache[$parent])) { - $resultForParents = $this->cache[$parent]; - } else { - $resultForParents = \OCP\Share::getUsersSharingFile($parent, $owner); - $this->cache[$parent] = $resultForParents; - } - $userIds = \array_merge($userIds, $resultForParents['users']); - $public = $resultForParents['public'] || $resultForParents['remote']; - - - // Find out who, if anyone, is sharing the file - $resultForFile = \OCP\Share::getUsersSharingFile($ownerPath, $owner, false, false, false); - $userIds = \array_merge($userIds, $resultForFile['users']); - $public = $resultForFile['public'] || $resultForFile['remote'] || $public; - - // 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']))) { - $mountedFor = $this->util->getUserWithAccessToMountPoint($mount['applicable']['users'], $mount['applicable']['groups']); - $userIds = array_merge($userIds, $mountedFor); - } - } - } - - // Remove duplicate UIDs - $uniqueUserIds = array_unique($userIds); - - return array('users' => $uniqueUserIds, 'public' => $public); - } - -} diff --git a/lib/private/encryption/hookmanager.php b/lib/private/encryption/hookmanager.php deleted file mode 100644 index 0bc42ec8159..00000000000 --- a/lib/private/encryption/hookmanager.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption; - -use OC\Files\Filesystem; -use OC\Files\View; - -class HookManager { - /** - * @var Update - */ - private static $updater; - - public static function postShared($params) { - self::getUpdate()->postShared($params); - } - public static function postUnshared($params) { - self::getUpdate()->postUnshared($params); - } - - public static function postRename($params) { - self::getUpdate()->postRename($params); - } - - public static function postRestore($params) { - self::getUpdate()->postRestore($params); - } - - /** - * @return Update - */ - private static function getUpdate() { - if (is_null(self::$updater)) { - $user = \OC::$server->getUserSession()->getUser(); - $uid = ''; - if ($user) { - $uid = $user->getUID(); - } - self::$updater = new Update( - new View(), - new Util( - new View(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager(), - \OC::$server->getConfig()), - Filesystem::getMountManager(), - \OC::$server->getEncryptionManager(), - \OC::$server->getEncryptionFilesHelper(), - $uid - ); - } - - return self::$updater; - } -} diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php deleted file mode 100644 index 47360f45aa5..00000000000 --- a/lib/private/encryption/keys/storage.php +++ /dev/null @@ -1,326 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption\Keys; - -use OC\Encryption\Util; -use OC\Files\Filesystem; -use OC\Files\View; -use OCP\Encryption\Keys\IStorage; - -class Storage implements IStorage { - - // hidden file which indicate that the folder is a valid key storage - const KEY_STORAGE_MARKER = '.oc_key_storage'; - - /** @var View */ - private $view; - - /** @var Util */ - private $util; - - // base dir where all the file related keys are stored - /** @var string */ - private $keys_base_dir; - - // root of the key storage default is empty which means that we use the data folder - /** @var string */ - private $root_dir; - - /** @var string */ - private $encryption_base_dir; - - /** @var array */ - private $keyCache = []; - - /** - * @param View $view - * @param Util $util - */ - public function __construct(View $view, Util $util) { - $this->view = $view; - $this->util = $util; - - $this->encryption_base_dir = '/files_encryption'; - $this->keys_base_dir = $this->encryption_base_dir .'/keys'; - $this->root_dir = $this->util->getKeyStorageRoot(); - } - - /** - * @inheritdoc - */ - public function getUserKey($uid, $keyId, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, $uid); - return $this->getKey($path); - } - - /** - * @inheritdoc - */ - public function getFileKey($path, $keyId, $encryptionModuleId) { - $realFile = $this->util->stripPartialFileExtension($path); - $keyDir = $this->getFileKeyDir($encryptionModuleId, $realFile); - $key = $this->getKey($keyDir . $keyId); - - if ($key === '' && $realFile !== $path) { - // Check if the part file has keys and use them, if no normal keys - // exist. This is required to fix copyBetweenStorage() when we - // rename a .part file over storage borders. - $keyDir = $this->getFileKeyDir($encryptionModuleId, $path); - $key = $this->getKey($keyDir . $keyId); - } - - return $key; - } - - /** - * @inheritdoc - */ - public function getSystemUserKey($keyId, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, null); - return $this->getKey($path); - } - - /** - * @inheritdoc - */ - public function setUserKey($uid, $keyId, $key, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, $uid); - return $this->setKey($path, $key); - } - - /** - * @inheritdoc - */ - public function setFileKey($path, $keyId, $key, $encryptionModuleId) { - $keyDir = $this->getFileKeyDir($encryptionModuleId, $path); - return $this->setKey($keyDir . $keyId, $key); - } - - /** - * @inheritdoc - */ - public function setSystemUserKey($keyId, $key, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, null); - return $this->setKey($path, $key); - } - - /** - * @inheritdoc - */ - public function deleteUserKey($uid, $keyId, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, $uid); - return !$this->view->file_exists($path) || $this->view->unlink($path); - } - - /** - * @inheritdoc - */ - public function deleteFileKey($path, $keyId, $encryptionModuleId) { - $keyDir = $this->getFileKeyDir($encryptionModuleId, $path); - return !$this->view->file_exists($keyDir . $keyId) || $this->view->unlink($keyDir . $keyId); - } - - /** - * @inheritdoc - */ - public function deleteAllFileKeys($path) { - $keyDir = $this->getFileKeyDir('', $path); - return !$this->view->file_exists($keyDir) || $this->view->deleteAll($keyDir); - } - - /** - * @inheritdoc - */ - public function deleteSystemUserKey($keyId, $encryptionModuleId) { - $path = $this->constructUserKeyPath($encryptionModuleId, $keyId, null); - return !$this->view->file_exists($path) || $this->view->unlink($path); - } - - /** - * construct path to users key - * - * @param string $encryptionModuleId - * @param string $keyId - * @param string $uid - * @return string - */ - protected function constructUserKeyPath($encryptionModuleId, $keyId, $uid) { - - if ($uid === null) { - $path = $this->root_dir . '/' . $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $keyId; - } else { - $path = $this->root_dir . '/' . $uid . $this->encryption_base_dir . '/' - . $encryptionModuleId . '/' . $uid . '.' . $keyId; - } - - return \OC\Files\Filesystem::normalizePath($path); - } - - /** - * read key from hard disk - * - * @param string $path to key - * @return string - */ - private function getKey($path) { - - $key = ''; - - if ($this->view->file_exists($path)) { - if (isset($this->keyCache[$path])) { - $key = $this->keyCache[$path]; - } else { - $key = $this->view->file_get_contents($path); - $this->keyCache[$path] = $key; - } - } - - return $key; - } - - /** - * write key to disk - * - * - * @param string $path path to key directory - * @param string $key key - * @return bool - */ - private function setKey($path, $key) { - $this->keySetPreparation(dirname($path)); - - $result = $this->view->file_put_contents($path, $key); - - if (is_int($result) && $result > 0) { - $this->keyCache[$path] = $key; - return true; - } - - return false; - } - - /** - * get path to key folder for a given file - * - * @param string $encryptionModuleId - * @param string $path path to the file, relative to data/ - * @return string - */ - private function getFileKeyDir($encryptionModuleId, $path) { - - list($owner, $filename) = $this->util->getUidAndFilename($path); - - // in case of system wide mount points the keys are stored directly in the data directory - if ($this->util->isSystemWideMountPoint($filename, $owner)) { - $keyPath = $this->root_dir . '/' . $this->keys_base_dir . $filename . '/'; - } else { - $keyPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $filename . '/'; - } - - return Filesystem::normalizePath($keyPath . $encryptionModuleId . '/', false); - } - - /** - * move keys if a file was renamed - * - * @param string $source - * @param string $target - * @return boolean - */ - public function renameKeys($source, $target) { - - $sourcePath = $this->getPathToKeys($source); - $targetPath = $this->getPathToKeys($target); - - if ($this->view->file_exists($sourcePath)) { - $this->keySetPreparation(dirname($targetPath)); - $this->view->rename($sourcePath, $targetPath); - - return true; - } - - return false; - } - - - /** - * copy keys if a file was renamed - * - * @param string $source - * @param string $target - * @return boolean - */ - public function copyKeys($source, $target) { - - $sourcePath = $this->getPathToKeys($source); - $targetPath = $this->getPathToKeys($target); - - if ($this->view->file_exists($sourcePath)) { - $this->keySetPreparation(dirname($targetPath)); - $this->view->copy($sourcePath, $targetPath); - return true; - } - - return false; - } - - /** - * get system wide path and detect mount points - * - * @param string $path - * @return string - */ - protected function getPathToKeys($path) { - list($owner, $relativePath) = $this->util->getUidAndFilename($path); - $systemWideMountPoint = $this->util->isSystemWideMountPoint($relativePath, $owner); - - if ($systemWideMountPoint) { - $systemPath = $this->root_dir . '/' . $this->keys_base_dir . $relativePath . '/'; - } else { - $systemPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $relativePath . '/'; - } - - return Filesystem::normalizePath($systemPath, false); - } - - /** - * Make preparations to filesystem for saving a key file - * - * @param string $path relative to the views root - */ - protected function keySetPreparation($path) { - // If the file resides within a subdirectory, create it - if (!$this->view->file_exists($path)) { - $sub_dirs = explode('/', ltrim($path, '/')); - $dir = ''; - foreach ($sub_dirs as $sub_dir) { - $dir .= '/' . $sub_dir; - if (!$this->view->is_dir($dir)) { - $this->view->mkdir($dir); - } - } - } - } - -} diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php deleted file mode 100644 index 8714d161807..00000000000 --- a/lib/private/encryption/manager.php +++ /dev/null @@ -1,284 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Jan-Christoph Borchardt <hey@jancborchardt.net> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption; - -use OC\Encryption\Keys\Storage; -use OC\Files\Filesystem; -use OC\Files\View; -use OC\Memcache\ArrayCache; -use OC\ServiceUnavailableException; -use OCP\Encryption\IEncryptionModule; -use OCP\Encryption\IManager; -use OCP\IConfig; -use OCP\IL10N; -use OCP\ILogger; - -class Manager implements IManager { - - /** @var array */ - protected $encryptionModules; - - /** @var IConfig */ - protected $config; - - /** @var ILogger */ - protected $logger; - - /** @var Il10n */ - protected $l; - - /** @var View */ - protected $rootView; - - /** @var Util */ - protected $util; - - /** @var ArrayCache */ - protected $arrayCache; - - /** - * @param IConfig $config - * @param ILogger $logger - * @param IL10N $l10n - * @param View $rootView - * @param Util $util - * @param ArrayCache $arrayCache - */ - public function __construct(IConfig $config, ILogger $logger, IL10N $l10n, View $rootView, Util $util, ArrayCache $arrayCache) { - $this->encryptionModules = array(); - $this->config = $config; - $this->logger = $logger; - $this->l = $l10n; - $this->rootView = $rootView; - $this->util = $util; - $this->arrayCache = $arrayCache; - } - - /** - * Check if encryption is enabled - * - * @return bool true if enabled, false if not - */ - public function isEnabled() { - - $installed = $this->config->getSystemValue('installed', false); - if (!$installed) { - return false; - } - - $enabled = $this->config->getAppValue('core', 'encryption_enabled', 'no'); - return $enabled === 'yes'; - } - - /** - * check if new encryption is ready - * - * @return bool - * @throws ServiceUnavailableException - */ - public function isReady() { - // check if we are still in transit between the old and the new encryption - $oldEncryption = $this->config->getAppValue('files_encryption', 'installed_version'); - if (!empty($oldEncryption)) { - $warning = 'Installation is in transit between the old Encryption (ownCloud <= 8.0) - and the new encryption. Please enable the "Default encryption module" - and run \'occ encryption:migrate\''; - $this->logger->warning($warning); - return false; - } - - if ($this->isKeyStorageReady() === false) { - throw new ServiceUnavailableException('Key Storage is not ready'); - } - - return true; - } - - /** - * @param string $user - */ - public function isReadyForUser($user) { - if (!$this->isReady()) { - return false; - } - - foreach ($this->getEncryptionModules() as $module) { - /** @var IEncryptionModule $m */ - $m = call_user_func($module['callback']); - if (!$m->isReadyForUser($user)) { - return false; - } - } - - return true; - } - - /** - * Registers an callback function which must return an encryption module instance - * - * @param string $id - * @param string $displayName - * @param callable $callback - * @throws Exceptions\ModuleAlreadyExistsException - */ - public function registerEncryptionModule($id, $displayName, callable $callback) { - - if (isset($this->encryptionModules[$id])) { - throw new Exceptions\ModuleAlreadyExistsException($id, $displayName); - } - - $this->encryptionModules[$id] = [ - 'id' => $id, - 'displayName' => $displayName, - 'callback' => $callback, - ]; - - $defaultEncryptionModuleId = $this->getDefaultEncryptionModuleId(); - - if (empty($defaultEncryptionModuleId)) { - $this->setDefaultEncryptionModule($id); - } - } - - /** - * Unregisters an encryption module - * - * @param string $moduleId - */ - public function unregisterEncryptionModule($moduleId) { - unset($this->encryptionModules[$moduleId]); - } - - /** - * get a list of all encryption modules - * - * @return array [id => ['id' => $id, 'displayName' => $displayName, 'callback' => callback]] - */ - public function getEncryptionModules() { - return $this->encryptionModules; - } - - /** - * get a specific encryption module - * - * @param string $moduleId - * @return IEncryptionModule - * @throws Exceptions\ModuleDoesNotExistsException - */ - public function getEncryptionModule($moduleId = '') { - if (!empty($moduleId)) { - if (isset($this->encryptionModules[$moduleId])) { - return call_user_func($this->encryptionModules[$moduleId]['callback']); - } else { - $message = "Module with id: $moduleId does not exist."; - $hint = $this->l->t('Module with id: %s does not exist. Please enable it in your apps settings or contact your administrator.', [$moduleId]); - throw new Exceptions\ModuleDoesNotExistsException($message, $hint); - } - } else { - return $this->getDefaultEncryptionModule(); - } - } - - /** - * get default encryption module - * - * @return \OCP\Encryption\IEncryptionModule - * @throws Exceptions\ModuleDoesNotExistsException - */ - protected function getDefaultEncryptionModule() { - $defaultModuleId = $this->getDefaultEncryptionModuleId(); - if (!empty($defaultModuleId)) { - if (isset($this->encryptionModules[$defaultModuleId])) { - return call_user_func($this->encryptionModules[$defaultModuleId]['callback']); - } else { - $message = 'Default encryption module not loaded'; - throw new Exceptions\ModuleDoesNotExistsException($message); - } - } else { - $message = 'No default encryption module defined'; - throw new Exceptions\ModuleDoesNotExistsException($message); - } - - } - - /** - * set default encryption module Id - * - * @param string $moduleId - * @return bool - */ - public function setDefaultEncryptionModule($moduleId) { - try { - $this->getEncryptionModule($moduleId); - } catch (\Exception $e) { - return false; - } - - $this->config->setAppValue('core', 'default_encryption_module', $moduleId); - return true; - } - - /** - * get default encryption module Id - * - * @return string - */ - public function getDefaultEncryptionModuleId() { - return $this->config->getAppValue('core', 'default_encryption_module'); - } - - /** - * Add storage wrapper - */ - public function setupStorage() { - $encryptionWrapper = new EncryptionWrapper($this->arrayCache, $this, $this->logger); - Filesystem::addStorageWrapper('oc_encryption', array($encryptionWrapper, 'wrapStorage'), 2); - } - - - /** - * check if key storage is ready - * - * @return bool - */ - protected function isKeyStorageReady() { - - $rootDir = $this->util->getKeyStorageRoot(); - - // the default root is always valid - if ($rootDir === '') { - return true; - } - - // check if key storage is mounted correctly - if ($this->rootView->file_exists($rootDir . '/' . Storage::KEY_STORAGE_MARKER)) { - return true; - } - - return false; - } - - -} diff --git a/lib/private/encryption/update.php b/lib/private/encryption/update.php deleted file mode 100644 index 62c23c1fe0c..00000000000 --- a/lib/private/encryption/update.php +++ /dev/null @@ -1,185 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption; - -use OC\Files\Filesystem; -use \OC\Files\Mount; -use \OC\Files\View; - -/** - * update encrypted files, e.g. because a file was shared - */ -class Update { - - /** @var \OC\Files\View */ - protected $view; - - /** @var \OC\Encryption\Util */ - protected $util; - - /** @var \OC\Files\Mount\Manager */ - protected $mountManager; - - /** @var \OC\Encryption\Manager */ - protected $encryptionManager; - - /** @var string */ - protected $uid; - - /** @var \OC\Encryption\File */ - protected $file; - - /** - * - * @param \OC\Files\View $view - * @param \OC\Encryption\Util $util - * @param \OC\Files\Mount\Manager $mountManager - * @param \OC\Encryption\Manager $encryptionManager - * @param \OC\Encryption\File $file - * @param string $uid - */ - public function __construct( - View $view, - Util $util, - Mount\Manager $mountManager, - Manager $encryptionManager, - File $file, - $uid - ) { - - $this->view = $view; - $this->util = $util; - $this->mountManager = $mountManager; - $this->encryptionManager = $encryptionManager; - $this->file = $file; - $this->uid = $uid; - } - - /** - * hook after file was shared - * - * @param array $params - */ - public function postShared($params) { - if ($this->encryptionManager->isEnabled()) { - if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { - $path = Filesystem::getPath($params['fileSource']); - list($owner, $ownerPath) = $this->getOwnerPath($path); - $absPath = '/' . $owner . '/files/' . $ownerPath; - $this->update($absPath); - } - } - } - - /** - * hook after file was unshared - * - * @param array $params - */ - public function postUnshared($params) { - if ($this->encryptionManager->isEnabled()) { - if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') { - $path = Filesystem::getPath($params['fileSource']); - list($owner, $ownerPath) = $this->getOwnerPath($path); - $absPath = '/' . $owner . '/files/' . $ownerPath; - $this->update($absPath); - } - } - } - - /** - * inform encryption module that a file was restored from the trash bin, - * e.g. to update the encryption keys - * - * @param array $params - */ - public function postRestore($params) { - if ($this->encryptionManager->isEnabled()) { - $path = Filesystem::normalizePath('/' . $this->uid . '/files/' . $params['filePath']); - $this->update($path); - } - } - - /** - * inform encryption module that a file was renamed, - * e.g. to update the encryption keys - * - * @param array $params - */ - public function postRename($params) { - $source = $params['oldpath']; - $target = $params['newpath']; - if( - $this->encryptionManager->isEnabled() && - dirname($source) !== dirname($target) - ) { - list($owner, $ownerPath) = $this->getOwnerPath($target); - $absPath = '/' . $owner . '/files/' . $ownerPath; - $this->update($absPath); - } - } - - /** - * get owner and path relative to data/<owner>/files - * - * @param string $path path to file for current user - * @return array ['owner' => $owner, 'path' => $path] - * @throw \InvalidArgumentException - */ - protected function getOwnerPath($path) { - $info = Filesystem::getFileInfo($path); - $owner = Filesystem::getOwner($path); - $view = new View('/' . $owner . '/files'); - $path = $view->getPath($info->getId()); - if ($path === null) { - throw new \InvalidArgumentException('No file found for ' . $info->getId()); - } - - return array($owner, $path); - } - - /** - * notify encryption module about added/removed users from a file/folder - * - * @param string $path relative to data/ - * @throws Exceptions\ModuleDoesNotExistsException - */ - public function update($path) { - - // if a folder was shared, get a list of all (sub-)folders - if ($this->view->is_dir($path)) { - $allFiles = $this->util->getAllFiles($path); - } else { - $allFiles = array($path); - } - - $encryptionModule = $this->encryptionManager->getEncryptionModule(); - - foreach ($allFiles as $file) { - $usersSharing = $this->file->getAccessList($file); - $encryptionModule->update($file, $this->uid, $usersSharing); - } - } - -} diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php deleted file mode 100644 index 9e0cfca830d..00000000000 --- a/lib/private/encryption/util.php +++ /dev/null @@ -1,393 +0,0 @@ -<?php -/** - * @author Björn Schießle <schiessle@owncloud.com> - * @author Jan-Christoph Borchardt <hey@jancborchardt.net> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @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/> - * - */ - -namespace OC\Encryption; - -use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException; -use OC\Encryption\Exceptions\EncryptionHeaderToLargeException; -use OC\Encryption\Exceptions\ModuleDoesNotExistsException; -use OC\Files\Filesystem; -use OC\Files\View; -use OCP\Encryption\IEncryptionModule; -use OCP\Files\Storage; -use OCP\IConfig; - -class Util { - - const HEADER_START = 'HBEGIN'; - const HEADER_END = 'HEND'; - const HEADER_PADDING_CHAR = '-'; - - const HEADER_ENCRYPTION_MODULE_KEY = 'oc_encryption_module'; - - /** - * block size will always be 8192 for a PHP stream - * @see https://bugs.php.net/bug.php?id=21641 - * @var integer - */ - protected $headerSize = 8192; - - /** - * block size will always be 8192 for a PHP stream - * @see https://bugs.php.net/bug.php?id=21641 - * @var integer - */ - protected $blockSize = 8192; - - /** @var View */ - protected $rootView; - - /** @var array */ - protected $ocHeaderKeys; - - /** @var \OC\User\Manager */ - protected $userManager; - - /** @var IConfig */ - protected $config; - - /** @var array paths excluded from encryption */ - protected $excludedPaths; - - /** @var \OC\Group\Manager $manager */ - protected $groupManager; - - /** - * - * @param View $rootView - * @param \OC\User\Manager $userManager - * @param \OC\Group\Manager $groupManager - * @param IConfig $config - */ - public function __construct( - View $rootView, - \OC\User\Manager $userManager, - \OC\Group\Manager $groupManager, - IConfig $config) { - - $this->ocHeaderKeys = [ - self::HEADER_ENCRYPTION_MODULE_KEY - ]; - - $this->rootView = $rootView; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - $this->config = $config; - - $this->excludedPaths[] = 'files_encryption'; - } - - /** - * read encryption module ID from header - * - * @param array $header - * @return string - * @throws ModuleDoesNotExistsException - */ - public function getEncryptionModuleId(array $header = null) { - $id = ''; - $encryptionModuleKey = self::HEADER_ENCRYPTION_MODULE_KEY; - - if (isset($header[$encryptionModuleKey])) { - $id = $header[$encryptionModuleKey]; - } elseif (isset($header['cipher'])) { - if (class_exists('\OCA\Encryption\Crypto\Encryption')) { - // fall back to default encryption if the user migrated from - // ownCloud <= 8.0 with the old encryption - $id = \OCA\Encryption\Crypto\Encryption::ID; - } else { - throw new ModuleDoesNotExistsException('Default encryption module missing'); - } - } - - return $id; - } - - /** - * create header for encrypted file - * - * @param array $headerData - * @param IEncryptionModule $encryptionModule - * @return string - * @throws EncryptionHeaderToLargeException if header has to many arguments - * @throws EncryptionHeaderKeyExistsException if header key is already in use - */ - public function createHeader(array $headerData, IEncryptionModule $encryptionModule) { - $header = self::HEADER_START . ':' . self::HEADER_ENCRYPTION_MODULE_KEY . ':' . $encryptionModule->getId() . ':'; - foreach ($headerData as $key => $value) { - if (in_array($key, $this->ocHeaderKeys)) { - throw new EncryptionHeaderKeyExistsException($key); - } - $header .= $key . ':' . $value . ':'; - } - $header .= self::HEADER_END; - - if (strlen($header) > $this->getHeaderSize()) { - throw new EncryptionHeaderToLargeException(); - } - - $paddedHeader = str_pad($header, $this->headerSize, self::HEADER_PADDING_CHAR, STR_PAD_RIGHT); - - return $paddedHeader; - } - - /** - * go recursively through a dir and collect all files and sub files. - * - * @param string $dir relative to the users files folder - * @return array with list of files relative to the users files folder - */ - public function getAllFiles($dir) { - $result = array(); - $dirList = array($dir); - - while ($dirList) { - $dir = array_pop($dirList); - $content = $this->rootView->getDirectoryContent($dir); - - foreach ($content as $c) { - if ($c->getType() === 'dir') { - $dirList[] = $c->getPath(); - } else { - $result[] = $c->getPath(); - } - } - - } - - return $result; - } - - /** - * check if it is a file uploaded by the user stored in data/user/files - * or a metadata file - * - * @param string $path relative to the data/ folder - * @return boolean - */ - public function isFile($path) { - $parts = explode('/', Filesystem::normalizePath($path), 4); - if (isset($parts[2]) && $parts[2] === 'files') { - return true; - } - return false; - } - - /** - * return size of encryption header - * - * @return integer - */ - public function getHeaderSize() { - return $this->headerSize; - } - - /** - * return size of block read by a PHP stream - * - * @return integer - */ - public function getBlockSize() { - return $this->blockSize; - } - - /** - * get the owner and the path for the file relative to the owners files folder - * - * @param string $path - * @return array - * @throws \BadMethodCallException - */ - public function getUidAndFilename($path) { - - $parts = explode('/', $path); - $uid = ''; - if (count($parts) > 2) { - $uid = $parts[1]; - } - if (!$this->userManager->userExists($uid)) { - throw new \BadMethodCallException( - 'path needs to be relative to the system wide data folder and point to a user specific file' - ); - } - - $ownerPath = implode('/', array_slice($parts, 2)); - - return array($uid, Filesystem::normalizePath($ownerPath)); - - } - - /** - * Remove .path extension from a file path - * @param string $path Path that may identify a .part file - * @return string File path without .part extension - * @note this is needed for reusing keys - */ - public function stripPartialFileExtension($path) { - $extension = pathinfo($path, PATHINFO_EXTENSION); - - if ( $extension === 'part') { - - $newLength = strlen($path) - 5; // 5 = strlen(".part") - $fPath = substr($path, 0, $newLength); - - // if path also contains a transaction id, we remove it too - $extension = pathinfo($fPath, PATHINFO_EXTENSION); - if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId") - $newLength = strlen($fPath) - strlen($extension) -1; - $fPath = substr($fPath, 0, $newLength); - } - return $fPath; - - } else { - return $path; - } - } - - public function getUserWithAccessToMountPoint($users, $groups) { - $result = array(); - if (in_array('all', $users)) { - $result = \OCP\User::getUsers(); - } else { - $result = array_merge($result, $users); - foreach ($groups as $group) { - $result = array_merge($result, \OC_Group::usersInGroup($group)); - } - } - - return $result; - } - - /** - * check if the file is stored on a system wide mount point - * @param string $path relative to /data/user with leading '/' - * @param string $uid - * @return boolean - */ - public function isSystemWideMountPoint($path, $uid) { - if (\OCP\App::isEnabled("files_external")) { - $mounts = \OC_Mount_Config::getSystemMountPoints(); - foreach ($mounts as $mount) { - if (strpos($path, '/files/' . $mount['mountpoint']) === 0) { - if ($this->isMountPointApplicableToUser($mount, $uid)) { - return true; - } - } - } - } - return false; - } - - /** - * check if mount point is applicable to user - * - * @param array $mount contains $mount['applicable']['users'], $mount['applicable']['groups'] - * @param string $uid - * @return boolean - */ - private function isMountPointApplicableToUser($mount, $uid) { - $acceptedUids = array('all', $uid); - // check if mount point is applicable for the user - $intersection = array_intersect($acceptedUids, $mount['applicable']['users']); - if (!empty($intersection)) { - return true; - } - // check if mount point is applicable for group where the user is a member - foreach ($mount['applicable']['groups'] as $gid) { - if ($this->groupManager->isInGroup($uid, $gid)) { - return true; - } - } - return false; - } - - /** - * check if it is a path which is excluded by ownCloud from encryption - * - * @param string $path - * @return boolean - */ - public function isExcluded($path) { - $normalizedPath = Filesystem::normalizePath($path); - $root = explode('/', $normalizedPath, 4); - if (count($root) > 1) { - - // detect alternative key storage root - $rootDir = $this->getKeyStorageRoot(); - if ($rootDir !== '' && - 0 === strpos( - Filesystem::normalizePath($path), - Filesystem::normalizePath($rootDir) - ) - ) { - return true; - } - - - //detect system wide folders - if (in_array($root[1], $this->excludedPaths)) { - return true; - } - - // detect user specific folders - if ($this->userManager->userExists($root[1]) - && in_array($root[2], $this->excludedPaths)) { - - return true; - } - } - return false; - } - - /** - * check if recovery key is enabled for user - * - * @param string $uid - * @return boolean - */ - public function recoveryEnabled($uid) { - $enabled = $this->config->getUserValue($uid, 'encryption', 'recovery_enabled', '0'); - - return ($enabled === '1') ? true : false; - } - - /** - * set new key storage root - * - * @param string $root new key store root relative to the data folder - */ - public function setKeyStorageRoot($root) { - $this->config->setAppValue('core', 'encryption_key_storage_root', $root); - } - - /** - * get key storage root - * - * @return string key storage root - */ - public function getKeyStorageRoot() { - return $this->config->getAppValue('core', 'encryption_key_storage_root', ''); - } - -} |