/** * @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; }
/** * read header from file * * @param string $path * @return array */ protected function getHeader($path) { $realFile = $this->util->stripPartialFileExtension($path); if ($this->storage->file_exists($realFile)) { $path = $realFile; } $firstBlock = $this->readFirstBlock($path); $result = $this->parseRawHeader($firstBlock); // if the header doesn't contain a encryption module we check if it is a // legacy file. If true, we add the default encryption module if (!isset($result[Util::HEADER_ENCRYPTION_MODULE_KEY])) { if (!empty($result)) { $result[Util::HEADER_ENCRYPTION_MODULE_KEY] = 'OC_DEFAULT_MODULE'; } else { // if the header was empty we have to check first if it is a encrypted file at all $info = $this->getCache()->get($path); if (isset($info['encrypted']) && $info['encrypted'] === true) { $result[Util::HEADER_ENCRYPTION_MODULE_KEY] = 'OC_DEFAULT_MODULE'; } } } return $result; }
/** * 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); }
/** * read header from file * * @param string $path * @return array */ protected function getHeader($path) { $header = ''; $realFile = $this->util->stripPartialFileExtension($path); if ($this->storage->file_exists($realFile)) { $handle = $this->storage->fopen($realFile, 'r'); $firstBlock = fread($handle, $this->util->getHeaderSize()); fclose($handle); if (substr($firstBlock, 0, strlen(Util::HEADER_START)) === Util::HEADER_START) { $header = $firstBlock; } } return $header; }
/** * get path to key folder for a given file * * @param string $path path to the file, relative to data/ * @return string * @throws GenericEncryptionException * @internal param string $keyId */ private function getFileKeyDir($path) { if ($this->view->is_dir($path)) { throw new GenericEncryptionException("file was expected but directory was given: {$path}"); } list($owner, $filename) = $this->util->getUidAndFilename($path); $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)) { $keyPath = $this->keys_base_dir . $filename . '/'; } else { $keyPath = '/' . $owner . $this->keys_base_dir . $filename . '/'; } return \OC\Files\Filesystem::normalizePath($keyPath . $this->encryptionModuleId . '/', false); }
/** * @dataProvider dataTestStripPartialFileExtension * * @param string $path * @param string $expected */ public function testStripPartialFileExtension($path, $expected) { $this->assertSame($expected, $this->util->stripPartialFileExtension($path)); }