diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/app.php | 2 | ||||
-rw-r--r-- | lib/private/files/storage/dav.php | 6 | ||||
-rw-r--r-- | lib/private/files/storage/wrapper/encryption.php | 132 | ||||
-rw-r--r-- | lib/private/share/hooks.php | 17 | ||||
-rw-r--r-- | lib/private/share20/manager.php | 2 | ||||
-rw-r--r-- | lib/private/updater.php | 6 |
6 files changed, 156 insertions, 9 deletions
diff --git a/lib/private/app.php b/lib/private/app.php index 49d4e942a09..787029b653b 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -87,7 +87,7 @@ class OC_App { /** * loads all apps * - * @param array $types + * @param string[] | string | null $types * @return bool * * This function walks through the ownCloud directory and loads all apps diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php index a6e77e1b232..5e00a03ebb8 100644 --- a/lib/private/files/storage/dav.php +++ b/lib/private/files/storage/dav.php @@ -136,9 +136,13 @@ class DAV extends Common { 'password' => $this->password, ); + $proxy = \OC::$server->getConfig()->getSystemValue('proxy', ''); + if($proxy !== '') { + $settings['proxy'] = $proxy; + } + $this->client = new Client($settings); $this->client->setThrowExceptions(true); - if ($this->secure === true && $this->certPath) { $this->client->addCurlSetting(CURLOPT_CAINFO, $this->certPath); } diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php index 11c6084d00c..1b0f39428a4 100644 --- a/lib/private/files/storage/wrapper/encryption.php +++ b/lib/private/files/storage/wrapper/encryption.php @@ -61,7 +61,7 @@ class Encryption extends Wrapper { private $uid; /** @var array */ - private $unencryptedSize; + protected $unencryptedSize; /** @var \OCP\Encryption\IFile */ private $fileHelper; @@ -78,6 +78,9 @@ class Encryption extends Wrapper { /** @var Manager */ private $mountManager; + /** @var array remember for which path we execute the repair step to avoid recursions */ + private $fixUnencryptedSizeOf = array(); + /** * @param array $parameters * @param IManager $encryptionManager @@ -147,8 +150,9 @@ class Encryption extends Wrapper { } if (isset($info['fileid']) && $info['encrypted']) { - return $info['size']; + return $this->verifyUnencryptedSize($path, $info['size']); } + return $this->storage->filesize($path); } @@ -169,8 +173,8 @@ class Encryption extends Wrapper { } else { $info = $this->getCache()->get($path); if (isset($info['fileid']) && $info['encrypted']) { + $data['size'] = $this->verifyUnencryptedSize($path, $info['size']); $data['encrypted'] = true; - $data['size'] = $info['size']; } } @@ -441,6 +445,128 @@ class Encryption extends Wrapper { return $this->storage->fopen($path, $mode); } + + /** + * perform some plausibility checks if the the unencrypted size is correct. + * If not, we calculate the correct unencrypted size and return it + * + * @param string $path internal path relative to the storage root + * @param int $unencryptedSize size of the unencrypted file + * + * @return int unencrypted size + */ + protected function verifyUnencryptedSize($path, $unencryptedSize) { + + $size = $this->storage->filesize($path); + $result = $unencryptedSize; + + if ($unencryptedSize < 0 || + ($size > 0 && $unencryptedSize === $size) + ) { + // check if we already calculate the unencrypted size for the + // given path to avoid recursions + if (isset($this->fixUnencryptedSizeOf[$this->getFullPath($path)]) === false) { + $this->fixUnencryptedSizeOf[$this->getFullPath($path)] = true; + try { + $result = $this->fixUnencryptedSize($path, $size, $unencryptedSize); + } catch (\Exception $e) { + $this->logger->error('Couldn\'t re-calculate unencrypted size for '. $path); + $this->logger->logException($e); + } + unset($this->fixUnencryptedSizeOf[$this->getFullPath($path)]); + } + } + + return $result; + } + + /** + * calculate the unencrypted size + * + * @param string $path internal path relative to the storage root + * @param int $size size of the physical file + * @param int $unencryptedSize size of the unencrypted file + * + * @return int calculated unencrypted size + */ + protected function fixUnencryptedSize($path, $size, $unencryptedSize) { + + $headerSize = $this->getHeaderSize($path); + $header = $this->getHeader($path); + $encryptionModule = $this->getEncryptionModule($path); + + $stream = $this->storage->fopen($path, 'r'); + + // if we couldn't open the file we return the old unencrypted size + if (!is_resource($stream)) { + $this->logger->error('Could not open ' . $path . '. Recalculation of unencrypted size aborted.'); + return $unencryptedSize; + } + + $newUnencryptedSize = 0; + $size -= $headerSize; + $blockSize = $this->util->getBlockSize(); + + // if a header exists we skip it + if ($headerSize > 0) { + fread($stream, $headerSize); + } + + // fast path, else the calculation for $lastChunkNr is bogus + if ($size === 0) { + return 0; + } + + $signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false; + $unencryptedBlockSize = $encryptionModule->getUnencryptedBlockSize($signed); + + // calculate last chunk nr + // next highest is end of chunks, one subtracted is last one + // we have to read the last chunk, we can't just calculate it (because of padding etc) + + $lastChunkNr = ceil($size/ $blockSize)-1; + // calculate last chunk position + $lastChunkPos = ($lastChunkNr * $blockSize); + // try to fseek to the last chunk, if it fails we have to read the whole file + if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) { + $newUnencryptedSize += $lastChunkNr * $unencryptedBlockSize; + } + + $lastChunkContentEncrypted=''; + $count = $blockSize; + + while ($count > 0) { + $data=fread($stream, $blockSize); + $count=strlen($data); + $lastChunkContentEncrypted .= $data; + if(strlen($lastChunkContentEncrypted) > $blockSize) { + $newUnencryptedSize += $unencryptedBlockSize; + $lastChunkContentEncrypted=substr($lastChunkContentEncrypted, $blockSize); + } + } + + fclose($stream); + + // we have to decrypt the last chunk to get it actual size + $encryptionModule->begin($this->getFullPath($path), $this->uid, 'r', $header, []); + $decryptedLastChunk = $encryptionModule->decrypt($lastChunkContentEncrypted, $lastChunkNr . 'end'); + $decryptedLastChunk .= $encryptionModule->end($this->getFullPath($path), $lastChunkNr . 'end'); + + // calc the real file size with the size of the last chunk + $newUnencryptedSize += strlen($decryptedLastChunk); + + $this->updateUnencryptedSize($this->getFullPath($path), $newUnencryptedSize); + + // write to cache if applicable + $cache = $this->storage->getCache(); + if ($cache) { + $entry = $cache->get($path); + $cache->update($entry['fileid'], ['size' => $newUnencryptedSize]); + } + + return $newUnencryptedSize; + } + /** * @param Storage $sourceStorage * @param string $sourceInternalPath diff --git a/lib/private/share/hooks.php b/lib/private/share/hooks.php index c939164e39e..b730146ddfe 100644 --- a/lib/private/share/hooks.php +++ b/lib/private/share/hooks.php @@ -55,6 +55,15 @@ class Hooks extends \OC\Share\Constants { * @param array $arguments */ public static function pre_addToGroup($arguments) { + $currentUser = \OC::$server->getUserSession()->getUser(); + $currentUserID = is_null($currentUser) ? '' : $currentUser->getUID(); + + // setup filesystem for added user if it isn't the current user + if($currentUserID !== $arguments['uid']) { + \OC_Util::tearDownFS(); + \OC_Util::setupFS($arguments['uid']); + } + /** @var \OC\DB\Connection $db */ $db = \OC::$server->getDatabaseConnection(); @@ -120,6 +129,14 @@ class Hooks extends \OC\Share\Constants { ]; } } + + // re-setup old filesystem state + if($currentUserID !== $arguments['uid']) { + \OC_Util::tearDownFS(); + if($currentUserID !== '') { + \OC_Util::setupFS($currentUserID); + } + } } /** diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index 9b33e947557..63119edf504 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -280,7 +280,7 @@ class Manager implements IManager { 'expirationDate' => &$expirationDate, 'accepted' => &$accepted, 'message' => &$message, - 'passwordSet' => $share->getPassword() === null, + 'passwordSet' => $share->getPassword() !== null, ]); if (!$accepted) { diff --git a/lib/private/updater.php b/lib/private/updater.php index 78457ba3a80..4f74481562b 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -324,9 +324,6 @@ class Updater extends BasicEmitter { if ($this->updateStepEnabled) { $this->doCoreUpgrade(); - // install new shipped apps on upgrade - OC_Installer::installShippedApps(); - // update all shipped apps $disabledApps = $this->checkAppsRequirements(); $this->doAppUpgrade(); @@ -334,6 +331,9 @@ class Updater extends BasicEmitter { // upgrade appstore apps $this->upgradeAppStoreApps($disabledApps); + // install new shipped apps on upgrade + OC_App::loadApps('authentication'); + OC_Installer::installShippedApps(); // post-upgrade repairs $repair = new Repair(Repair::getRepairSteps()); |