]> source.dussan.org Git - nextcloud-server.git/commitdiff
fixed problems with file_get_contents and file_put_contents this problem was related...
authorFlorin Peter <github@florin-peter.de>
Wed, 29 May 2013 23:13:22 +0000 (01:13 +0200)
committerFlorin Peter <github@florin-peter.de>
Fri, 31 May 2013 10:28:22 +0000 (12:28 +0200)
apps/files_encryption/lib/helper.php
apps/files_encryption/lib/proxy.php
apps/files_encryption/lib/util.php

index 1b3e5b1a6425a66ca27c3ae0878dbea33c3b7c45..e078ab35541154fee450f6840dde17ba607e4e93 100755 (executable)
@@ -186,4 +186,18 @@ class Helper {
                        return false;
                }
        }
+
+       /**
+        * @brief Format a path to be relative to the /user/files/ directory
+        * @param string $path the absolute path
+        * @return string e.g. turns '/admin/files/test.txt' into 'test.txt'
+        */
+       public static function stripUserFilesPath($path) {
+               $trimmed = ltrim($path, '/');
+               $split = explode('/', $trimmed);
+               $sliced = array_slice($split, 2);
+               $relPath = implode('/', $sliced);
+
+               return $relPath;
+       }
 }
\ No newline at end of file
index 737b75ca56a46b3b7cb6efddaf832ebe481ab816..5e3c567413388dec58395933cdbdae3f31c0ad6c 100644 (file)
@@ -104,78 +104,40 @@ class Proxy extends \OC_FileProxy {
 
                if (self::shouldEncrypt($path)) {
 
-                       // Stream put contents should have been converted to fopen
                        if (!is_resource($data)) {
 
-                               $userId = \OCP\USER::getUser();
+                               // get root view
                                $view = new \OC_FilesystemView('/');
-                               $util = new Util($view, $userId);
-                               $session = new \OCA\Encryption\Session($view);
-                               $privateKey = $session->getPrivateKey();
-                               $filePath = $util->stripUserFilesPath($path);
-                               // Set the filesize for userland, before encrypting
-                               $size = strlen($data);
 
-                               // Disable encryption proxy to prevent recursive calls
-                               $proxyStatus = \OC_FileProxy::$enabled;
-                               \OC_FileProxy::$enabled = false;
+                               // get relative path
+                               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
-                               // Check if there is an existing key we can reuse
-                               if ($encKeyfile = Keymanager::getFileKey($view, $userId, $filePath)) {
-
-                                       // Fetch shareKey
-                                       $shareKey = Keymanager::getShareKey($view, $userId, $filePath);
-
-                                       // Decrypt the keyfile
-                                       $plainKey = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
-
-                               } else {
-
-                                       // Make a new key
-                                       $plainKey = Crypt::generateKey();
-
-                               }
-
-                               // Encrypt data
-                               $encData = Crypt::symmetricEncryptFileContent($data, $plainKey);
-
-                               $sharingEnabled = \OCP\Share::isEnabled();
-
-                               // if file exists try to get sharing users
-                               if ($view->file_exists($path)) {
-                                       $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $filePath, $userId);
-                               } else {
-                                       $uniqueUserIds[] = $userId;
+                               if (!isset($relativePath)) {
+                                       return true;
                                }
 
-                               // Fetch public keys for all users who will share the file
-                               $publicKeys = Keymanager::getPublicKeys($view, $uniqueUserIds);
+                               $handle = fopen('crypt://' . $relativePath . '.part', 'w');
+                               if (is_resource($handle)) {
 
-                               // Encrypt plain keyfile to multiple sharefiles
-                               $multiEncrypted = Crypt::multiKeyEncrypt($plainKey, $publicKeys);
+                                       // write data to stream
+                                       fwrite($handle, $data);
 
-                               // Save sharekeys to user folders
-                               Keymanager::setShareKeys($view, $filePath, $multiEncrypted['keys']);
+                                       // close stream
+                                       fclose($handle);
 
-                               // Set encrypted keyfile as common varname
-                               $encKey = $multiEncrypted['data'];
+                                       // disable encryption proxy to prevent recursive calls
+                                       $proxyStatus = \OC_FileProxy::$enabled;
+                                       \OC_FileProxy::$enabled = false;
 
-                               // Save keyfile for newly encrypted file in parallel directory tree
-                               Keymanager::setFileKey($view, $filePath, $userId, $encKey);
+                                       // get encrypted content
+                                       $data = $view->file_get_contents($path . '.part');
 
-                               // Replace plain content with encrypted content by reference
-                               $data = $encData;
-
-                               // Update the file cache with file info
-                               \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;
+                                       // remove our temp file
+                                       $view->unlink($path . '.part');
 
+                                       // re-enable proxy - our work is done
+                                       \OC_FileProxy::$enabled = $proxyStatus;
+                               }
                        }
                }
 
@@ -189,15 +151,11 @@ class Proxy extends \OC_FileProxy {
         */
        public function postFile_get_contents($path, $data) {
 
-               $userId = \OCP\USER::getUser();
+               $plainData = null;
                $view = new \OC_FilesystemView('/');
-               $util = new Util($view, $userId);
 
-               $relPath = $util->stripUserFilesPath($path);
-
-               // Disable encryption proxy to prevent recursive calls
-               $proxyStatus = \OC_FileProxy::$enabled;
-               \OC_FileProxy::$enabled = false;
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
                // init session
                $session = new \OCA\Encryption\Session($view);
@@ -208,28 +166,27 @@ class Proxy extends \OC_FileProxy {
                        && Crypt::isCatfileContent($data)
                ) {
 
-                       $privateKey = $session->getPrivateKey($userId);
-
-                       // Get the encrypted keyfile
-                       $encKeyfile = Keymanager::getFileKey($view, $userId, $relPath);
-
-                       // Attempt to fetch the user's shareKey
-                       $shareKey = Keymanager::getShareKey($view, $userId, $relPath);
-
-                       // Decrypt keyfile with shareKey
-                       $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+                       $handle = fopen('crypt://' . $relativePath, 'r');
 
-                       $plainData = Crypt::symmetricDecryptFileContent($data, $plainKeyfile);
+                       if (is_resource($handle)) {
+                               while (($plainDataChunk = fgets($handle, 8192)) !== false) {
+                                       $plainData .= $plainDataChunk;
+                               }
+                       }
 
                } elseif (
                        Crypt::mode() == 'server'
                        && isset($_SESSION['legacyenckey'])
                        && Crypt::isEncryptedMeta($path)
                ) {
+                       // Disable encryption proxy to prevent recursive calls
+                       $proxyStatus = \OC_FileProxy::$enabled;
+                       \OC_FileProxy::$enabled = false;
+
                        $plainData = Crypt::legacyBlockDecrypt($data, $session->getLegacyKey());
-               }
 
-               \OC_FileProxy::$enabled = $proxyStatus;
+                       \OC_FileProxy::$enabled = $proxyStatus;
+               }
 
                if (!isset($plainData)) {
 
@@ -261,10 +218,10 @@ class Proxy extends \OC_FileProxy {
 
                $util = new Util($view, $userId);
 
-               // Format path to be relative to user files dir
-               $relPath = $util->stripUserFilesPath($path);
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
-               list($owner, $ownerPath) = $util->getUidAndFilename($relPath);
+               list($owner, $ownerPath) = $util->getUidAndFilename($relativePath);
 
                // Delete keyfile & shareKey so it isn't orphaned
                if (!Keymanager::deleteFileKey($view, $owner, $ownerPath)) {
@@ -305,12 +262,14 @@ class Proxy extends \OC_FileProxy {
 
                }
 
-               // Reformat path for use with OC_FSV
-               $path_split = explode('/', $path);
-               $path_f = implode('/', array_slice($path_split, 3));
+               // split the path parts
+               $pathParts = explode('/', $path);
+
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
                // FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted
-               if (isset($path_split) && $path_split[2] === 'cache') {
+               if (isset($pathParts[2]) && $pathParts[2] === 'cache') {
                        return $result;
                }
 
@@ -335,14 +294,14 @@ class Proxy extends \OC_FileProxy {
 
                        // Open the file using the crypto stream wrapper 
                        // protocol and let it do the decryption work instead
-                       $result = fopen('crypt://' . $path_f, $meta['mode']);
+                       $result = fopen('crypt://' . $relativePath, $meta['mode']);
 
                } elseif (
                        self::shouldEncrypt($path)
                        and $meta ['mode'] !== 'r'
                                and $meta['mode'] !== 'rb'
                ) {
-                       $result = fopen('crypt://' . $path_f, $meta['mode']);
+                       $result = fopen('crypt://' . $relativePath, $meta['mode']);
                }
 
                // Re-enable the proxy
@@ -390,12 +349,11 @@ class Proxy extends \OC_FileProxy {
                        return $size;
                }
 
-               // Reformat path for use with OC_FSV
-               $path_split = explode('/', $path);
-               $path_f = implode('/', array_slice($path_split, 3));
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
                // if path is empty we cannot resolve anything
-               if (empty($path_f)) {
+               if (empty($relativePath)) {
                        return $size;
                }
 
@@ -424,7 +382,7 @@ class Proxy extends \OC_FileProxy {
                                $fileInfo['unencrypted_size'] = $size;
 
                                // put file info if not .part file
-                               if (!Keymanager::isPartialFilePath($path_f)) {
+                               if (!Keymanager::isPartialFilePath($relativePath)) {
                                        $view->putFileInfo($path, $fileInfo);
                                }
                        }
@@ -447,21 +405,23 @@ class Proxy extends \OC_FileProxy {
                $userId = \OCP\User::getUser();
                $util = new Util($view, $userId);
 
-               // Reformat path for use with OC_FSV
-               $path_split = explode('/', $path);
-               $path_f = implode('/', array_slice($path_split, 3));
+               // split the path parts
+               $pathParts = explode('/', $path);
+
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
                // only if file is on 'files' folder fix file size and sharing
-               if (isset($path_split) && $path_split[2] === 'files' && $util->fixFileSize($path)) {
+               if (isset($pathParts[2]) && $pathParts[2] === 'files' && $util->fixFileSize($path)) {
 
                        // get sharing app state
                        $sharingEnabled = \OCP\Share::isEnabled();
 
                        // get users
-                       $usersSharing = $util->getSharingUsersArray($sharingEnabled, $path_f);
+                       $usersSharing = $util->getSharingUsersArray($sharingEnabled, $relativePath);
 
                        // update sharing-keys
-                       $util->setSharedFileKeyfiles($session, $usersSharing, $path_f);
+                       $util->setSharedFileKeyfiles($session, $usersSharing, $relativePath);
                }
 
                \OC_FileProxy::$enabled = $proxyStatus;
index 0c1421a471b10d75635ef8659ba04d6d90ac9bb2..04bd4dc8aca5711678bbbef1d0c7b22ff6885de2 100644 (file)
@@ -188,7 +188,9 @@ class Util {
 
        /**
         * @brief Sets up user folders and keys for serverside encryption
-        * @param string $passphrase passphrase to encrypt server-stored private key with
+        *
+        * @param string $passphrase to encrypt server-stored private key with
+        * @return bool
         */
        public function setupServerSide($passphrase = null) {
 
@@ -403,7 +405,7 @@ class Util {
                                ) {
 
                                        $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file);
-                                       $relPath = $this->stripUserFilesPath($filePath);
+                                       $relPath = \OCA\Encryption\Helper::stripUserFilesPath($filePath);
 
                                        // If the path is a directory, search 
                                        // its contents
@@ -528,7 +530,7 @@ class Util {
 
        /**
         * @brief Check if a given path identifies an encrypted file
-        * @param $path
+        * @param string $path
         * @return boolean
         */
        public function isEncryptedPath($path) {
@@ -565,11 +567,13 @@ class Util {
                $proxyStatus = \OC_FileProxy::$enabled;
                \OC_FileProxy::$enabled = false;
 
-               // Reformat path for use with OC_FSV
-               $pathSplit = explode('/', $path);
-               $pathRelative = implode('/', array_slice($pathSplit, 3));
+               // split the path parts
+               $pathParts = explode('/', $path);
+
+               // get relative path
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
-               if (isset($pathSplit[2]) && $pathSplit[2] === 'files' && $this->view->file_exists($path) && $this->isEncryptedPath($path)) {
+               if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path) && $this->isEncryptedPath($path)) {
 
                        // get the size from filesystem
                        $fullPath = $this->view->getLocalFile($path);
@@ -579,7 +583,7 @@ class Util {
                        $lastChunkNr = floor($size / 8192);
 
                        // open stream
-                       $stream = fopen('crypt://' . $pathRelative, "r");
+                       $stream = fopen('crypt://' . $relativePath, "r");
 
                        if (is_resource($stream)) {
                                // calculate last chunk position
@@ -639,21 +643,7 @@ class Util {
                return $result;
        }
 
-       /**
-        * @brief Format a path to be relative to the /user/files/ directory
-        * @note e.g. turns '/admin/files/test.txt' into 'test.txt'
-        */
-       public function stripUserFilesPath($path) {
-
-               $trimmed = ltrim($path, '/');
-               $split = explode('/', $trimmed);
-               $sliced = array_slice($split, 2);
-               $relPath = implode('/', $sliced);
-
-               return $relPath;
-
-       }
-
+       
        /**
         * @param $path
         * @return bool
@@ -748,7 +738,7 @@ class Util {
                                        $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKeys );
 
                                        $rawPath = $legacyFile['path'];
-                                       $relPath = $this->stripUserFilesPath($rawPath);
+                                       $relPath = \OCA\Encryption\Helper::stripUserFilesPath($rawPath);
 
                                        // Save keyfile
                                        Keymanager::setFileKey($this->view, $relPath, $this->userId, $recrypted['filekey']);
@@ -903,6 +893,7 @@ class Util {
         * @param string $filePath
         * @param string $fileOwner
         * @param string $privateKey
+        * @return bool|string
         * @note Checks whether file was encrypted with openssl_seal or
         *       openssl_encrypt, and decrypts accrdingly
         * @note This was used when 2 types of encryption for keyfiles was used,
@@ -1136,6 +1127,7 @@ class Util {
        /**
         * @brief get uid of the owners of the file and the path to the file
         * @param string $path Path of the file to check
+        * @throws \Exception
         * @note $shareFilePath must be relative to data/UID/files. Files
         *       relative to /Shared are also acceptable
         * @return array
@@ -1202,11 +1194,11 @@ class Util {
                $content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath($this->userFilesDir . '/' . $dir));
 
                // handling for re shared folders
-               $path_split = explode('/', $dir);
+               $pathSplit = explode('/', $dir);
 
                foreach ($content as $c) {
 
-                       $sharedPart = $path_split[sizeof($path_split) - 1];
+                       $sharedPart = $pathSplit[sizeof($pathSplit) - 1];
                        $targetPathSplit = array_reverse(explode('/', $c['path']));
 
                        $path = '';
@@ -1547,8 +1539,7 @@ class Util {
                $path = \OC\Files\Filesystem::normalizePath($mountPoint.'/'.$internalPath);
 
                // reformat the path to be relative e.g. /user/files/folder becomes /folder/
-               $pathSplit = explode( '/', $path );
-               $relativePath = implode( '/', array_slice( $pathSplit, 3 ) );
+               $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
 
                return $relativePath;
        }