]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fixed proxy class handing of read / write files
authorSam Tuke <samtuke@owncloud.com>
Wed, 10 Apr 2013 15:37:03 +0000 (17:37 +0200)
committerSam Tuke <samtuke@owncloud.com>
Tue, 16 Apr 2013 11:22:16 +0000 (13:22 +0200)
Various work on other classes

apps/files_encryption/ajax/adminrecovery.php
apps/files_encryption/appinfo/app.php
apps/files_encryption/hooks/hooks.php
apps/files_encryption/js/settings.js
apps/files_encryption/lib/proxy.php
apps/files_encryption/lib/stream.php
apps/files_encryption/lib/util.php
apps/files_encryption/test/proxy.php
apps/files_encryption/test/util.php

index f22114f85147da3f1fc8092ab082f8581b670d8c..cec0cd4ddda7560374e9f955839959b8ed2b0e76 100644 (file)
@@ -15,6 +15,8 @@ use OCA\Encryption;
 \OCP\JSON::checkAppEnabled( 'files_encryption' );
 \OCP\JSON::callCheck();
 
+$return = $doSetup = false;
+
 if ( 
        isset( $_POST['adminEnableRecovery'] ) 
        && $_POST['adminEnableRecovery'] == 1
@@ -47,7 +49,7 @@ if (
                // If the recoveryAdmin UID exists but doesn't have admin rights
                } else {
                
-                       \OCP\JSON::error();
+                       $return = false;
                        
                }
                
@@ -63,10 +65,12 @@ if (
                $util->setupServerSide( $_POST['recoveryPassword'] );
                
                // Store the UID in the DB
-               OC_Appconfig::setValue( 'encryption', 'recoveryAdminUid', $recoveryAdminUid );
+               OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminUid', $recoveryAdminUid );
                
-               \OCP\JSON::success();
+               $return = true;
                
        }
        
-}
\ No newline at end of file
+}
+
+($return) ? OC_JSON::success() : OC_JSON::error();
\ No newline at end of file
index 9747fb20ad6d0240807429f112511d3545a9dae3..c2de9d0b441ec01ad9952dff36a768b9f24360cc 100644 (file)
@@ -24,8 +24,10 @@ OCP\Util::connectHook( 'OCP\Share', 'post_unshareAll', 'OCA\Encryption\Hooks', '
 OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfileFromClient' );
 
 stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' );
-$view = new OC_FilesystemView('/');
-$session = new OCA\Encryption\Session($view);
+
+$view = new OC_FilesystemView( '/' );
+
+$session = new OCA\Encryption\Session( $view );
 
 if ( 
        ! $session->getPrivateKey( \OCP\USER::getUser() )
index 82de80a1cf4c3467347b3eb14c19d8af44addbe6..e65f0945f41115424f6c2c5f4112c0b700da504a 100644 (file)
@@ -63,7 +63,7 @@ class Hooks {
                \r
                $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] );\r
                \r
-               $session = new Session($view);\r
+               $session = new Session( $view );\r
                \r
                $session->setPrivateKey( $privateKey, $params['uid'] );\r
                \r
@@ -116,8 +116,8 @@ class Hooks {
                // is in use (client-side encryption does not have access to \r
                // the necessary keys)\r
                if ( Crypt::mode() == 'server' ) {\r
-                       $view = new \OC_FilesystemView( '/' );\r
-                       $session = new Session($view);\r
+                       \r
+                       $session = new Session();\r
                        \r
                        // Get existing decrypted private key\r
                        $privateKey = $session->getPrivateKey();\r
@@ -189,7 +189,7 @@ class Hooks {
                if ( $params['itemType'] === 'file' ) {\r
                \r
                        $view = new \OC_FilesystemView( '/' );\r
-                       $session = new Session($view);\r
+                       $session = new Session();\r
                        $userId = \OCP\User::getUser();\r
                        $util = new Util( $view, $userId );\r
                        $path = $util->fileIdToPath( $params['itemSource'] );\r
@@ -244,7 +244,7 @@ class Hooks {
                if ( $params['itemType'] === 'file' ) {\r
                \r
                        $view = new \OC_FilesystemView( '/' );\r
-                       $session = new Session($view);\r
+                       $session = new Session();\r
                        $userId = \OCP\User::getUser();\r
                        $util = new Util( $view, $userId );\r
                        $path = $util->fileIdToPath( $params['itemSource'] );\r
index 4f367f880db829b6e408ea5518a778a9db1aded5..9a0bebf2478a8c80980455404aa33fb410b6d375 100644 (file)
@@ -16,11 +16,14 @@ $(document).ready(function(){
        // Trigger ajax on recoveryAdmin status change
        $( 'input:radio[name="adminEnableRecovery"]' ).change( 
                function() {
+                       
+                       var foo = $( this ).val();
+                       
                        $.post( 
-                               '../ajax/adminrecovery.php'
-                               , $( this ).val()
+                               OC.filePath('files_encryption', 'ajax', 'adminrecovery.php')
+                               , { adminEnableRecovery: foo, recoveryPassword: 'password' }
                                ,  function( data ) {
-                                       // TODO: provide user with feedback of outcome
+                                       alert( data );
                                }
                        );
                }
index 7e18ec9b104793220dcbbe5e850398c3e3d58b53..44a2e1aae55dd82a59c56ca1dbf7859eb7f3861c 100644 (file)
@@ -101,7 +101,7 @@ class Proxy extends \OC_FileProxy {
                                $userId = \OCP\USER::getUser();
                                $rootView = new \OC_FilesystemView( '/' );
                                $util = new Util( $rootView, $userId );
-                               $session = new Session($rootView);
+                               $session = new Session( $rootView );
                                $fileOwner = \OC\Files\Filesystem::getOwner( $path );
                                $privateKey = $session->getPrivateKey();
                                $filePath = $util->stripUserFilesPath( $path );
@@ -115,9 +115,16 @@ class Proxy extends \OC_FileProxy {
                                if ( $encKeyfile = Keymanager::getFileKey( $rootView, $fileOwner, $filePath ) ) {
                                
                                        $keyPreExists = true;
-                               
+                                       
+                                       // Fetch shareKey
+                                       $shareKey = Keymanager::getShareKey( $rootView, $userId, $filePath );
+                                       
                                        // Decrypt the keyfile
-                                       $plainKey = $util->decryptUnknownKeyfile( $filePath, $fileOwner, $privateKey );
+                                       $plainKey = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey );
+                                       
+                                       trigger_error("\$shareKey = $shareKey");
+                                       
+                                       trigger_error("\$plainKey = $plainKey");
                                
                                } else {
                                
@@ -170,6 +177,7 @@ class Proxy extends \OC_FileProxy {
                                
                                // Save sharekeys to user folders
                                // TODO: openssl_seal generates new shareKeys (envelope keys) each time data is encrypted, but will data still be decryptable using old shareKeys? If so we don't need to replace the old shareKeys here, we only need to set the new ones
+                               
                                Keymanager::setShareKeys( $rootView, $filePath, $multiEncrypted['keys'] );
                                
                                // Set encrypted keyfile as common varname
@@ -219,15 +227,18 @@ class Proxy extends \OC_FileProxy {
                // If data is a catfile
                if ( 
                        Crypt::mode() == 'server' 
-                       && Crypt::isCatfileContent( $data ) 
+                       && Crypt::isCatfileContent( $data ) // TODO: Do we really need this check? Can't we assume it is properly encrypted?
                ) {
                
-                       // TODO use get owner to find correct location of key files for shared files
-                       $session = new Session($view);
+                       // TODO: use get owner to find correct location of key files for shared files
+                       $session = new Session( $view );
                        $privateKey = $session->getPrivateKey( $userId );
                        
                        // Get the file owner so we can retrieve its keyfile
-                       list($fileOwner, $ownerPath) = $util->getUidAndFilename($relPath);
+//                     list( $fileOwner, $ownerPath ) = $util->getUidAndFilename( $relPath );
+
+                       $fileOwner = \OC\Files\Filesystem::getOwner( $path );
+                       $ownerPath = $util->stripUserFilesPath( $path );  // TODO: Don't trust $path, fetch owner path
 
                        // Get the encrypted keyfile
                        $encKeyfile = Keymanager::getFileKey( $view, $fileOwner, $ownerPath );
@@ -235,27 +246,9 @@ class Proxy extends \OC_FileProxy {
                        // Attempt to fetch the user's shareKey
                        $shareKey = Keymanager::getShareKey( $view, $userId, $relPath );
                        
-                       // Check if key is shared or not
-                       if ( $shareKey ) {
-                               
-                               \OC_FileProxy::$enabled = false;
-                               
-//                             trigger_error("\$encKeyfile = $encKeyfile, \$shareKey = $shareKey, \$privateKey = $privateKey");
-                               
-                               // Decrypt keyfile with shareKey
-                               $plainKeyfile = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey );
-                               
-//                             $plainKeyfile = $encKeyfile;
-                               
-//                             trigger_error("PROXY plainkeyfile = ". var_export($plainKeyfile, 1));
-                       
-                       } else {
-                               
-                               // If key is unshared, decrypt with user private key
-                               $plainKeyfile = Crypt::keyDecrypt( $encKeyfile, $privateKey );
-                       
-                       }
-                       
+                       // Decrypt keyfile with shareKey
+                       $plainKeyfile = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey );
+               
                        $plainData = Crypt::symmetricDecryptFileContent( $data, $plainKeyfile );
                        
 //                     trigger_error("PLAINDATA = ". var_export($plainData, 1));
index d269a5624041d4c9ef7e8f3334c18d09064511a3..7315245fcce1ef306e04d2607d7f3a4894ff23f2 100644 (file)
@@ -236,7 +236,7 @@ class Stream {
                        
                        $this->getUser();
                        
-                       $session = new Session($this->rootView);
+                       $session = new Session( $this->rootView );
                        
                        $privateKey = $session->getPrivateKey( $this->userId );
                        
index 420e3398a8d7442f104961e2e5fa1d5cd0b74657..dc4e37150c5977ae00e37101e7adbc3ab4ee8c4e 100644 (file)
 # Bugs
 # ----
 # Sharing a file to a user without encryption set up will not provide them with access but won't notify the sharer
-# Timeouts on first login due to encryption of very large files
+# Sharing files to other users currently broken (due to merge + ongoing implementation of support for lost password recovery)
+# Timeouts on first login due to encryption of very large files (fix in progress, as a result streaming is currently broken)
+# Sharing all files to admin for recovery purposes still in progress
+# Possibly public links are broken (not tested since last merge of master)
+# getOwner() currently returns false in all circumstances, unsure what code is returning this...
 
 
 # Missing features
 # ----------------
-# Re-use existing keyfiles so they don't need version control (part implemented, stream{} and util{} remain)
 # Make sure user knows if large files weren't encrypted
+# Support for resharing encrypted files
 
 
 # Test
@@ -122,7 +126,8 @@ class Util {
                $this->userId = $userId;
                $this->client = $client;
                $this->userDir =  '/' . $this->userId;
-               $this->userFilesDir =  '/' . $this->userId . '/' . 'files';
+               $this->fileFolderName = 'files';
+               $this->userFilesDir =  '/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
                $this->publicKeyDir =  '/' . 'public-keys';
                $this->encryptionDir =  '/' . $this->userId . '/' . 'files_encryption';
                $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
@@ -690,7 +695,6 @@ class Util {
        
        /**
         * @brief Expand given path to all sub files & folders
-        * @param Session $session
         * @param string $path path which needs to be updated
         * @return array $pathsArray all found file paths
         * @note Paths of directories excluded, only *file* paths are returned
@@ -747,6 +751,8 @@ class Util {
         * @param string $privateKey
         * @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, 
+        *       but now we've switched to exclusively using openssl_seal()
         */
        public function decryptUnknownKeyfile( $filePath, $fileOwner, $privateKey ) {
 
@@ -861,19 +867,55 @@ class Util {
 
        /**
         * @brief get uid of the owners of the file and the path to the file
-        * @param $filename
+        * @param $shareFilePath Path of the file to check 
+        * @note $shareFilePath must be relative to data/UID/files. Files 
+        *       relative to /Shared are also acceptable
         * @return array
         */
-       public function getUidAndFilename($filename) {
-               $uid = \OC\Files\Filesystem::getOwner($filename);
-
-               \OC\Files\Filesystem::initMountPoints($uid);
-               if ( $uid != \OCP\User::getUser() ) {
-                       $info = \OC\Files\Filesystem::getFileInfo($filename);
-                       $ownerView = new \OC\Files\View('/'.$uid.'/files');
-                       $filename = $ownerView->getPath($info['fileid']);
+       public function getUidAndFilename( $shareFilePath ) {
+       
+               $fileOwnerUid = \OC\Files\Filesystem::getOwner( $shareFilePath );
+               
+               // Check that UID is valid
+               if ( ! \OCP\User::userExists( $fileOwnerUid ) ) {
+               
+                       throw new \Exception( 'Could not find owner (UID = "' . var_export( $fileOwnerUid, 1 ) . '") of file "' . $shareFilePath . '"' );
+                       
+               }
+
+               // NOTE: Bah, this dependency should be elsewhere
+               \OC\Files\Filesystem::initMountPoints( $fileOwnerUid );
+               
+               // If the file owner is the currently logged in user
+               if ( $fileOwnerUid == $this->userId ) {
+               
+                       // Assume the path supplied is correct
+                       $filename = $shareFilePath;
+                       
+               } else {
+               
+                       $info = \OC\Files\Filesystem::getFileInfo( $shareFilePath );
+                       $ownerView = new \OC\Files\View( '/' . $fileOwnerUid . '/files' );
+                       
+                       // Fetch real file path from DB
+                       $filename = $ownerView->getPath( $info['fileid'] ); // TODO: Check that this returns a path without including the user data dir
+               
                }
-               return array($uid, $filename);
+               
+               // Make path relative for use by $view
+               $relpath = $fileOwnerUid . '/' . $this->fileFolderName . '/' . $filename;
+               
+               // Check that the filename we're using is working
+               if ( $this->view->file_exists( $relpath ) ) {
+               
+                       return array ( $fileOwnerUid, $relpath );
+                       
+               } else {
+               
+                       throw new \Exception( 'Supplied path could not be resolved "' . $shareFilePath . '"' );
+                       
+               }
+               
        }
 
 }
index 709730f7609ca2464a1faa2c410569b50fa80c19..5a2d851ff7c1019144c132875d94ddc28506ab07 100644 (file)
@@ -52,7 +52,7 @@
 //             $this->userId = 'admin';
 //             $this->pass = 'admin';
 //             
-//             $this->session = new Encryption\Session();
+//             $this->session = new Encryption\Session( $view ); // FIXME: Provide a $view object for use here
 //             
 // $this->session->setPrivateKey( 
 // '-----BEGIN PRIVATE KEY-----
index e2767a2ec39fccb84f6f21b44acdf9ad6e032ea1..3ebc484809b430176a4da5f3d052ee8ad132375e 100755 (executable)
@@ -24,6 +24,8 @@ $loader->register();
 use \Mockery as m;
 use OCA\Encryption;
 
+\OC_User::login( 'admin', 'admin' );
+
 class Test_Enc_Util extends \PHPUnit_Framework_TestCase {
        
        function setUp() {
@@ -184,6 +186,16 @@ class Test_Enc_Util extends \PHPUnit_Framework_TestCase {
                $this->assertTrue( $util->setRecovery( $enabled ) );
                
        }
+       
+       function testGetUidAndFilename() {
+       
+               \OC_User::setUserId( 'admin' );
+               
+               $this->util->getUidAndFilename( 'test1.txt' );
+               
+               
+       
+       }
 
 //     /**
 //      * @brief test decryption using legacy blowfish method