From 6b47da10bea66d7a925de2850919b503201558be Mon Sep 17 00:00:00 2001 From: Florin Peter Date: Mon, 22 Apr 2013 04:40:49 +0200 Subject: [PATCH] improved rename and file size support fix missing user_id on write --- apps/files_encryption/lib/proxy.php | 174 +++++++++++++++------------ apps/files_encryption/lib/stream.php | 31 ++--- 2 files changed, 115 insertions(+), 90 deletions(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 67c93694e3..505fad440d 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -288,38 +288,54 @@ class Proxy extends \OC_FileProxy { * @return bool Result of rename() * @note This is pre rather than post because using post didn't work */ - public function preRename( $oldPath, $newPath ) { - - // Disable encryption proxy to prevent recursive calls - \OC_FileProxy::$enabled = false; - - $view = new \OC_FilesystemView( '/' ); - - $userId = \OCP\USER::getUser(); - - // Format paths to be relative to user files dir - $oldTrimmed = ltrim( $oldPath, '/' ); - $oldSplit = explode( '/', $oldTrimmed ); - $oldSliced = array_slice( $oldSplit, 2 ); - $oldRelPath = implode( '/', $oldSliced ); - $oldKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $oldRelPath . '.key'; - - $newTrimmed = ltrim( $newPath, '/' ); - $newSplit = explode( '/', $newTrimmed ); - $newSliced = array_slice( $newSplit, 2 ); - $newRelPath = implode( '/', $newSliced ); - $newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath . '.key'; - - // Rename keyfile so it isn't orphaned - $result = $view->rename( $oldKeyfilePath, $newKeyfilePath ); - - \OC_FileProxy::$enabled = true; - - return $result; - - } - - public function postFopen( $path, &$result ){ + public function preRename( $oldPath, $newPath ) + { + + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; + + $view = new \OC_FilesystemView('/'); + + $userId = \OCP\USER::getUser(); + + // Format paths to be relative to user files dir + $oldTrimmed = ltrim($oldPath, '/'); + $oldSplit = explode('/', $oldTrimmed); + $oldSliced = array_slice($oldSplit, 2); + $oldRelPath = implode('/', $oldSliced); + $oldKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $oldRelPath; + + + $newTrimmed = ltrim($newPath, '/'); + $newSplit = explode('/', $newTrimmed); + $newSliced = array_slice($newSplit, 2); + $newRelPath = implode('/', $newSliced); + $newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath; + + // add key ext if this is not an folder + if (!$view->is_dir($oldKeyfilePath)) { + $oldKeyfilePath .= '.key'; + $newKeyfilePath .= '.key'; + } else { + // handle share-keys folders + $oldShareKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $oldRelPath; + $newShareKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $newRelPath; + $view->rename($oldShareKeyfilePath, $newShareKeyfilePath); + } + + //TODO add support for share-keys files + //... + + // Rename keyfile so it isn't orphaned + $result = $view->rename($oldKeyfilePath, $newKeyfilePath); + + \OC_FileProxy::$enabled = true; + + return $result; + + } + + public function postFopen( $path, &$result ){ if ( !$result ) { @@ -421,49 +437,55 @@ class Proxy extends \OC_FileProxy { } public function postFileSize( $path, $size ) { - - // Reformat path for use with OC_FSV - $path_split = explode( '/', $path ); - $path_f = implode( '/', array_slice( $path_split, 3 ) ); - - if ( Crypt::isEncryptedMeta( $path_f ) ) { - - // Disable encryption proxy to prevent recursive calls - \OC_FileProxy::$enabled = false; - - // get file info - $cached = \OC\Files\Filesystem::getFileInfo( $path_f, '' ); - - // calculate last chunk nr - $lastChunckNr = floor( $size / 8192); - - // open stream - $result = fopen( 'crypt://'.$path_f, "r" ); - - // calculate last chunk position - $lastChunckPos = ( $lastChunckNr * 8192 ); - - // seek to end - fseek( $result, $lastChunckPos ); - - // get the content of the last chunck - $lastChunkContent = fgets( $result ); - - // calc the real filesize with the size of the last chunk - $realSize = ( ( $lastChunckNr * 6126 ) + strlen( $lastChunkContent ) ); - - // enable proxy - \OC_FileProxy::$enabled = true; - - // set the size - $cached['size'] = $realSize; - - return $cached['size']; - - } else { - - return $size; - - } + + // Reformat path for use with OC_FSV + $path_split = explode('/', $path); + $path_f = implode('/', array_slice($path_split, 3)); + + $view = new \OC_FilesystemView( '/' ); + $userId = \OCP\User::getUser(); + $util = new Util( $view, $userId ); + + if ($util->isEncryptedPath($path)) { + + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; + + // get file info + $cached = \OC\Files\Filesystem::getFileInfo($path_f, ''); + + // calculate last chunk nr + $lastChunckNr = floor($size / 8192); + + // open stream + $result = fopen('crypt://' . $path_f, "r"); + + if(is_resource($result)) { + // calculate last chunk position + $lastChunckPos = ($lastChunckNr * 8192); + + // seek to end + fseek($result, $lastChunckPos); + + // get the content of the last chunck + $lastChunkContent = fgets($result); + + // calc the real file size with the size of the last chunk + $realSize = (($lastChunckNr * 6126) + strlen($lastChunkContent)); + + // set the size + $cached['size'] = $realSize; + } + + // enable proxy + \OC_FileProxy::$enabled = true; + + return $cached['size']; + + } else { + + return $size; + + } } } diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 4b33c200bf..c12fab783b 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -101,6 +101,9 @@ class Stream { } else { + // Disable fileproxies so we can get the file size and open the source file without recursive encryption + \OC_FileProxy::$enabled = false; + if ( $mode == 'w' or $mode == 'w+' @@ -119,9 +122,6 @@ class Stream { } - // Disable fileproxies so we can open the source file without recursive encryption - \OC_FileProxy::$enabled = false; - //$this->handle = fopen( $this->rawPath, $mode ); $this->handle = $this->rootView->fopen( $this->rawPath, $mode ); @@ -240,14 +240,13 @@ class Stream { // Avoid problems with .part file extensions $this->relPath = Keymanager::fixPartialFilePath( $this->relPath ); - + + // Fetch and decrypt keyfile + // Fetch existing keyfile + $this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->relPath ); + // If a keyfile already exists - if ( $this->rootView->file_exists( $this->userId . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->relPath . '.key' ) ) { - - // Fetch and decrypt keyfile - // Fetch existing keyfile - $this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->relPath ); - + if ( $this->encKeyfile ) { $this->setUserProperty(); $session = new Session( $this->rootView ); @@ -338,11 +337,15 @@ class Stream { // Get all users sharing the file $uniqueUserIds = $util->getSharingUsersArray( $sharingEnabled, $this->relPath ); - + + // allways add current user + $uniqueUserIds[] = $this->userId; + array_unique( $uniqueUserIds ); + // Fetch public keys for all sharing users $publicKeys = Keymanager::getPublicKeys( $this->rootView, $uniqueUserIds ); - - // Encrypt enc key for all sharing users + + // Encrypt enc key for all sharing users $this->encKeyfiles = Crypt::multiKeyEncrypt( $this->plainKey, $publicKeys ); $view = new \OC_FilesystemView( '/' ); @@ -429,7 +432,7 @@ class Stream { $encrypted = $this->preWriteEncrypt( $chunk, $this->plainKey ); - trigger_error("\$encrypted = $encrypted"); + //trigger_error("\$encrypted = $encrypted"); // Write the data chunk to disk. This will be // attended to the last data chunk if the file