summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/private/app.php2
-rw-r--r--lib/private/files/storage/dav.php6
-rw-r--r--lib/private/files/storage/wrapper/encryption.php132
-rw-r--r--lib/private/share/hooks.php17
-rw-r--r--lib/private/share20/manager.php2
-rw-r--r--lib/private/updater.php6
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());