diff options
author | Frank Karlitschek <karlitschek@gmx.de> | 2016-03-31 20:36:03 +0200 |
---|---|---|
committer | Frank Karlitschek <karlitschek@gmx.de> | 2016-03-31 20:36:03 +0200 |
commit | fdb59079a26b605544bfd76fdd2254e73f27d316 (patch) | |
tree | d29c9b0118d737db9fd9faa469778e2a1e679332 /lib | |
parent | dea3985e86638ba451c79c84ca0b473a2aab99b8 (diff) | |
parent | 93ed965cbb1952faafc1ca5e09ee0de84d122c05 (diff) | |
download | nextcloud-server-fdb59079a26b605544bfd76fdd2254e73f27d316.tar.gz nextcloud-server-fdb59079a26b605544bfd76fdd2254e73f27d316.zip |
Merge pull request #23675 from owncloud/fix_encryption_versions_on_external_storages
fix creation of versions of encrypted files on external storages
Diffstat (limited to 'lib')
-rw-r--r-- | lib/base.php | 3 | ||||
-rw-r--r-- | lib/private/Server.php | 4 | ||||
-rw-r--r-- | lib/private/encryption/encryptionwrapper.php | 124 | ||||
-rw-r--r-- | lib/private/encryption/manager.php | 19 | ||||
-rw-r--r-- | lib/private/encryption/util.php | 50 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 21 |
6 files changed, 159 insertions, 62 deletions
diff --git a/lib/base.php b/lib/base.php index 1a3dbbaa56a..f3076a1181a 100644 --- a/lib/base.php +++ b/lib/base.php @@ -722,7 +722,8 @@ class OC { } private static function registerEncryptionWrapper() { - \OCP\Util::connectHook('OC_Filesystem', 'preSetup', 'OC\Encryption\Manager', 'setupStorage'); + $manager = self::$server->getEncryptionManager(); + \OCP\Util::connectHook('OC_Filesystem', 'preSetup', $manager, 'setupStorage'); } private static function registerEncryptionHooks() { diff --git a/lib/private/Server.php b/lib/private/Server.php index 392b2b17b9c..581a2b44cea 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -59,6 +59,7 @@ use OC\Lock\DBLockingProvider; use OC\Lock\MemcacheLockingProvider; use OC\Lock\NoopLockingProvider; use OC\Mail\Mailer; +use OC\Memcache\ArrayCache; use OC\Notification\Manager; use OC\Security\CertificateManager; use OC\Security\CSP\ContentSecurityPolicyManager; @@ -117,7 +118,8 @@ class Server extends ServerContainer implements IServerContainer { $c->getLogger(), $c->getL10N('core'), new View(), - $util + $util, + new ArrayCache() ); }); diff --git a/lib/private/encryption/encryptionwrapper.php b/lib/private/encryption/encryptionwrapper.php new file mode 100644 index 00000000000..11beb0cd6b1 --- /dev/null +++ b/lib/private/encryption/encryptionwrapper.php @@ -0,0 +1,124 @@ +<?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/manager.php b/lib/private/encryption/manager.php index d1d17a92887..d45bbf07ee9 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -27,6 +27,7 @@ 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; @@ -54,20 +55,25 @@ class Manager implements IManager { /** @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) { + 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; } /** @@ -227,14 +233,9 @@ class Manager implements IManager { /** * Add storage wrapper */ - public static function setupStorage() { - $util = new Util( - new View(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager(), - \OC::$server->getConfig() - ); - Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2); + public function setupStorage() { + $encryptionWrapper = new EncryptionWrapper($this->arrayCache, $this, $this->logger); + Filesystem::addStorageWrapper('oc_encryption', array($encryptionWrapper, 'wrapStorage'), 2); } diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index 860c541934a..9e0cfca830d 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -28,10 +28,8 @@ use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException; use OC\Encryption\Exceptions\EncryptionHeaderToLargeException; use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\Files\Filesystem; -use OC\Files\Storage\Wrapper\Encryption; use OC\Files\View; use OCP\Encryption\IEncryptionModule; -use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage; use OCP\IConfig; @@ -392,52 +390,4 @@ class Util { return $this->config->getAppValue('core', 'encryption_key_storage_root', ''); } - /** - * 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')) { - - $manager = \OC::$server->getEncryptionManager(); - $user = \OC::$server->getUserSession()->getUser(); - $logger = \OC::$server->getLogger(); - $mountManager = Filesystem::getMountManager(); - $uid = $user ? $user->getUID() : null; - $fileHelper = \OC::$server->getEncryptionFilesHelper(); - $keyStorage = \OC::$server->getEncryptionKeyStorage(); - $update = new Update( - new View(), - $this, - Filesystem::getMountManager(), - $manager, - $fileHelper, - $uid - ); - return new Encryption( - $parameters, - $manager, - $this, - $logger, - $fileHelper, - $uid, - $keyStorage, - $update, - $mountManager - ); - } else { - return $storage; - } - } } diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 81eea9944f8..49515fbcc57 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -33,6 +33,7 @@ use OC\Files\Cache\CacheEntry; use OC\Files\Filesystem; use OC\Files\Mount\Manager; use OC\Files\Storage\LocalTempFileTrait; +use OC\Memcache\ArrayCache; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\Encryption\IFile; use OCP\Encryption\IManager; @@ -82,6 +83,9 @@ class Encryption extends Wrapper { /** @var array remember for which path we execute the repair step to avoid recursions */ private $fixUnencryptedSizeOf = array(); + /** @var ArrayCache */ + private $arrayCache; + /** * @param array $parameters * @param IManager $encryptionManager @@ -92,6 +96,7 @@ class Encryption extends Wrapper { * @param IStorage $keyStorage * @param Update $update * @param Manager $mountManager + * @param ArrayCache $arrayCache */ public function __construct( $parameters, @@ -102,7 +107,8 @@ class Encryption extends Wrapper { $uid = null, IStorage $keyStorage = null, Update $update = null, - Manager $mountManager = null + Manager $mountManager = null, + ArrayCache $arrayCache = null ) { $this->mountPoint = $parameters['mountPoint']; @@ -116,6 +122,7 @@ class Encryption extends Wrapper { $this->unencryptedSize = array(); $this->update = $update; $this->mountManager = $mountManager; + $this->arrayCache = $arrayCache; parent::__construct($parameters); } @@ -352,6 +359,14 @@ class Encryption extends Wrapper { */ public function fopen($path, $mode) { + // check if the file is stored in the array cache, this means that we + // copy a file over to the versions folder, in this case we don't want to + // decrypt it + if ($this->arrayCache->hasKey('encryption_copy_version_' . $path)) { + $this->arrayCache->remove('encryption_copy_version_' . $path); + return $this->storage->fopen($path, $mode); + } + $encryptionEnabled = $this->encryptionManager->isEnabled(); $shouldEncrypt = false; $encryptionModule = null; @@ -674,6 +689,10 @@ class Encryption extends Wrapper { // key from the original file. Just create a 1:1 copy and done if ($this->isVersion($targetInternalPath) || $this->isVersion($sourceInternalPath)) { + // remember that we try to create a version so that we can detect it during + // fopen($sourceInternalPath) and by-pass the encryption in order to + // create a 1:1 copy of the file + $this->arrayCache->set('encryption_copy_version_' . $sourceInternalPath, true); $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); if ($result) { $info = $this->getCache('', $sourceStorage)->get($sourceInternalPath); |