diff options
author | Vincent Petry <pvince81@owncloud.com> | 2015-08-31 15:58:30 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2015-08-31 15:58:30 +0200 |
commit | f8d8de5da63f8838cf05a48634f07384cf30ab7d (patch) | |
tree | cdbeb69de7b4dfdb82e8adea12a3a63cb1081903 /lib/private | |
parent | 3e9533ae11b1a14d56fa562cc75667308e40e743 (diff) | |
parent | 37513f9411035f6edcb78f9f89ceb4f8433f0aa5 (diff) | |
download | nextcloud-server-f8d8de5da63f8838cf05a48634f07384cf30ab7d.tar.gz nextcloud-server-f8d8de5da63f8838cf05a48634f07384cf30ab7d.zip |
Merge pull request #17899 from owncloud/enc_make_key_storage_root_configurable
Make root of key storage configurable
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/encryption/keys/storage.php | 25 | ||||
-rw-r--r-- | lib/private/encryption/manager.php | 53 | ||||
-rw-r--r-- | lib/private/encryption/util.php | 42 | ||||
-rw-r--r-- | lib/private/security/certificatemanager.php | 15 | ||||
-rw-r--r-- | lib/private/server.php | 27 | ||||
-rw-r--r-- | lib/private/util.php | 1 |
6 files changed, 133 insertions, 30 deletions
diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php index b754462d9b0..d0c094538b0 100644 --- a/lib/private/encryption/keys/storage.php +++ b/lib/private/encryption/keys/storage.php @@ -27,11 +27,13 @@ namespace OC\Encryption\Keys; use OC\Encryption\Util; use OC\Files\Filesystem; use OC\Files\View; -use OCP\Encryption\Exceptions\GenericEncryptionException; 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; @@ -42,6 +44,10 @@ class Storage implements IStorage { /** @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; @@ -58,6 +64,7 @@ class Storage implements IStorage { $this->encryption_base_dir = '/files_encryption'; $this->keys_base_dir = $this->encryption_base_dir .'/keys'; + $this->root_dir = $this->util->getKeyStorageRoot(); } /** @@ -162,13 +169,13 @@ class Storage implements IStorage { protected function constructUserKeyPath($encryptionModuleId, $keyId, $uid) { if ($uid === null) { - $path = $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $keyId; + $path = $this->root_dir . '/' . $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $keyId; } else { - $path = '/' . $uid . $this->encryption_base_dir . '/' + $path = $this->root_dir . '/' . $uid . $this->encryption_base_dir . '/' . $encryptionModuleId . '/' . $uid . '.' . $keyId; } - return $path; + return \OC\Files\Filesystem::normalizePath($path); } /** @@ -227,9 +234,9 @@ class Storage implements IStorage { // in case of system wide mount points the keys are stored directly in the data directory if ($this->util->isSystemWideMountPoint($filename, $owner)) { - $keyPath = $this->keys_base_dir . $filename . '/'; + $keyPath = $this->root_dir . '/' . $this->keys_base_dir . $filename . '/'; } else { - $keyPath = '/' . $owner . $this->keys_base_dir . $filename . '/'; + $keyPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $filename . '/'; } return Filesystem::normalizePath($keyPath . $encryptionModuleId . '/', false); @@ -290,12 +297,12 @@ class Storage implements IStorage { $systemWideMountPoint = $this->util->isSystemWideMountPoint($relativePath, $owner); if ($systemWideMountPoint) { - $systemPath = $this->keys_base_dir . $relativePath . '/'; + $systemPath = $this->root_dir . '/' . $this->keys_base_dir . $relativePath . '/'; } else { - $systemPath = '/' . $owner . $this->keys_base_dir . $relativePath . '/'; + $systemPath = $this->root_dir . '/' . $owner . $this->keys_base_dir . $relativePath . '/'; } - return $systemPath; + return Filesystem::normalizePath($systemPath, false); } /** diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index 1e0a065e25a..c004dfda0d9 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -25,14 +25,12 @@ namespace OC\Encryption; +use OC\Encryption\Keys\Storage; use OC\Files\Filesystem; -use OC\Files\Storage\Shared; -use OC\Files\Storage\Wrapper\Encryption; use OC\Files\View; -use OC\Search\Provider\File; +use OC\ServiceUnavailableException; use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IManager; -use OCP\Files\Mount\IMountPoint; use OCP\IConfig; use OCP\IL10N; use OCP\ILogger; @@ -51,16 +49,26 @@ class Manager implements IManager { /** @var Il10n */ protected $l; + /** @var View */ + protected $rootView; + + /** @var Util */ + protected $util; + /** * @param IConfig $config * @param ILogger $logger * @param IL10N $l10n + * @param View $rootView + * @param Util $util */ - public function __construct(IConfig $config, ILogger $logger, IL10N $l10n) { + public function __construct(IConfig $config, ILogger $logger, IL10N $l10n, View $rootView, Util $util) { $this->encryptionModules = array(); $this->config = $config; $this->logger = $logger; $this->l = $l10n; + $this->rootView = $rootView; + $this->util = $util; } /** @@ -82,7 +90,8 @@ class Manager implements IManager { /** * check if new encryption is ready * - * @return boolean + * @return bool + * @throws ServiceUnavailableException */ public function isReady() { // check if we are still in transit between the old and the new encryption @@ -94,6 +103,11 @@ class Manager implements IManager { $this->logger->warning($warning); return false; } + + if ($this->isKeyStorageReady() === false) { + throw new ServiceUnavailableException('Key Storage is not ready'); + } + return true; } @@ -221,6 +235,31 @@ class Manager implements IManager { \OC::$server->getGroupManager(), \OC::$server->getConfig() ); - \OC\Files\Filesystem::addStorageWrapper('oc_encryption', array($util, 'wrapStorage'), 2); + Filesystem::addStorageWrapper('oc_encryption', array($util, '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/util.php b/lib/private/encryption/util.php index d0733941a35..90ae8259972 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -59,7 +59,7 @@ class Util { protected $blockSize = 8192; /** @var View */ - protected $view; + protected $rootView; /** @var array */ protected $ocHeaderKeys; @@ -78,13 +78,13 @@ class Util { /** * - * @param \OC\Files\View $view + * @param View $rootView * @param \OC\User\Manager $userManager * @param \OC\Group\Manager $groupManager * @param IConfig $config */ public function __construct( - \OC\Files\View $view, + View $rootView, \OC\User\Manager $userManager, \OC\Group\Manager $groupManager, IConfig $config) { @@ -93,7 +93,7 @@ class Util { self::HEADER_ENCRYPTION_MODULE_KEY ]; - $this->view = $view; + $this->rootView = $rootView; $this->userManager = $userManager; $this->groupManager = $groupManager; $this->config = $config; @@ -167,7 +167,7 @@ class Util { while ($dirList) { $dir = array_pop($dirList); - $content = $this->view->getDirectoryContent($dir); + $content = $this->rootView->getDirectoryContent($dir); foreach ($content as $c) { if ($c->getType() === 'dir') { @@ -332,10 +332,22 @@ class Util { * @return boolean */ public function isExcluded($path) { - $normalizedPath = \OC\Files\Filesystem::normalizePath($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; @@ -364,6 +376,24 @@ class Util { } /** + * 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', ''); + } + + /** * Wraps the given storage when it is not a shared storage * * @param string $mountPoint diff --git a/lib/private/security/certificatemanager.php b/lib/private/security/certificatemanager.php index d61c7f29327..4d470f69a66 100644 --- a/lib/private/security/certificatemanager.php +++ b/lib/private/security/certificatemanager.php @@ -27,6 +27,7 @@ namespace OC\Security; use OC\Files\Filesystem; use OCP\ICertificateManager; +use OCP\IConfig; /** * Manage trusted certificates for users @@ -43,12 +44,19 @@ class CertificateManager implements ICertificateManager { protected $view; /** + * @var IConfig + */ + protected $config; + + /** * @param string $uid * @param \OC\Files\View $view relative zu data/ + * @param IConfig $config */ - public function __construct($uid, \OC\Files\View $view) { + public function __construct($uid, \OC\Files\View $view, IConfig $config) { $this->uid = $uid; $this->view = $view; + $this->config = $config; } /** @@ -57,6 +65,11 @@ class CertificateManager implements ICertificateManager { * @return \OCP\ICertificate[] */ public function listCertificates() { + + if (!$this->config->getSystemValue('installed', false)) { + return array(); + } + $path = $this->getPathToCertificates() . 'uploads/'; if (!$this->view->is_dir($path)) { return array(); diff --git a/lib/private/server.php b/lib/private/server.php index a47fa2e43f9..a741f33eb3d 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -91,12 +91,25 @@ class Server extends SimpleContainer implements IServerContainer { }); $this->registerService('EncryptionManager', function (Server $c) { - return new Encryption\Manager($c->getConfig(), $c->getLogger(), $c->getL10N('core')); + $view = new View(); + $util = new Encryption\Util( + $view, + $c->getUserManager(), + $c->getGroupManager(), + $c->getConfig() + ); + return new Encryption\Manager( + $c->getConfig(), + $c->getLogger(), + $c->getL10N('core'), + new View(), + $util + ); }); $this->registerService('EncryptionFileHelper', function (Server $c) { - $util = new \OC\Encryption\Util( - new \OC\Files\View(), + $util = new Encryption\Util( + new View(), $c->getUserManager(), $c->getGroupManager(), $c->getConfig() @@ -105,8 +118,8 @@ class Server extends SimpleContainer implements IServerContainer { }); $this->registerService('EncryptionKeyStorage', function (Server $c) { - $view = new \OC\Files\View(); - $util = new \OC\Encryption\Util( + $view = new View(); + $util = new Encryption\Util( $view, $c->getUserManager(), $c->getGroupManager(), @@ -326,7 +339,7 @@ class Server extends SimpleContainer implements IServerContainer { $uid = $user ? $user : null; return new ClientService( $c->getConfig(), - new \OC\Security\CertificateManager($uid, new \OC\Files\View()) + new \OC\Security\CertificateManager($uid, new View(), $c->getConfig()) ); }); $this->registerService('EventLogger', function (Server $c) { @@ -839,7 +852,7 @@ class Server extends SimpleContainer implements IServerContainer { } $userId = $user->getUID(); } - return new CertificateManager($userId, new \OC\Files\View()); + return new CertificateManager($userId, new View(), $this->getConfig()); } /** diff --git a/lib/private/util.php b/lib/private/util.php index edd375b5c36..0fda55496dc 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1145,6 +1145,7 @@ class OC_Util { * @throws \OC\HintException If the test file can't get written. */ public function isHtaccessWorking(\OCP\IConfig $config) { + if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) { return true; } |