diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/base.php | 1 | ||||
-rw-r--r-- | lib/private/encryption/keys/storage.php | 6 | ||||
-rw-r--r-- | lib/private/encryption/manager.php | 46 | ||||
-rw-r--r-- | lib/private/encryption/util.php | 47 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 11 | ||||
-rw-r--r-- | lib/private/files/stream/encryption.php | 4 | ||||
-rw-r--r-- | lib/private/server.php | 16 |
7 files changed, 108 insertions, 23 deletions
diff --git a/lib/base.php b/lib/base.php index f0c54640b17..80f2736fcf6 100644 --- a/lib/base.php +++ b/lib/base.php @@ -728,6 +728,7 @@ class OC { new \OC\Encryption\Util( new \OC\Files\View(), \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), \OC::$server->getConfig()), \OC\Files\Filesystem::getMountManager(), \OC::$server->getEncryptionManager(), diff --git a/lib/private/encryption/keys/storage.php b/lib/private/encryption/keys/storage.php index 9d978193130..925c20c74c8 100644 --- a/lib/private/encryption/keys/storage.php +++ b/lib/private/encryption/keys/storage.php @@ -266,7 +266,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { $filename = $this->util->stripPartialFileExtension($filename); // in case of system wide mount points the keys are stored directly in the data directory - if ($this->util->isSystemWideMountPoint($filename)) { + if ($this->util->isSystemWideMountPoint($filename, $owner)) { $keyPath = $this->keys_base_dir . $filename . '/'; } else { $keyPath = '/' . $owner . $this->keys_base_dir . $filename . '/'; @@ -287,7 +287,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { list($owner, $source) = $this->util->getUidAndFilename($source); list(, $target) = $this->util->getUidAndFilename($target); - $systemWide = $this->util->isSystemWideMountPoint($target); + $systemWide = $this->util->isSystemWideMountPoint($target, $owner); if ($systemWide) { $sourcePath = $this->keys_base_dir . $source . '/'; @@ -315,7 +315,7 @@ class Storage implements \OCP\Encryption\Keys\IStorage { list($owner, $source) = $this->util->getUidAndFilename($source); list(, $target) = $this->util->getUidAndFilename($target); - $systemWide = $this->util->isSystemWideMountPoint($target); + $systemWide = $this->util->isSystemWideMountPoint($target, $owner); if ($systemWide) { $sourcePath = $this->keys_base_dir . $source . '/'; diff --git a/lib/private/encryption/manager.php b/lib/private/encryption/manager.php index 74cad0a75bb..89abad4934a 100644 --- a/lib/private/encryption/manager.php +++ b/lib/private/encryption/manager.php @@ -22,24 +22,34 @@ namespace OC\Encryption; +use OC\Files\Storage\Shared; use OC\Files\Storage\Wrapper\Encryption; +use OC\Files\View; use OCP\Encryption\IEncryptionModule; +use OCP\Encryption\IManager; use OCP\Files\Mount\IMountPoint; +use OCP\IConfig; +use OCP\ILogger; -class Manager implements \OCP\Encryption\IManager { +class Manager implements IManager { /** @var array */ protected $encryptionModules; - /** @var \OCP\IConfig */ + /** @var IConfig */ protected $config; + /** @var ILogger */ + protected $logger; + /** - * @param \OCP\IConfig $config + * @param IConfig $config + * @param ILogger $logger */ - public function __construct(\OCP\IConfig $config) { + public function __construct(IConfig $config, ILogger $logger) { $this->encryptionModules = array(); $this->config = $config; + $this->logger = $logger; } /** @@ -59,6 +69,24 @@ class Manager implements \OCP\Encryption\IManager { } /** + * check if new encryption is ready + * + * @return boolean + */ + 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 "ownCloud Default Encryption Module" + and run \'occ encryption:migrate\''; + $this->logger->warning($warning); + return false; + } + return true; + } + + /** * Registers an encryption module * * @param IEncryptionModule $module @@ -185,10 +213,14 @@ class Manager implements \OCP\Encryption\IManager { 'mountPoint' => $mountPoint, 'mount' => $mount]; - if (!($storage instanceof \OC\Files\Storage\Shared)) { + if (!($storage instanceof Shared)) { $manager = \OC::$server->getEncryptionManager(); - $util = new \OC\Encryption\Util( - new \OC\Files\View(), \OC::$server->getUserManager(), \OC::$server->getConfig()); + $util = new Util( + new View(), + \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), + \OC::$server->getConfig() + ); $user = \OC::$server->getUserSession()->getUser(); $logger = \OC::$server->getLogger(); $uid = $user ? $user->getUID() : null; diff --git a/lib/private/encryption/util.php b/lib/private/encryption/util.php index e7cf607c7b1..98a38012dba 100644 --- a/lib/private/encryption/util.php +++ b/lib/private/encryption/util.php @@ -24,6 +24,7 @@ namespace OC\Encryption; use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException; use OC\Encryption\Exceptions\EncryptionHeaderToLargeException; +use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\Files\View; use OCP\Encryption\IEncryptionModule; use OCP\IConfig; @@ -65,15 +66,20 @@ class Util { /** @var array paths excluded from encryption */ protected $excludedPaths; + /** @var \OC\Group\Manager $manager */ + protected $groupManager; + /** * * @param \OC\Files\View $view * @param \OC\User\Manager $userManager + * @param \OC\Group\Manager $groupManager * @param IConfig $config */ public function __construct( \OC\Files\View $view, \OC\User\Manager $userManager, + \OC\Group\Manager $groupManager, IConfig $config) { $this->ocHeaderKeys = [ @@ -82,6 +88,7 @@ class Util { $this->view = $view; $this->userManager = $userManager; + $this->groupManager = $groupManager; $this->config = $config; $this->excludedPaths[] = 'files_encryption'; @@ -92,6 +99,7 @@ class Util { * * @param array $header * @return string + * @throws ModuleDoesNotExistsException */ public function getEncryptionModuleId(array $header = null) { $id = ''; @@ -99,6 +107,14 @@ class Util { 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('ownCloud default encryption module missing'); + } } return $id; @@ -294,15 +310,15 @@ class Util { /** * 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) { - $normalizedPath = ltrim($path, '/'); + public function isSystemWideMountPoint($path, $uid) { if (\OCP\App::isEnabled("files_external")) { $mounts = \OC_Mount_Config::getSystemMountPoints(); foreach ($mounts as $mount) { - if ($mount['mountpoint'] == substr($normalizedPath, 0, strlen($mount['mountpoint']))) { - if ($this->isMountPointApplicableToUser($mount)) { + if (strpos($path, '/files/' . $mount['mountpoint']) === 0) { + if ($this->isMountPointApplicableToUser($mount, $uid)) { return true; } } @@ -312,6 +328,29 @@ class Util { } /** + * 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 diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 5697139bd6b..01bd861e3a2 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -154,7 +154,8 @@ class Encryption extends Wrapper { * @return bool */ public function unlink($path) { - if ($this->util->isExcluded($path)) { + $fullPath = $this->getFullPath($path); + if ($this->util->isExcluded($fullPath)) { return $this->storage->unlink($path); } @@ -175,7 +176,8 @@ class Encryption extends Wrapper { * @return bool */ public function rename($path1, $path2) { - if ($this->util->isExcluded($path1)) { + $fullPath1 = $this->getFullPath($path1); + if ($this->util->isExcluded($fullPath1)) { return $this->storage->rename($path1, $path2); } @@ -204,8 +206,9 @@ class Encryption extends Wrapper { * @return bool */ public function copy($path1, $path2) { - if ($this->util->isExcluded($path1)) { - return $this->storage->rename($path1, $path2); + $fullPath1 = $this->getFullPath($path1); + if ($this->util->isExcluded($fullPath1)) { + return $this->storage->copy($path1, $path2); } $source = $this->getFullPath($path1); diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php index 9ba98e61d3e..4a1df840105 100644 --- a/lib/private/files/stream/encryption.php +++ b/lib/private/files/stream/encryption.php @@ -280,7 +280,7 @@ class Encryption extends Wrapper { if ($this->position === 0) { $this->writeHeader(); - $this->size+=$this->util->getHeaderSize(); + $this->size = $this->util->getHeaderSize(); } $length = 0; @@ -293,7 +293,7 @@ class Encryption extends Wrapper { // for seekable streams the pointer is moved back to the beginning of the encrypted block // flush will start writing there when the position moves to another block - $positionInFile = floor($this->position / $this->unencryptedBlockSize) * + $positionInFile = (int)floor($this->position / $this->unencryptedBlockSize) * $this->util->getBlockSize() + $this->util->getHeaderSize(); $resultFseek = parent::stream_seek($positionInFile); diff --git a/lib/private/server.php b/lib/private/server.php index 6df7722973e..ea673ea1485 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -84,11 +84,16 @@ class Server extends SimpleContainer implements IServerContainer { }); $this->registerService('EncryptionManager', function (Server $c) { - return new Encryption\Manager($c->getConfig()); + return new Encryption\Manager($c->getConfig(), $c->getLogger()); }); $this->registerService('EncryptionFileHelper', function (Server $c) { - $util = new \OC\Encryption\Util(new \OC\Files\View(), $c->getUserManager(), $c->getConfig()); + $util = new \OC\Encryption\Util( + new \OC\Files\View(), + $c->getUserManager(), + $c->getGroupManager(), + $c->getConfig() + ); return new Encryption\File($util); }); @@ -437,7 +442,12 @@ class Server extends SimpleContainer implements IServerContainer { */ function getEncryptionKeyStorage($encryptionModuleId) { $view = new \OC\Files\View(); - $util = new \OC\Encryption\Util($view, \OC::$server->getUserManager(), \OC::$server->getConfig()); + $util = new \OC\Encryption\Util( + $view, + \OC::$server->getUserManager(), + \OC::$server->getGroupManager(), + \OC::$server->getConfig() + ); return $this->query('EncryptionKeyStorageFactory')->get($encryptionModuleId, $view, $util); } |