From 3e2d4c1bc1cb7c9d8e93848cfdc23491fd4e85f7 Mon Sep 17 00:00:00 2001 From: hkjolhede Date: Fri, 15 Nov 2013 21:10:09 +0100 Subject: [PATCH 1/8] Fixed error-checking error in sftp.php --- apps/files_external/lib/sftp.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php index fb1ecd54635..7c5aed5aa06 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/sftp.php @@ -94,15 +94,17 @@ class SFTP extends \OC\Files\Storage\Common { private function writeHostKeys($keys) { try { $keyPath = $this->hostKeysPath(); - $fp = fopen($keyPath, 'w'); - foreach ($keys as $host => $key) { - fwrite($fp, $host . '::' . $key . "\n"); + if ($keyPath && file_exists($keyPath)) { + $fp = fopen($keyPath, 'w'); + foreach ($keys as $host => $key) { + fwrite($fp, $host . '::' . $key . "\n"); + } + fclose($fp); + return true; } - fclose($fp); - return true; } catch (\Exception $e) { - return false; } + return false; } private function readHostKeys() { From 0c24c7c4203071542d1f1acc447bb6c6b18148db Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 20 Nov 2013 11:02:22 +0100 Subject: [PATCH 2/8] only check if the key file exists to decide if it is an encrypted file or not. This solves problems with external storage which doesn't support fseek --- apps/files_encryption/lib/keymanager.php | 3 +-- apps/files_encryption/lib/stream.php | 2 +- apps/files_encryption/lib/util.php | 23 ++++++++--------------- apps/files_encryption/tests/crypt.php | 14 +++++++------- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 6dadd12a62e..3427e8a963a 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -172,14 +172,13 @@ class Keymanager { /** * @brief retrieve keyfile for an encrypted file * @param \OC_FilesystemView $view - * @param $userId * @param $filePath * @internal param \OCA\Encryption\file $string name * @return string file key or false * @note The keyfile returned is asymmetrically encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getFileKey(\OC_FilesystemView $view, $userId, $filePath) { + public static function getFileKey(\OC_FilesystemView $view, $filePath) { $util = new Util($view, \OCP\User::getUser()); diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 1738955d1aa..206e3469023 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -250,7 +250,7 @@ class Stream { // Fetch and decrypt keyfile // Fetch existing keyfile - $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath); + $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->relPath); // If a keyfile already exists if ($this->encKeyfile) { diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index f9beb9de670..4f27c2b00fb 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -367,7 +367,7 @@ class Util { // scanning every file like this // will eat server resources :( if ( - Keymanager::getFileKey($this->view, $this->userId, $relPath) + Keymanager::getFileKey($this->view, $relPath) && $isEncryptedPath ) { @@ -472,22 +472,15 @@ class Util { */ public function isEncryptedPath($path) { - // Disable encryption proxy so data retrieved is in its - // original form - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; + $relPath = Helper::stripUserFilesPath($path); - // we only need 24 byte from the last chunk - $data = ''; - $handle = $this->view->fopen($path, 'r'); - if (is_resource($handle) && !fseek($handle, -24, SEEK_END)) { - $data = fgets($handle); + $fileKey = Keymanager::getFileKey($this->view, $relPath); + + if ($fileKey === false) { + return false; } - // re-enable proxy - \OC_FileProxy::$enabled = $proxyStatus; - - return Crypt::isCatfileContent($data); + return true; } @@ -1059,7 +1052,7 @@ class Util { private function decryptKeyfile($filePath, $privateKey) { // Get the encrypted keyfile - $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath); + $encKeyfile = Keymanager::getFileKey($this->view, $filePath); // The file has a shareKey and must use it for decryption $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath); diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php index 5146613e252..9c32ee06453 100755 --- a/apps/files_encryption/tests/crypt.php +++ b/apps/files_encryption/tests/crypt.php @@ -176,7 +176,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $this->assertNotEquals($this->dataShort, $retreivedCryptedFile); // Get the encrypted keyfile - $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename); + $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $filename); // Attempt to fetch the user's shareKey $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename); @@ -244,13 +244,13 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { $i = 0; while ($i < count($r)-1) { $e[] = $r[$i] . $r[$i+1]; - $i = $i + 2; + $i = $i + 2; } //print_r($e); // Get the encrypted keyfile - $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename); + $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $filename); // Attempt to fetch the user's shareKey $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename); @@ -387,7 +387,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @brief test decryption using legacy blowfish method */ function testLegacyDecryptShort() { - + $crypted = $this->legacyEncrypt($this->dataShort, $this->pass); $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass); @@ -401,7 +401,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { * @brief test decryption using legacy blowfish method */ function testLegacyDecryptLong() { - + $crypted = $this->legacyEncrypt($this->dataLong, $this->pass); $decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass); @@ -653,8 +653,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase { // tear down $view->unlink($filename); } - - + + /** * @brief encryption using legacy blowfish method * @param $data string data to encrypt From f3e2a63712e3306c5bb1cad1921da4a3ff542474 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 20 Nov 2013 12:34:23 +0100 Subject: [PATCH 3/8] check if it is a cached file or a version to resolve the correct path to the file key --- apps/files_encryption/lib/util.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 4f27c2b00fb..b208a808bac 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -472,7 +472,11 @@ class Util { */ public function isEncryptedPath($path) { - $relPath = Helper::stripUserFilesPath($path); + $relPath = Helper::getPathToRealFile($path); + + if ($relPath === false) { + $relPath = Helper::stripUserFilesPath($path); + } $fileKey = Keymanager::getFileKey($this->view, $relPath); From a0d570b4cc22cb344921147a511b071ebce24c22 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 20 Nov 2013 15:25:29 +0100 Subject: [PATCH 4/8] Change default mimetype detection for storage backends to only use filename --- lib/private/files/storage/common.php | 26 ++++++----------------- lib/private/files/storage/commontest.php | 2 +- lib/private/files/storage/local.php | 8 ------- lib/private/files/storage/mappedlocal.php | 8 ------- 4 files changed, 7 insertions(+), 37 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 3943d667c35..f99bbc9ae5e 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -142,7 +142,7 @@ abstract class Common implements \OC\Files\Storage\Storage { return false; } else { $directoryHandle = $this->opendir($directory); - if(is_resource($directoryHandle)) { + if (is_resource($directoryHandle)) { while (($contents = readdir($directoryHandle)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($contents)) { $path = $directory . '/' . $contents; @@ -165,27 +165,13 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function getMimeType($path) { - if (!$this->file_exists($path)) { - return false; - } if ($this->is_dir($path)) { return 'httpd/unix-directory'; - } - $source = $this->fopen($path, 'r'); - if (!$source) { + } elseif ($this->file_exists($path)) { + return \OC_Helper::getFileNameMimeType($path); + } else { return false; } - $head = fread($source, 8192); //8kb should suffice to determine a mimetype - if ($pos = strrpos($path, '.')) { - $extension = substr($path, $pos); - } else { - $extension = ''; - } - $tmpFile = \OC_Helper::tmpFile($extension); - file_put_contents($tmpFile, $head); - $mime = \OC_Helper::getMimeType($tmpFile); - unlink($tmpFile); - return $mime; } public function hash($type, $path, $raw = false) { @@ -227,7 +213,7 @@ abstract class Common implements \OC\Files\Storage\Storage { private function addLocalFolder($path, $target) { $dh = $this->opendir($path); - if(is_resource($dh)) { + if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { if ($file !== '.' and $file !== '..') { if ($this->is_dir($path . '/' . $file)) { @@ -298,7 +284,7 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->watcher; } - public function getStorageCache(){ + public function getStorageCache() { if (!isset($this->storageCache)) { $this->storageCache = new \OC\Files\Cache\Storage($this); } diff --git a/lib/private/files/storage/commontest.php b/lib/private/files/storage/commontest.php index c3f1eb31955..2394b14a82f 100644 --- a/lib/private/files/storage/commontest.php +++ b/lib/private/files/storage/commontest.php @@ -54,7 +54,7 @@ class CommonTest extends \OC\Files\Storage\Common{ return $this->storage->stat($path); } public function filetype($path) { - return $this->storage->filetype($path); + return @$this->storage->filetype($path); } public function isReadable($path) { return $this->storage->isReadable($path); diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index 5209fabc30a..02e8df4af4e 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -203,14 +203,6 @@ if (\OC_Util::runningOnWindows()) { return $return; } - public function getMimeType($path) { - if ($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->datadir . $path); - } else { - return false; - } - } - private function delTree($dir) { $dirRelative = $dir; $dir = $this->datadir . $dir; diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index ba5ac4191c5..6c37d445867 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -210,14 +210,6 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $return; } - public function getMimeType($path) { - if($this->isReadable($path)) { - return \OC_Helper::getMimeType($this->buildPath($path)); - }else{ - return false; - } - } - private function delTree($dir, $isLogicPath=true) { $dirRelative=$dir; if ($isLogicPath) { From 51a8172868c1d6763041b12bfaa9cd2f1cbe8350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Wed, 20 Nov 2013 16:14:08 +0100 Subject: [PATCH 5/8] always get the right node for the given file path --- lib/private/connector/sabre/filesplugin.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/private/connector/sabre/filesplugin.php b/lib/private/connector/sabre/filesplugin.php index 89444cb8d18..1c80ebe8044 100644 --- a/lib/private/connector/sabre/filesplugin.php +++ b/lib/private/connector/sabre/filesplugin.php @@ -78,6 +78,8 @@ class OC_Connector_Sabre_FilesPlugin extends Sabre_DAV_ServerPlugin * @throws Sabre_DAV_Exception_BadRequest */ public function sendFileIdHeader($filePath, Sabre_DAV_INode $node = null) { + // we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder + $node = $this->server->tree->getNodeForPath($filePath); if ($node instanceof OC_Connector_Sabre_Node) { $fileId = $node->getFileId(); if (!is_null($fileId)) { From fe440248683fb74d758dd257272efcffb7e3c325 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 20 Nov 2013 16:20:21 +0100 Subject: [PATCH 6/8] Fix for extstorage + encryption where unencrypted size is not kept Fix for external storage with encryption where the unencrypted size is first written in the DB, then set back to zero, causing performance issue because the file needs to be reopened every time to find out the unencrypted size (and potentially needs a full redownload) --- apps/files_encryption/lib/proxy.php | 3 +++ apps/files_encryption/lib/stream.php | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 54c3b9caa15..a8c74bd9dd4 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -349,7 +349,10 @@ class Proxy extends \OC_FileProxy { $fileInfo = false; // get file info from database/cache if not .part file if (!Helper::isPartialFilePath($path)) { + $proxyState = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); + \OC_FileProxy::$enabled = $proxyState; } // if file is encrypted return real file size diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 1738955d1aa..1f4f14d7fe5 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -491,7 +491,8 @@ class Stream { if ( $this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && - $this->size > 0 + $this->size > 0 && + $this->unencryptedSize > 0 ) { // only write keyfiles if it was a new file From e26500045fd9f0f102398fabd5e44497618f8b03 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Wed, 20 Nov 2013 18:59:02 +0100 Subject: [PATCH 7/8] Fixed move operation to pass the whole URL as expected The MOVE and COPY spec expect the "Destination" header to receive the full URL, not only the root. Fixes #5942 --- apps/files_external/lib/webdav.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 66920fc9f64..9ee7f555285 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -268,7 +268,7 @@ class DAV extends \OC\Files\Storage\Common{ public function rename($path1, $path2) { $this->init(); $path1=$this->cleanPath($path1); - $path2=$this->root.$this->cleanPath($path2); + $path2=$this->createBaseUri().$this->cleanPath($path2); try { $this->client->request('MOVE', $path1, null, array('Destination'=>$path2)); return true; @@ -280,7 +280,7 @@ class DAV extends \OC\Files\Storage\Common{ public function copy($path1, $path2) { $this->init(); $path1=$this->cleanPath($path1); - $path2=$this->root.$this->cleanPath($path2); + $path2=$this->createBaseUri().$this->cleanPath($path2); try { $this->client->request('COPY', $path1, null, array('Destination'=>$path2)); return true; From c2ccf4a6b3398ffe137f9eafdda55cc695ad0722 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Wed, 20 Nov 2013 19:30:30 +0100 Subject: [PATCH 8/8] beta 5 is here --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 9b04bd244fb..2e3b8f1f904 100644 --- a/version.php +++ b/version.php @@ -1,10 +1,10 @@