From 9ca9a22c6a6495e657290195c97282aee8976282 Mon Sep 17 00:00:00 2001 From: Florin Peter Date: Wed, 22 May 2013 00:53:07 +0200 Subject: [PATCH] fixed finding encrypted files in subfolders and removed unused code --- apps/files_encryption/lib/keymanager.php | 58 +----------- apps/files_encryption/lib/proxy.php | 50 +++++----- apps/files_encryption/lib/stream.php | 113 +++++++---------------- apps/files_encryption/lib/util.php | 40 +------- 4 files changed, 61 insertions(+), 200 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 542b1cf2876..ddd8f0ad6e2 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -326,44 +326,6 @@ class Keymanager } - /** - * @brief store private keys from the user - * - * @param string $privatekey - * @param string $publickey - * @return bool true/false - */ - public static function setUserKeys($privatekey, $publickey) - { - - return (self::setPrivateKey($privatekey) && self::setPublicKey($publickey)); - - } - - /** - * @brief store public key of the user - * - * @param string $key - * @return bool true/false - */ - public static function setPublicKey($key) - { - - $view = new \OC_FilesystemView('/public-keys'); - - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - if (!$view->file_exists('')) $view->mkdir(''); - - $result = $view->file_put_contents(\OCP\User::getUser() . '.public.key', $key); - - \OC_FileProxy::$enabled = $proxyStatus; - - return $result; - - } - /** * @brief store share key * @@ -538,7 +500,7 @@ class Keymanager list($owner, $filename) = $util->getUidAndFilename($filePath); - $shareKeyPath = '/' . $owner . '/files_encryption/share-keys/' . $filename; + $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename); if ($view->is_dir($shareKeyPath)) { @@ -611,22 +573,4 @@ class Keymanager return $targetPath; } - - /** - * @brief Fetch the legacy encryption key from user files - * @internal param string $login used to locate the legacy key - * @internal param string $passphrase used to decrypt the legacy key - * @return boolean - * - * if the key is left out, the default handeler will be used - */ - public function getLegacyKey() - { - - $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView('/' . $user); - return $view->file_get_contents('encryption.key'); - - } - } \ No newline at end of file diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7419a85e9ba..f29e893f12a 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -170,7 +170,7 @@ class Proxy extends \OC_FileProxy $data = $encData; // Update the file cache with file info - \OC\Files\Filesystem::putFileInfo($filePath, array('encrypted' => true, 'size' => strlen($size), 'unencrypted_size' => $size), ''); + \OC\Files\Filesystem::putFileInfo($filePath, array('encrypted' => true, 'size' => strlen($data), 'unencrypted_size' => $size), ''); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; @@ -189,28 +189,25 @@ class Proxy extends \OC_FileProxy public function postFile_get_contents($path, $data) { - // FIXME: $path for shared files is just /uid/files/Shared/filepath - $userId = \OCP\USER::getUser(); $view = new \OC_FilesystemView('/'); $util = new Util($view, $userId); $relPath = $util->stripUserFilesPath($path); - - // TODO check for existing key file and reuse it if possible to avoid problems with versioning etc. // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; + // init session + $session = new Session($view); + // If data is a catfile if ( Crypt::mode() == 'server' - && Crypt::isCatfileContent($data) // TODO: Do we really need this check? Can't we assume it is properly encrypted? + && Crypt::isCatfileContent($data) ) { - // TODO: use get owner to find correct location of key files for shared files - $session = new Session($view); $privateKey = $session->getPrivateKey($userId); // Get the encrypted keyfile @@ -229,9 +226,7 @@ class Proxy extends \OC_FileProxy && isset($_SESSION['legacyenckey']) && Crypt::isEncryptedMeta($path) ) { - $plainData = Crypt::legacyDecrypt($data, $session->getLegacyKey()); - } \OC_FileProxy::$enabled = $proxyStatus; @@ -292,19 +287,6 @@ class Proxy extends \OC_FileProxy } - /** - * @brief When a file is renamed, rename its keyfile also - * @param $path - * @return bool Result of rename() - * @note This is pre rather than post because using post didn't work - */ - public function postWrite($path) - { - $this->handleFile($path); - - return true; - } - /** * @param $path * @return bool @@ -362,7 +344,6 @@ class Proxy extends \OC_FileProxy // protocol and let it do the decryption work instead $result = fopen('crypt://' . $path_f, $meta['mode']); - } elseif ( self::shouldEncrypt($path) and $meta ['mode'] != 'r' @@ -428,11 +409,28 @@ class Proxy extends \OC_FileProxy */ public function postStat($path, $data) { + $content = ''; + $view = new \OC_FilesystemView('/'); + if($view->file_exists($path)) { + // disable encryption proxy + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + + // we only need 24 byte from the last chunk + $handle = $view->fopen($path, 'r'); + if (!fseek($handle, -24, SEEK_END)) { + $content = fgets($handle); + } + + // re-enable proxy + \OC_FileProxy::$enabled = $proxyStatus; + } + // check if file is encrypted - if (Crypt::isCatfileContent($path)) { + if (Crypt::isCatfileContent($content)) { // get file info from cache - $cached = \OC\Files\Filesystem::getFileInfo($path, ''); + $cached = $view->getFileInfo($path); // set the real file size $data['size'] = $cached['unencrypted_size']; diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 31546a2cc50..b143b62827f 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -50,8 +50,6 @@ namespace OCA\Encryption; */ class Stream { - - public static $sourceStreams = array(); private $plainKey; private $encKeyfiles; @@ -96,57 +94,41 @@ class Stream // rawPath is relative to the data directory $this->rawPath = $util->getUserFilesDir() . $this->relPath; + // Disable fileproxies so we can get the file size and open the source file without recursive encryption + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + if ( - dirname($this->rawPath) == 'streams' - and isset(self::$sourceStreams[basename($this->rawPath)]) + $mode == 'w' + or $mode == 'w+' + or $mode == 'wb' + or $mode == 'wb+' ) { - // Is this just for unit testing purposes? - - $this->handle = self::$sourceStreams[basename($this->rawPath)]['stream']; - - $this->path = self::$sourceStreams[basename($this->rawPath)]['path']; - - $this->size = self::$sourceStreams[basename($this->rawPath)]['size']; + // We're writing a new file so start write counter with 0 bytes + $this->size = 0; + $this->unencryptedSize = 0; } else { - // Disable fileproxies so we can get the file size and open the source file without recursive encryption - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - if ( - $mode == 'w' - or $mode == 'w+' - or $mode == 'wb' - or $mode == 'wb+' - ) { - - // We're writing a new file so start write counter with 0 bytes - $this->size = 0; - $this->unencryptedSize = 0; - - } else { + $this->size = $this->rootView->filesize($this->rawPath, $mode); + } - $this->size = $this->rootView->filesize($this->rawPath, $mode); + $this->handle = $this->rootView->fopen($this->rawPath, $mode); - } + \OC_FileProxy::$enabled = $proxyStatus; - $this->handle = $this->rootView->fopen($this->rawPath, $mode); + if (!is_resource($this->handle)) { - \OC_FileProxy::$enabled = $proxyStatus; + \OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR); - if (!is_resource($this->handle)) { + } else { - \OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR); + $this->meta = stream_get_meta_data($this->handle); - } else { + } - $this->meta = stream_get_meta_data($this->handle); - } - - } return is_resource($this->handle); @@ -165,14 +147,6 @@ class Stream } - /** - * @return int - */ - public function stream_tell() - { - return ftell($this->handle); - } - /** * @param $count * @return bool|string @@ -259,7 +233,6 @@ class Stream // If a keyfile already exists if ($this->encKeyfile) { - $this->setUserProperty(); $session = new Session($this->rootView); @@ -279,23 +252,6 @@ class Stream } - public function setUserProperty() - { - - // Only get the user again if it isn't already set - if (empty($this->userId)) { - - // TODO: Move this user call out of here - it belongs - // elsewhere - $this->userId = \OCP\User::getUser(); - - } - - // TODO: Add a method for getting the user in case OCP\User:: - // getUser() doesn't work (can that scenario ever occur?) - - } - /** * @brief Handle plain data from the stream, and write it in 8192 byte blocks * @param string $data data to be written to disk @@ -318,16 +274,10 @@ class Stream // Get the length of the unencrypted data that we are handling $length = strlen($data); - // So far this round, no data has been written - $written = 0; - - // Find out where we are up to in the writing of data to the + // Find out where we are up to in the writing of data to the // file $pointer = ftell($this->handle); - // Make sure the userId is set - $this->setUserProperty(); - // Get / generate the keyfile for the file we're handling // If we're writing a new file (not overwriting an existing // one), save the newly generated keyfile @@ -337,7 +287,6 @@ class Stream } - // If extra data is left over from the last round, make sure it // is integrated into the next 6126 / 8192 block if ($this->writeCache) { @@ -351,17 +300,16 @@ class Stream } - // While there still remains somed data to be processed & written while (strlen($data) > 0) { // Remaining length for this iteration, not of the // entire file (may be greater than 8192 bytes) - $remainingLength = strlen( $data ); + $remainingLength = strlen($data); // If data remaining to be written is less than the // size of 1 6126 byte block - if (strlen($data) < 6126) { + if ($remainingLength < 6126) { // Set writeCache to contents of $data // The writeCache will be carried over to the @@ -388,9 +336,7 @@ class Stream // being handled totals more than 6126 bytes fwrite($this->handle, $encrypted); - $writtenLen = strlen($encrypted); - - // Remove the chunk we just processed from + // Remove the chunk we just processed from // $data, leaving only unprocessed data in $data // var, for handling on the next round $data = substr($data, 6126); @@ -416,16 +362,19 @@ class Stream */ public function stream_set_option($option, $arg1, $arg2) { + $return = false; switch ($option) { case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->handle, $arg1); + $return = stream_set_blocking($this->handle, $arg1); break; case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->handle, $arg1, $arg2); + $return = stream_set_timeout($this->handle, $arg1, $arg2); break; case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->handle, $arg1, $arg2); + $return = stream_set_write_buffer($this->handle, $arg1); } + + return $return; } /** @@ -441,7 +390,7 @@ class Stream */ public function stream_lock($mode) { - flock($this->handle, $mode); + return flock($this->handle, $mode); } /** diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 8147982d483..1f4609ae2f6 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -367,14 +367,16 @@ class Util * @note $directory needs to be a path relative to OC data dir. e.g. * /admin/files NOT /backup OR /home/www/oc/data/admin/files */ - public function findEncFiles($directory) + public function findEncFiles($directory, &$found = false) { // Disable proxy - we don't want files to be decrypted before // we handle them \OC_FileProxy::$enabled = false; - $found = array('plain' => array(), 'encrypted' => array(), 'legacy' => array()); + if($found == false) { + $found = array('plain' => array(), 'encrypted' => array(), 'legacy' => array()); + } if ( $this->view->is_dir($directory) @@ -395,7 +397,7 @@ class Util // its contents if ($this->view->is_dir($filePath)) { - $this->findEncFiles($filePath); + $this->findEncFiles($filePath, $found); // If the path is a file, determine // its encryption status @@ -636,38 +638,6 @@ class Util } - /** - * @brief Format a path to be relative to the /user directory - * @note e.g. turns '/admin/files/test.txt' into 'files/test.txt' - */ - public function stripFilesPath($path) - { - - $trimmed = ltrim($path, '/'); - $split = explode('/', $trimmed); - $sliced = array_slice($split, 1); - $relPath = implode('/', $sliced); - - return $relPath; - - } - - /** - * @brief Format a shared path to be relative to the /user/files/ directory - * @note Expects a path like /uid/files/Shared/filepath - */ - public function stripSharedFilePath($path) - { - - $trimmed = ltrim($path, '/'); - $split = explode('/', $trimmed); - $sliced = array_slice($split, 3); - $relPath = implode('/', $sliced); - - return $relPath; - - } - /** * @param $path * @return bool -- 2.39.5