From e9f3c5feea94833d686dbc1b99e01b7a06fdaaed Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Mon, 14 Jan 2013 15:39:04 +0000 Subject: [PATCH 01/31] Added creation of dir for shared file env encryption keys Added comment to use multiKeyEncrypt --- apps/files_encryption/lib/crypt.php | 2 ++ apps/files_encryption/lib/util.php | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index fddc89dae5..642187b910 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -390,6 +390,8 @@ class Crypt { */ public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { + // Set empty vars to be set by openssl by reference + $sealed = ''; $envKeys = array(); if( openssl_seal( $plainContent, $sealed, $envKeys, $publicKeys ) ) { diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index cd46d23108..56e4d572c2 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -96,9 +96,10 @@ class Util { private $view; // OC_FilesystemView object for filesystem operations private $pwd; // User Password private $client; // Client side encryption mode flag - private $publicKeyDir; // Directory containing all public user keys - private $encryptionDir; // Directory containing user's files_encryption - private $keyfilesPath; // Directory containing user's keyfiles + private $publicKeyDir; // Dir containing all public user keys + private $encryptionDir; // Dir containing user's files_encryption + private $keyfilesPath; // Dir containing user's keyfiles + private $shareKeysPath; // Dir containing env keys for shared files private $publicKeyPath; // Path to user's public key private $privateKeyPath; // Path to user's private key @@ -110,6 +111,7 @@ class Util { $this->publicKeyDir = '/' . 'public-keys'; $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; + $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys'; $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key $this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key @@ -159,6 +161,13 @@ class Util { $this->view->mkdir( $this->keyfilesPath ); } + + // Create mirrored share env keys directory + if( !$this->view->file_exists( $this->shareKeysPath ) ) { + + $this->view->mkdir( $this->shareKeysPath ); + + } // Create user keypair if ( From de0ed634f2fb1bb9fbb93f6c0a66882dea42e288 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Mon, 14 Jan 2013 17:05:47 +0000 Subject: [PATCH 02/31] Added two hooks: pre_unshare and pre_unshareAll, useful for files_encryption --- lib/public/share.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/public/share.php b/lib/public/share.php index 8c0cfc16b4..0ff68fe265 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -465,6 +465,13 @@ class Share { null, 1); if ($item) { + // Pass all the vars we have for now, they may be useful + \OC_Hook::emit('OCP\Share', 'pre_unshare', array( + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'shareType' => $shareType, + 'shareWith' => $shareWith, + )); self::delete($item['id']); return true; } @@ -480,6 +487,12 @@ class Share { public static function unshareAll($itemType, $itemSource) { $shares = self::getItemShared($itemType, $itemSource); if ($shares) { + // Pass all the vars we have for now, they may be useful + \OC_Hook::emit('OCP\Share', 'pre_unshareAll', array( + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'shares' => $shares + )); foreach ($shares as $share) { self::delete($share['id']); } From d95fc4e1e33f2e6fe4664d03bd39aa48f27e0ad8 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Mon, 14 Jan 2013 19:07:28 +0000 Subject: [PATCH 03/31] Adding sharing support: added new method in Keymanager setShareKey() Added notes in proxy{} and stream{} pointing to share support --- apps/files_encryption/appinfo/app.php | 16 ++++- apps/files_encryption/hooks/hooks.php | 44 ++++++++++++- apps/files_encryption/lib/keymanager.php | 77 ++++++++++++++--------- apps/files_encryption/lib/proxy.php | 9 ++- apps/files_encryption/lib/stream.php | 13 ++-- apps/files_encryption/test/keymanager.php | 16 +++-- 6 files changed, 125 insertions(+), 50 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 31b430d37a..cc78402d1d 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -10,10 +10,18 @@ OC::$CLASSPATH['OCA\Encryption\Session'] = 'apps/files_encryption/lib/session.ph OC_FileProxy::register( new OCA\Encryption\Proxy() ); +// User-related hooks OCP\Util::connectHook( 'OC_User','post_login', 'OCA\Encryption\Hooks', 'login' ); -OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfile' ); OCP\Util::connectHook( 'OC_User','post_setPassword','OCA\Encryption\Hooks' ,'setPassphrase' ); +// Sharing-related hooks +OCP\Util::connectHook( 'OCP\Share','post_shared','OCA\Encryption\Hooks' ,'postShared' ); +OCP\Util::connectHook( 'OCP\Share','pre_unshare','OCA\Encryption\Hooks' ,'preUnshare' ); +OCP\Util::connectHook( 'OCP\Share','pre_unshareAll','OCA\Encryption\Hooks' ,'preUnshareAll' ); + +// Webdav-related hooks +OCP\Util::connectHook( 'OC_Webdav_Properties', 'update', 'OCA\Encryption\Hooks', 'updateKeyfile' ); + stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' ); $session = new OCA\Encryption\Session(); @@ -24,7 +32,9 @@ if ( && OCA\Encryption\Crypt::mode() == 'server' ) { - // Force the user to re-log in if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled) + // Force the user to re-log in if the encryption key isn't unlocked + // (happens when a user is logged in before the encryption app is + // enabled) OCP\User::logout(); header( "Location: " . OC::$WEBROOT.'/' ); @@ -33,5 +43,5 @@ if ( } -OCP\App::registerAdmin( 'files_encryption', 'settings'); +OCP\App::registerAdmin( 'files_encryption', 'settings' ); OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); \ No newline at end of file diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index c2f9724783..ecceae352b 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -121,8 +121,11 @@ class Hooks { if ( isset( $params['properties']['key'] ) ) { - Keymanager::setFileKey( $params['path'], $params['properties']['key'] ); - + $view = new \OC_FilesystemView( '/' ); + $userId = \OCP\User::getUser(); + + Keymanager::setFileKey( $view, $params['path'], $userId, $params['properties']['key'] ); + } else { \OC_Log::write( @@ -138,6 +141,43 @@ class Hooks { } + /** + * @brief + */ + public static function postShared( $params ) { + + // Delete existing catfile + Keymanager::deleteFileKey( ); + + // Generate new catfile and env keys + Crypt::multiKeyEncrypt( $plainContent, $publicKeys ); + + // Save env keys to user folders + + + } + + /** + * @brief + */ + public static function preUnshare( $params ) { + + // Delete existing catfile + + // Generate new catfile and env keys + + // Save env keys to user folders + } + + /** + * @brief + */ + public static function preUnshareAll( $params ) { + + trigger_error( "preUnshareAll" ); + + } + } ?> \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 706e1c2661..61bc50721e 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -238,7 +238,7 @@ class Keymanager { */ public static function setUserKeys($privatekey, $publickey) { - return (self::setPrivateKey($privatekey) && self::setPublicKey($publickey)); + return ( self::setPrivateKey( $privatekey ) && self::setPublicKey( $publickey ) ); } @@ -262,6 +262,42 @@ class Keymanager { } + /** + * @note 'shareKey' is a more user-friendly name for env_key + */ + public static function setShareKey( \OC_FilesystemView $view, $path, $userId, $shareKey ) { + + $basePath = '/' . $userId . '/files_encryption/share-keys'; + + $shareKeyPath = self::keySetPreparation( $view, $path, $basePath, $userId ); + + return $view->file_put_contents( $basePath . '/' . $shareKeyPath . '.shareKey', $shareKey ); + + } + + /** + * @brief Make preparations to vars and filesystem for saving a keyfile + */ + public static function keySetPreparation( \OC_FilesystemView $view, $path, $basePath, $userId ) { + + $targetPath = ltrim( $path, '/' ); + + $path_parts = pathinfo( $targetPath ); + + // If the file resides within a subdirectory, create it + if ( + isset( $path_parts['dirname'] ) + && ! $view->file_exists( $basePath . $path_parts['dirname'] ) + ) { + + $view->mkdir( $basePath . $path_parts['dirname'] ); + + } + + return $targetPath; + + } + /** * @brief store file encryption key * @@ -271,15 +307,16 @@ class Keymanager { * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - public static function setFileKey( $path, $key, $view = Null, $dbClassName = '\OC_DB') { - - $targetPath = ltrim( $path, '/' ); - $user = \OCP\User::getUser(); + public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) { -// // update $keytarget and $user if key belongs to a file shared by someone else + $basePath = '/' . $userId . '/files_encryption/keyfiles'; + + $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId ); + +// // update $keytarget and $userId if key belongs to a file shared by someone else // $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); // -// $result = $query->execute( array ( '/'.$user.'/files/'.$targetPath, $user ) ); +// $result = $query->execute( array ( '/'.$userId.'/files/'.$targetPath, $userId ) ); // // if ( $row = $result->fetchRow( ) ) { // @@ -287,7 +324,7 @@ class Keymanager { // // $targetPath_parts = explode( '/', $targetPath ); // -// $user = $targetPath_parts[1]; +// $userId = $targetPath_parts[1]; // // $rootview = new \OC_FilesystemView( '/' ); // @@ -299,34 +336,14 @@ class Keymanager { // // } // -// $targetPath = str_replace( '/'.$user.'/files/', '', $targetPath ); +// $targetPath = str_replace( '/'.$userId.'/files/', '', $targetPath ); // // //TODO: check for write permission on shared file once the new sharing API is in place // // } - $path_parts = pathinfo( $targetPath ); - - if ( !$view ) { - - $view = new \OC_FilesystemView( '/' ); - - } - - $view->chroot( '/' . $user . '/files_encryption/keyfiles' ); - - // If the file resides within a subdirectory, create it - if ( - isset( $path_parts['dirname'] ) - && ! $view->file_exists( $path_parts['dirname'] ) - ) { - - $view->mkdir( $path_parts['dirname'] ); - - } - // Save the keyfile in parallel directory - return $view->file_put_contents( '/' . $targetPath . '.key', $key ); + return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 52f47dba29..83c5e21c4b 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -101,6 +101,8 @@ class Proxy extends \OC_FileProxy { // Disable encryption proxy to prevent recursive calls \OC_FileProxy::$enabled = false; + # TODO: Check if file is shared, if so, use multiKeyEncrypt + // Encrypt plain data and fetch key $encrypted = Crypt::keyEncryptKeyfile( $data, Keymanager::getPublicKey( $rootView, $userId ) ); @@ -114,10 +116,11 @@ class Proxy extends \OC_FileProxy { $filePath = '/' . implode( '/', $filePath ); # TODO: make keyfile dir dynamic from app config - $view = new \OC_FilesystemView( '/' . $userId . '/files_encryption/keyfiles' ); + + $view = new \OC_FilesystemView( '/' ); // Save keyfile for newly encrypted file in parallel directory tree - Keymanager::setFileKey( $filePath, $encrypted['key'], $view, '\OC_DB' ); + Keymanager::setFileKey( $view, $filePath, $userId, $encrypted['key'] ); // Update the file cache with file info \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); @@ -159,6 +162,8 @@ class Proxy extends \OC_FileProxy { $userId = \OCP\USER::getUser(); + # TODO: Check if file is shared, if so, use multiKeyDecrypt + $encryptedKeyfile = Keymanager::getFileKey( $view, $userId, $filePath ); $session = new Session(); diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index f482e2d75a..a17a4514fa 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -302,8 +302,12 @@ class Stream { // Make sure the userId is set $this->getuser(); + # TODO: Check if file is shared, if so, use multiKeyEncrypt and + # save shareKeys in necessary user directories + // 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 + // If we're writing a new file (not overwriting an existing + // one), save the newly generated keyfile if ( ! $this->getKey() ) { $this->keyfile = Crypt::generateKey(); @@ -312,10 +316,11 @@ class Stream { $this->encKeyfile = Crypt::keyEncrypt( $this->keyfile, $this->publicKey ); - // Save the new encrypted file key - Keymanager::setFileKey( $this->rawPath, $this->encKeyfile, new \OC_FilesystemView( '/' ) ); + $view = new \OC_FilesystemView( '/' ); + $userId = \OCP\User::getUser(); - # TODO: move this new OCFSV out of here some how, use DI + // Save the new encrypted file key + Keymanager::setFileKey( $view, $this->rawPath, $userId, $this->encKeyfile ); } diff --git a/apps/files_encryption/test/keymanager.php b/apps/files_encryption/test/keymanager.php index f02d6eb5f7..bf453fe316 100644 --- a/apps/files_encryption/test/keymanager.php +++ b/apps/files_encryption/test/keymanager.php @@ -79,15 +79,13 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase { # NOTE: This cannot be tested until we are able to break out # of the FileSystemView data directory root -// $key = Crypt::symmetricEncryptFileContentKeyfile( $this->data, 'hat' ); -// -// $tmpPath = sys_get_temp_dir(). '/' . 'testSetFileKey'; -// -// $view = new \OC_FilesystemView( '/tmp/' ); -// -// //$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' ); -// -// Encryption\Keymanager::setFileKey( $tmpPath, $key['key'], $view ); + $key = Encryption\Crypt::symmetricEncryptFileContentKeyfile( $this->randomKey, 'hat' ); + + $path = 'unittest-'.time().'txt'; + + //$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' ); + + Encryption\Keymanager::setFileKey( $this->view, $path, $this->userId, $key['key'] ); } From 59ca312263d358c95b950266c678c71bf97716f3 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 23 Jan 2013 19:24:26 +0000 Subject: [PATCH 04/31] Work on util: findFiles() and encryptAll(); both close to working Ecnryption unit tests are failing, recursion in filecache{} --- apps/files_encryption/appinfo/app.php | 6 +- apps/files_encryption/lib/crypt.php | 4 +- apps/files_encryption/lib/keymanager.php | 112 +++++++------ apps/files_encryption/lib/proxy.php | 10 +- apps/files_encryption/lib/util.php | 157 +++++++++++++----- .../templates/settings-personal.php | 13 +- apps/files_encryption/templates/settings.php | 63 +------ apps/files_encryption/test/crypt.php | 6 +- apps/files_encryption/test/util.php | 23 ++- 9 files changed, 213 insertions(+), 181 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index cc78402d1d..fa293f4512 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -32,7 +32,7 @@ if ( && OCA\Encryption\Crypt::mode() == 'server' ) { - // Force the user to re-log in if the encryption key isn't unlocked + // Force the user to log-in again if the encryption key isn't unlocked // (happens when a user is logged in before the encryption app is // enabled) OCP\User::logout(); @@ -44,4 +44,6 @@ if ( } OCP\App::registerAdmin( 'files_encryption', 'settings' ); -OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); \ No newline at end of file + +// This is disabled until client-side encryption is supported: +// OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); \ No newline at end of file diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 642187b910..2591e90227 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -130,7 +130,7 @@ class Crypt { * @return true / false * @note see also OCA\Encryption\Util->isEncryptedPath() */ - public static function isEncryptedContent( $content ) { + public static function isCatfile( $content ) { if ( !$content ) { @@ -192,7 +192,7 @@ class Crypt { $content and isset( $metadata['encrypted'] ) and $metadata['encrypted'] === true - and !self::isEncryptedContent( $content ) + and !self::isCatfile( $content ) ) { return true; diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 61bc50721e..c6669081a2 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -146,10 +146,59 @@ class Keymanager { } + /** + * @brief store file encryption key + * + * @param string $path relative path of the file, including filename + * @param string $key + * @return bool true/false + * @note The keyfile is not encrypted here. Client code must + * asymmetrically encrypt the keyfile before passing it to this method + */ + public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) { + + $basePath = '/' . $userId . '/files_encryption/keyfiles'; + + $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId ); + +// // update $keytarget and $userId if key belongs to a file shared by someone else +// $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); +// +// $result = $query->execute( array ( '/'.$userId.'/files/'.$targetPath, $userId ) ); +// +// if ( $row = $result->fetchRow( ) ) { +// +// $targetPath = $row['source']; +// +// $targetPath_parts = explode( '/', $targetPath ); +// +// $userId = $targetPath_parts[1]; +// +// $rootview = new \OC_FilesystemView( '/' ); +// +// if ( ! $rootview->is_writable( $targetPath ) ) { +// +// \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file", \OC_Log::ERROR ); +// +// return false; +// +// } +// +// $targetPath = str_replace( '/'.$userId.'/files/', '', $targetPath ); +// +// //TODO: check for write permission on shared file once the new sharing API is in place +// +// } + + // Save the keyfile in parallel directory + return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); + + } + /** * @brief retrieve keyfile for an encrypted file * @param string file name - * @return string file key or false + * @return string file key or false on failure * @note The keyfile returned is asymmetrically encrypted. Decryption * of the keyfile must be performed by client code */ @@ -171,7 +220,17 @@ class Keymanager { // // } - return $view->file_get_contents( '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key' ); + $catfilePath = '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key'; + + if ( $view->file_exists( $catfilePath ) ) { + + return $view->file_get_contents( $catfilePath ); + + } else { + + return false; + + } } @@ -298,55 +357,6 @@ class Keymanager { } - /** - * @brief store file encryption key - * - * @param string $path relative path of the file, including filename - * @param string $key - * @return bool true/false - * @note The keyfile is not encrypted here. Client code must - * asymmetrically encrypt the keyfile before passing it to this method - */ - public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) { - - $basePath = '/' . $userId . '/files_encryption/keyfiles'; - - $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId ); - -// // update $keytarget and $userId if key belongs to a file shared by someone else -// $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); -// -// $result = $query->execute( array ( '/'.$userId.'/files/'.$targetPath, $userId ) ); -// -// if ( $row = $result->fetchRow( ) ) { -// -// $targetPath = $row['source']; -// -// $targetPath_parts = explode( '/', $targetPath ); -// -// $userId = $targetPath_parts[1]; -// -// $rootview = new \OC_FilesystemView( '/' ); -// -// if ( ! $rootview->is_writable( $targetPath ) ) { -// -// \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file", \OC_Log::ERROR ); -// -// return false; -// -// } -// -// $targetPath = str_replace( '/'.$userId.'/files/', '', $targetPath ); -// -// //TODO: check for write permission on shared file once the new sharing API is in place -// -// } - - // Save the keyfile in parallel directory - return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); - - } - /** * @brief change password of private encryption key * diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 83c5e21c4b..6f00bd13b4 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -68,7 +68,7 @@ class Proxy extends \OC_FileProxy { } - if ( Crypt::isEncryptedContent( $path ) ) { + if ( Crypt::isCatfile( $path ) ) { return true; @@ -147,7 +147,7 @@ class Proxy extends \OC_FileProxy { // If data is a catfile if ( Crypt::mode() == 'server' - && Crypt::isEncryptedContent( $data ) + && Crypt::isCatfile( $data ) ) { $split = explode( '/', $path ); @@ -269,14 +269,14 @@ class Proxy extends \OC_FileProxy { } public function postGetMimeType($path,$mime){ - if( Crypt::isEncryptedContent($path)){ + if( Crypt::isCatfile($path)){ $mime = \OCP\Files::getMimeType('crypt://'.$path,'w'); } return $mime; } public function postStat($path,$data){ - if( Crypt::isEncryptedContent($path)){ + if( Crypt::isCatfile($path)){ $cached= \OC_FileCache_Cached::get($path,''); $data['size']=$cached['size']; } @@ -284,7 +284,7 @@ class Proxy extends \OC_FileProxy { } public function postFileSize($path,$size){ - if( Crypt::isEncryptedContent($path)){ + if( Crypt::isCatfile($path)){ $cached = \OC_FileCache_Cached::get($path,''); return $cached['size']; }else{ diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 56e4d572c2..f70839e39f 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -94,6 +94,7 @@ class Util { private $view; // OC_FilesystemView object for filesystem operations + private $userId; // ID of the currently logged-in user private $pwd; // User Password private $client; // Client side encryption mode flag private $publicKeyDir; // Dir containing all public user keys @@ -108,6 +109,8 @@ class Util { $this->view = $view; $this->userId = $userId; $this->client = $client; + $this->userDir = '/' . $this->userId; + $this->userFilesDir = '/' . $this->userId . '/' . 'files'; $this->publicKeyDir = '/' . 'public-keys'; $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; @@ -120,7 +123,9 @@ class Util { public function ready() { if( - !$this->view->file_exists( $this->keyfilesPath ) + !$this->view->file_exists( $this->encryptionDir ) + or !$this->view->file_exists( $this->keyfilesPath ) + or !$this->view->file_exists( $this->shareKeysPath ) or !$this->view->file_exists( $this->publicKeyPath ) or !$this->view->file_exists( $this->privateKeyPath ) ) { @@ -141,6 +146,20 @@ class Util { */ public function setupServerSide( $passphrase = null ) { + // Create user dir + if( !$this->view->file_exists( $this->userDir ) ) { + + $this->view->mkdir( $this->userDir ); + + } + + // Create user files dir + if( !$this->view->file_exists( $this->userFilesDir ) ) { + + $this->view->mkdir( $this->userFilesDir ); + + } + // Create shared public key directory if( !$this->view->file_exists( $this->publicKeyDir ) ) { @@ -171,13 +190,13 @@ class Util { // Create user keypair if ( - !$this->view->file_exists( $this->publicKeyPath ) - or !$this->view->file_exists( $this->privateKeyPath ) + ! $this->view->file_exists( $this->publicKeyPath ) + or ! $this->view->file_exists( $this->privateKeyPath ) ) { // Generate keypair $keypair = Crypt::createKeypair(); - + \OC_FileProxy::$enabled = false; // Save public key @@ -193,52 +212,71 @@ class Util { } + $publicKey = Keymanager::getPublicKey( $this->view, $this->userId ); + + // Encrypt existing user files: + $this->encryptAll( $publicKey, $this->userFilesDir ); + return true; } - public function findFiles( $directory, $type = 'plain' ) { - - # TODO: test finding non plain content + /** + * @brief Find all files and their encryption status within a directory + * @param string $directory The path of the parent directory to search + * @return mixed false if 0 found, array on success. Keys: name, path + */ + public function findFiles( $directory ) { + + // 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 ( + $this->view->is_dir( $directory ) + && $handle = $this->view->opendir( $directory ) + ) { - if ( $handle = $this->view->opendir( $directory ) ) { - while ( false !== ( $file = readdir( $handle ) ) ) { - + if ( $file != "." && $file != ".." ) { - + $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file ); - var_dump($filePath); - + // If the path is a directory, search + // its contents if ( $this->view->is_dir( $filePath ) ) { $this->findFiles( $filePath ); - + + // If the path is a file, determine + // its encryption status } elseif ( $this->view->is_file( $filePath ) ) { - - if ( $type == 'plain' ) { - - $this->files[] = array( 'name' => $file, 'path' => $filePath ); - - } elseif ( $type == 'encrypted' ) { - if ( Crypt::isEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { - - $this->files[] = array( 'name' => $file, 'path' => $filePath ); - - } + // Disable proxies again, some- + // how they get re-enabled :/ + \OC_FileProxy::$enabled = false; - } elseif ( $type == 'legacy' ) { + // If the file is encrypted + if ( Keymanager::getFileKey( $this->view, $this->userId, $file ) ) { - if ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + $found['encrypted'][] = array( 'name' => $file, 'path' => $filePath ); + + // If the file uses old + // encryption system + } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { - $this->files[] = array( 'name' => $file, 'path' => $filePath ); + $found['legacy'][] = array( 'name' => $file, 'path' => $filePath ); - } + // If the file is not encrypted + } else { + + $found['plain'][] = array( 'name' => $file, 'path' => $filePath ); } @@ -248,18 +286,22 @@ class Util { } - if ( !empty( $this->files ) ) { + \OC_FileProxy::$enabled = true; - return $this->files; + if ( empty( $found ) ) { + + return false; } else { - return false; + return $found; } } + \OC_FileProxy::$enabled = true; + return false; } @@ -278,22 +320,55 @@ class Util { \OC_FileProxy::$enabled = true; - return Crypt::isEncryptedContent( $data ); + return Crypt::isCatfile( $data ); } - public function encryptAll( $directory ) { + /** + * @brief Encrypt all files in a directory + * @param string $publicKey the public key to encrypt files with + * @param string $dirPath the directory whose files will be encrypted + * @note Encryption is recursive + */ + public function encryptAll( $publicKey, $dirPath ) { - $plainFiles = $this->findFiles( $this->view, 'plain' ); + if ( $found = $this->findFiles( $dirPath ) ) { - if ( $this->encryptFiles( $plainFiles ) ) { - - return true; + // Encrypt unencrypted files + foreach ( $found['plain'] as $plainFilePath ) { - } else { - - return false; + // Fetch data from file + $plainData = $this->view->file_get_contents( $plainFilePath ); + + // Encrypt data, generate catfile + $encrypted = Crypt::keyEncryptKeyfile( $plainData, $publicKey ); + + // Save catfile + Keymanager::setFileKey( $this->view, $plainFilePath, $this->userId, $encrypted['key'] ); + + // Overwrite the existing file with the encrypted one + $this->view->file_put_contents( $plainFilePath, $encrypted['data'] ); + } + + // FIXME: Legacy recrypting here isn't finished yet + // Encrypt legacy encrypted files + foreach ( $found['legacy'] as $legacyFilePath ) { + + // Fetch data from file + $legacyData = $this->view->file_get_contents( $legacyFilePath ); + + // Recrypt data, generate catfile + $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); + + // Save catfile + Keymanager::setFileKey( $this->view, $plainFilePath, $this->userId, $recrypted['key'] ); + + // Overwrite the existing file with the encrypted one + $this->view->file_put_contents( $plainFilePath, $recrypted['data'] ); + + } + } } diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 1274bd3bb5..c8144da563 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -9,17 +9,6 @@ value="" > - - /> - t('Client side encryption (most secure but makes it impossible to access your data from the web interface)'); ?> -
- /> - t('Server side encryption (allows you to access your files from the web interface and the desktop client)'); ?> + t('Server side encryption (allows you to access your files from the web interface)'); ?>
- - t('Choose encryption mode:'); ?> - - -

- - t('Important: Once you selected an encryption mode there is no way to change it back'); ?> - -

- -

- - /> - - t("Client side encryption (most secure but makes it impossible to access your data from the web interface)"); ?> -
- - - /> - - t('Server side encryption (allows you to access your files from the web interface and the desktop client)'); ?> -
- - - /> - - t('User specific (let the user decide)'); ?> -
- - - /> - - t('None (no encryption at all)'); ?> -
- -

t('Encryption'); ?> - t("Exclude the following file types from encryption"); ?> + t("Exclude the following file types from encryption:"); ?> +
+ style="width:20px;" /> - t('Server side encryption (allows you to access your files from the web interface)'); ?> + t( 'Server side encryption (allows you to access your files from the web interface)' ); ?>
+ /> - t('None (no encryption at all)'); ?> + t( 'None (no encryption at all)' ); ?>

diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 17ac1fd224..f7ef8a8efe 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -2,17 +2,17 @@

- t('Encryption'); ?> + t( 'Encryption' ); ?> - t("Exclude the following file types from encryption:"); ?> + t( "Exclude the following file types from encryption:" ); ?>

From c1f20fe37a28c6f596dd55a27962d77d0ade1892 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 29 Jan 2013 19:54:40 +0000 Subject: [PATCH 06/31] Made encyrption keyfiles be deleted when their parents are Made encryption keyfiles be renamed when their parents are Fixed bugs with encryptAll() execution on login --- apps/files_encryption/appinfo/spec.txt | 12 +++++ apps/files_encryption/hooks/hooks.php | 15 ++++-- apps/files_encryption/lib/keymanager.php | 44 ++++++++-------- apps/files_encryption/lib/proxy.php | 67 ++++++++++++++++++++++++ apps/files_encryption/lib/util.php | 38 +++++++++++--- 5 files changed, 142 insertions(+), 34 deletions(-) diff --git a/apps/files_encryption/appinfo/spec.txt b/apps/files_encryption/appinfo/spec.txt index ab248be64d..2d22dffe08 100644 --- a/apps/files_encryption/appinfo/spec.txt +++ b/apps/files_encryption/appinfo/spec.txt @@ -1,3 +1,15 @@ +Encrypted files +--------------- + +- Each encrypted file has at least two components: the encrypted data file + ('catfile'), and it's corresponding key file ('keyfile'). Shared files have an + additional key file ('share key'). The catfile contains the encrypted data + concatenated with delimiter text, followed by the initialisation vector ('IV'), + and padding. e.g.: + + [encrypted data string][delimiter][IV][padding] + [anhAAjAmcGXqj1X9g==][00iv00][MSHU5N5gECP7aAg7][xx] (square braces added) + Notes ----- diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 73d7957541..dafa14fc00 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -37,8 +37,6 @@ class Hooks { * @note This method should never be called for users using client side encryption */ public static function login( $params ) { - - // TODO: use lots of dependency injection here $view = new \OC_FilesystemView( '/' ); @@ -83,8 +81,17 @@ class Hooks { // Encrypt existing user files: // This serves to upgrade old versions of the encryption - // app (see appinfo/spec.txt - $this->encryptAll( $publicKey, $this->userFilesDir, $session->getLegacyKey(), $params['password'] ); + // app (see appinfo/spec.txt) + if ( + $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] ) + ) { + + \OC_Log::write( + 'Encryption library', 'Encryption of file belonging to "' . $params['uid'] . '" was started at login' + , \OC_Log::INFO + ); + + } return true; diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 301e5b33fd..8656bb9675 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -234,33 +234,33 @@ class Keymanager { } /** - * @brief retrieve file encryption key + * @brief Delete a keyfile * - * @param string file name - * @return string file key or false + * @param OC_FilesystemView $view + * @param string $userId username + * @param string $path path of the file the key belongs to + * @return bool Outcome of unlink operation + * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT + * /data/admin/files/mydoc.txt */ - public static function deleteFileKey( $path, $staticUserClass = 'OCP\User' ) { + public static function deleteFileKey( \OC_FilesystemView $view, $userId, $path ) { - $keypath = ltrim( $path, '/' ); - $user = $staticUserClass::getUser(); - - // update $keypath and $user if path point to a file shared by someone else -// $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); -// -// $result = $query->execute( array ('/'.$user.'/files/'.$keypath, $user)); -// -// if ($row = $result->fetchRow()) { -// -// $keypath = $row['source']; -// $keypath_parts = explode( '/', $keypath ); -// $user = $keypath_parts[1]; -// $keypath = str_replace( '/' . $user . '/files/', '', $keypath ); -// -// } + $trimmed = ltrim( $path, '/' ); + $keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed . '.key'; - $view = new \OC_FilesystemView( '/' . $user. '/files_encryption/keyfiles/' ); + // Unlink doesn't tell us if file was deleted (not found returns + // true), so we perform our own test + if ( $view->file_exists( $keyPath ) ) { - return $view->unlink( $keypath . '.key' ); + return $view->unlink( $keyPath ); + + } else { + + \OC_Log::write( 'Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR ); + + return false; + + } } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 025af3c7f1..6d2a574abd 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -192,6 +192,73 @@ class Proxy extends \OC_FileProxy { } + /** + * @brief When a file is deleted, remove its keyfile also + */ + public function postUnlink( $path ) { + + // Disable encryption proxy to prevent recursive calls + \OC_FileProxy::$enabled = false; + + $view = new \OC_FilesystemView( '/' ); + + $userId = \OCP\USER::getUser(); + + // Format path to be relative to user files dir + $trimmed = ltrim( $path, '/' ); + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); + + // Delete keyfile so it isn't orphaned + $result = Keymanager::deleteFileKey( $view, $userId, $relPath ); + + \OC_FileProxy::$enabled = true; + + return $result; + + } + + /** + * @brief When a file is renamed, rename its keyfile also + * @return bool Result of rename() + * @note This is pre rather than post because using post didn't work + */ + public function preRename( $oldPath, $newPath ) { + +// trigger_error( "PATHS = ".var_export($oldPath, 1).' '.var_export($newPath, 1)); + + // 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'; + +// trigger_error("RENAMING = ".var_export($oldKeyfilePath, 1).' -> '.var_export($newKeyfilePath, 1)); + + // 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 ) { diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index fd4d7a9fcc..2a69bba43c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -225,6 +225,9 @@ class Util { * @brief Find all files and their encryption status within a directory * @param string $directory The path of the parent directory to search * @return mixed false if 0 found, array on success. Keys: name, path + + * @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 findFiles( $directory ) { @@ -293,7 +296,7 @@ class Util { return false; } else { - + return $found; } @@ -334,20 +337,29 @@ class Util { if ( $found = $this->findFiles( $dirPath ) ) { + // Disable proxy to prevent file being encrypted twice + \OC_FileProxy::$enabled = false; + // Encrypt unencrypted files - foreach ( $found['plain'] as $plainFilePath ) { - + foreach ( $found['plain'] as $plainFile ) { + // Fetch data from file - $plainData = $this->view->file_get_contents( $plainFilePath ); + $plainData = $this->view->file_get_contents( $plainFile['path'] ); // Encrypt data, generate catfile $encrypted = Crypt::keyEncryptKeyfile( $plainData, $publicKey ); + // Format path to be relative to user files dir + $trimmed = ltrim( $plainFile['path'], '/' ); + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); + // Save catfile - Keymanager::setFileKey( $this->view, $plainFilePath, $this->userId, $encrypted['key'] ); + Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encrypted['key'] ); // Overwrite the existing file with the encrypted one - $this->view->file_put_contents( $plainFilePath, $encrypted['data'] ); + $this->view->file_put_contents( $plainFile['path'], $encrypted['data'] ); } @@ -367,15 +379,25 @@ class Util { $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); // Save catfile - Keymanager::setFileKey( $this->view, $plainFilePath, $this->userId, $recrypted['key'] ); + Keymanager::setFileKey( $this->view, $plainFile['path'], $this->userId, $recrypted['key'] ); // Overwrite the existing file with the encrypted one - $this->view->file_put_contents( $plainFilePath, $recrypted['data'] ); + $this->view->file_put_contents( $plainFile['path'], $recrypted['data'] ); } } + + \OC_FileProxy::$enabled = true; + + // If files were found, return true + return true; + } else { + + // If no files were found, return false + return false; + } } From 61b23ce6cc4c9e21da1dd161f11fc15b878027fd Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 30 Jan 2013 17:25:17 +0000 Subject: [PATCH 07/31] Working on support for deleting directories (removing all keyfiles) --- apps/files_encryption/lib/proxy.php | 32 +++++++++++++++++------------ 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 6d2a574abd..9e1dbfe0d3 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -195,27 +195,37 @@ class Proxy extends \OC_FileProxy { /** * @brief When a file is deleted, remove its keyfile also */ - public function postUnlink( $path ) { + public function preUnlink( $path ) { // Disable encryption proxy to prevent recursive calls \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView( '/' ); - $userId = \OCP\USER::getUser(); - // Format path to be relative to user files dir $trimmed = ltrim( $path, '/' ); $split = explode( '/', $trimmed ); $sliced = array_slice( $split, 2 ); $relPath = implode( '/', $sliced ); - - // Delete keyfile so it isn't orphaned - $result = Keymanager::deleteFileKey( $view, $userId, $relPath ); - - \OC_FileProxy::$enabled = true; - return $result; + if ( $view->is_dir( $path ) ) { + + // Dirs must be handled separately as deleteFileKey + // doesn't handle them + $view->unlink( 'files_encryption/keyfiles/'. $relPath ); + + } else { + + $userId = \OCP\USER::getUser(); + + // Delete keyfile so it isn't orphaned + $result = Keymanager::deleteFileKey( $view, $userId, $relPath ); + + \OC_FileProxy::$enabled = true; + + return $result; + + } } @@ -225,8 +235,6 @@ class Proxy extends \OC_FileProxy { * @note This is pre rather than post because using post didn't work */ public function preRename( $oldPath, $newPath ) { - -// trigger_error( "PATHS = ".var_export($oldPath, 1).' '.var_export($newPath, 1)); // Disable encryption proxy to prevent recursive calls \OC_FileProxy::$enabled = false; @@ -248,8 +256,6 @@ class Proxy extends \OC_FileProxy { $newRelPath = implode( '/', $newSliced ); $newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath . '.key'; -// trigger_error("RENAMING = ".var_export($oldKeyfilePath, 1).' -> '.var_export($newKeyfilePath, 1)); - // Rename keyfile so it isn't orphaned $result = $view->rename( $oldKeyfilePath, $newKeyfilePath ); From c7b1bdf00e65cca2a42d77fc5f27d0ea69e53be3 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 30 Jan 2013 18:52:02 +0000 Subject: [PATCH 08/31] Fixed handling of keyfile subdir creation Improved keyfile subdir deletion (1 bug remains here) --- apps/files_encryption/lib/keymanager.php | 94 ++++-------------------- apps/files_encryption/lib/proxy.php | 12 ++- 2 files changed, 23 insertions(+), 83 deletions(-) diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 8656bb9675..43af70dacc 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -83,38 +83,7 @@ class Keymanager { // Check if sharing is enabled if ( OC_App::isEnabled( 'files_sharing' ) ) { -// // Check if file was shared with other users -// $query = \OC_DB::prepare( " -// SELECT -// uid_owner -// , source -// , target -// , uid_shared_with -// FROM -// `*PREFIX*sharing` -// WHERE -// ( target = ? AND uid_shared_with = ? ) -// OR source = ? -// " ); -// -// $result = $query->execute( array ( $filepath, $userId, $filepath ) ); -// -// $users = array(); -// -// if ( $row = $result->fetchRow() ) -// { -// $source = $row['source']; -// $owner = $row['uid_owner']; -// $users[] = $owner; -// // get the uids of all user with access to the file -// $query = \OC_DB::prepare( "SELECT source, uid_shared_with FROM `*PREFIX*sharing` WHERE source = ?" ); -// $result = $query->execute( array ($source)); -// while ( ($row = $result->fetchRow()) ) { -// $users[] = $row['uid_shared_with']; -// -// } -// -// } + } else { @@ -160,37 +129,16 @@ class Keymanager { $targetPath = self::keySetPreparation( $view, $path, $basePath, $userId ); -// // update $keytarget and $userId if key belongs to a file shared by someone else -// $query = $dbClassName::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); -// -// $result = $query->execute( array ( '/'.$userId.'/files/'.$targetPath, $userId ) ); -// -// if ( $row = $result->fetchRow( ) ) { -// -// $targetPath = $row['source']; -// -// $targetPath_parts = explode( '/', $targetPath ); -// -// $userId = $targetPath_parts[1]; -// -// $rootview = new \OC_FilesystemView( '/' ); -// -// if ( ! $rootview->is_writable( $targetPath ) ) { -// -// \OC_Log::write( 'Encryption library', "File Key not updated because you don't have write access for the corresponding file", \OC_Log::ERROR ); -// -// return false; -// -// } -// -// $targetPath = str_replace( '/'.$userId.'/files/', '', $targetPath ); -// -// //TODO: check for write permission on shared file once the new sharing API is in place -// -// } + if ( $view->is_dir( $basePath . '/' . $targetPath ) ) { - // Save the keyfile in parallel directory - return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); + + + } else { + + // Save the keyfile in parallel directory + return $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); + + } } @@ -204,21 +152,7 @@ class Keymanager { public static function getFileKey( \OC_FilesystemView $view, $userId, $filePath ) { $filePath_f = ltrim( $filePath, '/' ); - -// // update $keypath and $userId if path point to a file shared by someone else -// $query = \OC_DB::prepare( "SELECT uid_owner, source, target FROM `*PREFIX*sharing` WHERE target = ? AND uid_shared_with = ?" ); -// -// $result = $query->execute( array ('/'.$userId.'/files/'.$keypath, $userId)); -// -// if ($row = $result->fetchRow()) { -// -// $keypath = $row['source']; -// $keypath_parts = explode( '/', $keypath ); -// $userId = $keypath_parts[1]; -// $keypath = str_replace( '/' . $userId . '/files/', '', $keypath ); -// -// } - + $catfilePath = '/' . $userId . '/files_encryption/keyfiles/' . $filePath_f . '.key'; if ( $view->file_exists( $catfilePath ) ) { @@ -337,7 +271,7 @@ class Keymanager { * @brief Make preparations to vars and filesystem for saving a keyfile */ public static function keySetPreparation( \OC_FilesystemView $view, $path, $basePath, $userId ) { - + $targetPath = ltrim( $path, '/' ); $path_parts = pathinfo( $targetPath ); @@ -345,10 +279,10 @@ class Keymanager { // If the file resides within a subdirectory, create it if ( isset( $path_parts['dirname'] ) - && ! $view->file_exists( $basePath . $path_parts['dirname'] ) + && ! $view->file_exists( $basePath . '/' . $path_parts['dirname'] ) ) { - $view->mkdir( $basePath . $path_parts['dirname'] ); + $view->mkdir( $basePath . '/' . $path_parts['dirname'] ); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 9e1dbfe0d3..f7245d11cf 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -22,6 +22,12 @@ * */ +/** +* @brief Encryption proxy which handles filesystem operations before and after +* execution and encrypts, and handles keyfiles accordingly. Used for +* webui. +*/ + namespace OCA\Encryption; class Proxy extends \OC_FileProxy { @@ -202,6 +208,8 @@ class Proxy extends \OC_FileProxy { $view = new \OC_FilesystemView( '/' ); + $userId = \OCP\USER::getUser(); + // Format path to be relative to user files dir $trimmed = ltrim( $path, '/' ); $split = explode( '/', $trimmed ); @@ -212,11 +220,9 @@ class Proxy extends \OC_FileProxy { // Dirs must be handled separately as deleteFileKey // doesn't handle them - $view->unlink( 'files_encryption/keyfiles/'. $relPath ); + $view->unlink( $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/'. $relPath ); } else { - - $userId = \OCP\USER::getUser(); // Delete keyfile so it isn't orphaned $result = Keymanager::deleteFileKey( $view, $userId, $relPath ); From 2183f77527fa027a4bf86d8eb2229092605d6827 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 31 Jan 2013 16:49:07 +0000 Subject: [PATCH 09/31] Fixed incompatibilities with filecache rewrite merge --- apps/files_encryption/lib/crypt.php | 6 +++--- apps/files_encryption/lib/proxy.php | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 9d4f5a1fae..106b757307 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -170,10 +170,10 @@ class Crypt { */ public static function isEncryptedMeta( $path ) { - // TODO: Use DI to get OC_FileCache_Cached out of here + // TODO: Use DI to get \OC\Files\Filesystem out of here // Fetch all file metadata from DB - $metadata = \OC_FileCache_Cached::get( $path, '' ); + $metadata = \OC\Files\Filesystem::getFileInfo( $path, '' ); // Return encryption status return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted']; @@ -187,7 +187,7 @@ class Crypt { public static function isLegacyEncryptedContent( $content ) { // Fetch all file metadata from DB - $metadata = \OC_FileCache_Cached::get( $content, '' ); + $metadata = \OC\Files\Filesystem::getFileInfo( $content, '' ); // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index f7245d11cf..55cddf2bec 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -129,7 +129,7 @@ class Proxy extends \OC_FileProxy { Keymanager::setFileKey( $view, $filePath, $userId, $encrypted['key'] ); // Update the file cache with file info - \OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); + \OC\Files\Filesystem::putFileInfo( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = true; @@ -162,7 +162,7 @@ class Proxy extends \OC_FileProxy { $filePath = '/' . implode( '/', $filePath ); - //$cached = \OC_FileCache_Cached::get( $path, '' ); + //$cached = \OC\Files\Filesystem::getFileInfo( $path, '' ); $view = new \OC_FilesystemView( '' ); @@ -363,7 +363,7 @@ class Proxy extends \OC_FileProxy { if ( Crypt::isCatfile( $path ) ) { - $cached = \OC_FileCache_Cached::get( $path, '' ); + $cached = \OC\Files\Filesystem::getFileInfo( $path, '' ); $data['size'] = $cached['size']; @@ -376,7 +376,7 @@ class Proxy extends \OC_FileProxy { if ( Crypt::isCatfile( $path ) ) { - $cached = \OC_FileCache_Cached::get( $path, '' ); + $cached = \OC\Files\Filesystem::getFileInfo( $path, '' ); return $cached['size']; From c6b3bdd5a0f6651c557c6653b49acd005bbadba8 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 31 Jan 2013 17:47:30 +0000 Subject: [PATCH 10/31] Fixed compatibility with filecache rewrite merge --- apps/files_encryption/lib/stream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index f634db7a38..4102a681d7 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -484,7 +484,7 @@ class Stream { and $this->meta['mode']!='rb' ) { - \OC_FileCache::put( $this->path, array( 'encrypted' => true, 'size' => $this->size ), '' ); + \OC\Files\Filesystem::putFileInfo( $this->path, array( 'encrypted' => true, 'size' => $this->size ), '' ); } From 06847f609b09f118b552d70e6f837a92008db570 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Thu, 31 Jan 2013 19:40:51 +0000 Subject: [PATCH 11/31] Improved support for detecting and recrypting legacy files. Bugs remain. --- apps/files_encryption/hooks/hooks.php | 4 +-- apps/files_encryption/lib/crypt.php | 13 +++++----- apps/files_encryption/lib/session.php | 2 +- apps/files_encryption/lib/util.php | 35 +++++++++++++++++++++------ 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index dafa14fc00..cb9993b238 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -70,7 +70,7 @@ class Hooks { $view1->file_exists( 'encryption.key' ) && $encLegacyKey = $view1->file_get_contents( 'encryption.key' ) ) { - + $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] ); $session->setLegacyKey( $plainLegacyKey ); @@ -87,7 +87,7 @@ class Hooks { ) { \OC_Log::write( - 'Encryption library', 'Encryption of file belonging to "' . $params['uid'] . '" was started at login' + 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" started at login' , \OC_Log::INFO ); diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 106b757307..6fbbd412b8 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -184,19 +184,18 @@ class Crypt { * @brief Check if a file is encrypted via legacy system * @return true / false */ - public static function isLegacyEncryptedContent( $content ) { + public static function isLegacyEncryptedContent( $data, $path ) { // Fetch all file metadata from DB - $metadata = \OC\Files\Filesystem::getFileInfo( $content, '' ); - + $metadata = \OC\Files\Filesystem::getFileInfo( $path, '' ); + // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the // legacy encryption system if ( - $content - and isset( $metadata['encrypted'] ) - and $metadata['encrypted'] === true - and ! self::isCatfile( $content ) + isset( $metadata['encrypted'] ) + and $metadata['encrypted'] === true + and ! self::isCatfile( $data ) ) { return true; diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 4abc8be689..bda22ee3a0 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -70,7 +70,7 @@ class Session { */ public function setLegacyKey( $legacyKey ) { - $_SESSION['legacyKey'] = $LegacyKey; + $_SESSION['legacyKey'] = $legacyKey; return true; diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 2a69bba43c..b1c128cf8c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -37,8 +37,9 @@ namespace OCA\Encryption; /** * @brief Class for utilities relating to encrypted file storage system - * @param $view OC_FilesystemView object, expected to have OC '/' as root path - * @param $client flag indicating status of client side encryption. Currently + * @param OC_FilesystemView $view expected to have OC '/' as root path + * @param string $userId ID of the logged in user + * @param int $client indicating status of client side encryption. Currently * unused, likely to become obsolete shortly */ @@ -262,17 +263,25 @@ class Util { } elseif ( $this->view->is_file( $filePath ) ) { // Disable proxies again, some- - // how they get re-enabled :/ + // where they got re-enabled :/ \OC_FileProxy::$enabled = false; + $data = $this->view->file_get_contents( $filePath ); + // If the file is encrypted - if ( Keymanager::getFileKey( $this->view, $this->userId, $file ) ) { + // NOTE: If the userId is + // empty or not set, file will + // detected as plain + if ( + Keymanager::getFileKey( $this->view, $this->userId, $file ) + && Crypt::isCatfile( $filePath ) + ) { $found['encrypted'][] = array( 'name' => $file, 'path' => $filePath ); // If the file uses old // encryption system - } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ) ) ) { + } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ), $filePath ) ) { $found['legacy'][] = array( 'name' => $file, 'path' => $filePath ); @@ -355,11 +364,16 @@ class Util { $sliced = array_slice( $split, 2 ); $relPath = implode( '/', $sliced ); - // Save catfile + // Save keyfile Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encrypted['key'] ); // Overwrite the existing file with the encrypted one $this->view->file_put_contents( $plainFile['path'], $encrypted['data'] ); + + $size = strlen( $encrypted['data'] ); + + // Add the file to the cache + \OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' ); } @@ -370,6 +384,8 @@ class Util { && ! empty( $newPassphrase ) ) { + trigger_error("LEGACY FOUND"); + foreach ( $found['legacy'] as $legacyFilePath ) { // Fetch data from file @@ -378,11 +394,16 @@ class Util { // Recrypt data, generate catfile $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); - // Save catfile + // Save keyfile Keymanager::setFileKey( $this->view, $plainFile['path'], $this->userId, $recrypted['key'] ); // Overwrite the existing file with the encrypted one $this->view->file_put_contents( $plainFile['path'], $recrypted['data'] ); + + $size = strlen( $recrypted['data'] ); + + // Add the file to the cache + \OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' ); } From 0677d56ee226b0ba884f3e175c86540dbab643a5 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Fri, 1 Feb 2013 19:31:15 +0000 Subject: [PATCH 12/31] Added debugging output relating to recrypting legacy files --- apps/files_encryption/lib/crypt.php | 8 +++++++- apps/files_encryption/lib/util.php | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 6fbbd412b8..231bfd9826 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -186,8 +186,14 @@ class Crypt { */ public static function isLegacyEncryptedContent( $data, $path ) { + $trimmed = ltrim( $path, '/' ); + +// trigger_error( "DATA = ".var_export($data, 1). " CATFILE?: ".var_export( self::isCatfile( $data ), 1)); + // Fetch all file metadata from DB - $metadata = \OC\Files\Filesystem::getFileInfo( $path, '' ); + $metadata = \OC\Files\Filesystem::getFileInfo( $trimmed, '' ); + + trigger_error("PATH = ". var_export($trimmed, 1)." METADATA = ".var_export($metadata['encrypted'], 1)); // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index b1c128cf8c..7e396a9145 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -268,10 +268,15 @@ class Util { $data = $this->view->file_get_contents( $filePath ); +// trigger_error("HAKE \n".var_export($this->view->file_get_contents( $filePath ), 1)." \nfilepath = ".var_export($filePath, 1 )); + // If the file is encrypted // NOTE: If the userId is // empty or not set, file will // detected as plain + // NOTE: This is inefficient; + // scanning every file like this + // will eat server resources :( if ( Keymanager::getFileKey( $this->view, $this->userId, $file ) && Crypt::isCatfile( $filePath ) @@ -346,6 +351,8 @@ class Util { if ( $found = $this->findFiles( $dirPath ) ) { +// trigger_error("FOUND = ".print_r($found, 1)); + // Disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; @@ -384,13 +391,13 @@ class Util { && ! empty( $newPassphrase ) ) { - trigger_error("LEGACY FOUND"); - foreach ( $found['legacy'] as $legacyFilePath ) { // Fetch data from file $legacyData = $this->view->file_get_contents( $legacyFilePath ); + trigger_error("\n\nlegdata = ".var_export($legacyData).' \n\npassphrase = '.var_export($legacyPassphrase).' \n\npublickey = '.var_export($publicKey).' \n\nnewpass = '.var_export($newPassphrase)); + // Recrypt data, generate catfile $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); From 88ad1e5fbd2178c6281d060e9caa47837c447edf Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 3 Feb 2013 16:02:25 +0100 Subject: [PATCH 13/31] Make app icon linkable when enabling app. --- settings/js/apps.js | 1 + 1 file changed, 1 insertion(+) diff --git a/settings/js/apps.js b/settings/js/apps.js index 8bee958ec5..912ae99016 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -138,6 +138,7 @@ OC.Settings.Apps = OC.Settings.Apps || { li.append(img); var a=$('').attr('href', entry.href); a.text(entry.name); + a.prepend(img); li.append(a); container.append(li); } From 65bd7af8dfea7f263cc318556d5a36baca4b1d3a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 4 Feb 2013 20:40:16 -0500 Subject: [PATCH 14/31] Remove undefined crumb variable from home breadcrumb --- apps/files/templates/part.breadcrumb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/templates/part.breadcrumb.php b/apps/files/templates/part.breadcrumb.php index e506ba31f6..8778915be8 100644 --- a/apps/files/templates/part.breadcrumb.php +++ b/apps/files/templates/part.breadcrumb.php @@ -1,6 +1,6 @@ From 661da10dc505a5a6f92f6df939a650ecd9c2a429 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 5 Feb 2013 11:04:39 +0100 Subject: [PATCH 15/31] gitignore all apps except core ones --- .gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.gitignore b/.gitignore index 819347f540..09af6808d6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,17 @@ config/mount.php apps/inc.php 3rdparty +# ignore all apps except core ones +apps/* +!apps/files +!apps/files_encryption +!apps/files_external +!apps/files_sharing +!apps/files_trashbin +!apps/files_versions +!apps/user_ldap +!apps/user_webdavauth + # just sane ignores .*.sw[po] *.bak From 2ec0c491d4f24ead6bdb8bbff519182d08b2d139 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 5 Feb 2013 11:30:18 +0100 Subject: [PATCH 16/31] remove superfluous enabled-app class again --- core/css/styles.css | 5 ----- settings/js/apps.js | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/core/css/styles.css b/core/css/styles.css index 19cfad7626..a467857a21 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -228,11 +228,6 @@ fieldset.warning legend { color:#b94a48 !important; } #navigation a:hover, #navigation a:focus { opacity:.8; } #navigation a.active { opacity:1; } #navigation .icon { display:block; width:32px; height:32px; margin:0 16px 0; } - #navigation .enabled-app:hover, #navigation .enabled-app:focus { opacity:1; } - #navigation .enabled-app img { opacity:0.3; cursor:pointer;} - #navigation .enabled-app a {padding:4px 0 4px; } - #navigation .enabled-app:hover a, #navigation .enabled-app:focus a {opacity:0.8; } - #navigation .enabled-app:hover img, #navigation .enabled-app:focus img {opacity:0.8; } #navigation li:first-child a { padding-top:16px; } #settings { float:right; margin-top:7px; color:#bbb; text-shadow:0 -1px 0 #000; } #expand { padding:15px; cursor:pointer; font-weight:bold; } diff --git a/settings/js/apps.js b/settings/js/apps.js index 912ae99016..467d531269 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -132,7 +132,7 @@ OC.Settings.Apps = OC.Settings.Apps || { var container = $('#apps'); if(container.children('li[data-id="'+entry.id+'"]').length === 0){ - var li=$('
  • ').attr({class: 'enabled-app'}); + var li=$('
  • '); li.attr('data-id', entry.id); var img= $('').attr({ src: entry.icon, class:'icon'}); li.append(img); From 7eaa2d0de1bf548b974f71e9f34e246d54c3d89a Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 5 Feb 2013 12:48:30 +0100 Subject: [PATCH 17/31] form detail on log in button, better shape --- core/css/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/css/styles.css b/core/css/styles.css index 19cfad7626..77a07d90cf 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -112,7 +112,7 @@ input[type="submit"] img, input[type="button"] img, button img, .button img { cu #body-login input { font-size:1.5em; } #body-login input[type="text"], #body-login input[type="password"] { width:13em; } -#body-login input.login { width:auto; float:right; } +#body-login input.login { width:auto; float:right; padding:7px 9px 6px; } #remember_login { margin:.8em .2em 0 1em; } .searchbox input[type="search"] { font-size:1.2em; padding:.2em .5em .2em 1.5em; background:#fff url('../img/actions/search.svg') no-repeat .5em center; border:0; -moz-border-radius:1em; -webkit-border-radius:1em; border-radius:1em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70);opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; margin-top:10px; float:right; } input[type="submit"].enabled { background:#66f866; border:1px solid #5e5; -moz-box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; -webkit-box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; } From 8ae1205b95c0560b15fd0988939da79b7a06f0e2 Mon Sep 17 00:00:00 2001 From: Jan-Christoph Borchardt Date: Tue, 5 Feb 2013 12:49:33 +0100 Subject: [PATCH 18/31] line up 'remember' text with checkbox --- core/css/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/css/styles.css b/core/css/styles.css index 77a07d90cf..7204a729e5 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -113,7 +113,7 @@ input[type="submit"] img, input[type="button"] img, button img, .button img { cu #body-login input { font-size:1.5em; } #body-login input[type="text"], #body-login input[type="password"] { width:13em; } #body-login input.login { width:auto; float:right; padding:7px 9px 6px; } -#remember_login { margin:.8em .2em 0 1em; } +#remember_login { margin:.8em .2em 0 1em; vertical-align:text-bottom; } .searchbox input[type="search"] { font-size:1.2em; padding:.2em .5em .2em 1.5em; background:#fff url('../img/actions/search.svg') no-repeat .5em center; border:0; -moz-border-radius:1em; -webkit-border-radius:1em; border-radius:1em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70);opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; margin-top:10px; float:right; } input[type="submit"].enabled { background:#66f866; border:1px solid #5e5; -moz-box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; -webkit-box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; box-shadow:0 1px 1px #f8f8f8, 0 1px 1px #cfc inset; } #select_all{ margin-top:.4em !important;} From cda0780d4b029133a7641ca4565593a3ffa6c691 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Tue, 5 Feb 2013 14:15:17 +0100 Subject: [PATCH 19/31] Remove superfluous append --- settings/js/apps.js | 1 - 1 file changed, 1 deletion(-) diff --git a/settings/js/apps.js b/settings/js/apps.js index 467d531269..3bc3488e49 100644 --- a/settings/js/apps.js +++ b/settings/js/apps.js @@ -135,7 +135,6 @@ OC.Settings.Apps = OC.Settings.Apps || { var li=$('
  • '); li.attr('data-id', entry.id); var img= $('').attr({ src: entry.icon, class:'icon'}); - li.append(img); var a=$('').attr('href', entry.href); a.text(entry.name); a.prepend(img); From d8084c132ec411381519fe9dba2d235148692da4 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Tue, 5 Feb 2013 15:43:12 +0100 Subject: [PATCH 20/31] new function \OC_Util::runningOnWindows() --- lib/util.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/util.php b/lib/util.php index 363e3f105c..c5ef4e3b6f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -677,4 +677,11 @@ class OC_Util { return $data; } + /** + * @return bool - well are we running on windows or not + */ + public static function runningOnWindows() { + return (substr(PHP_OS, 0, 3) === "WIN"); + } + } From ac11c842e67fe278c4b2178623ad63a5066fc898 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Tue, 5 Feb 2013 15:46:55 +0100 Subject: [PATCH 21/31] setlocale test is pointless on Windows --- lib/util.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/util.php b/lib/util.php index c5ef4e3b6f..4932be2d6c 100755 --- a/lib/util.php +++ b/lib/util.php @@ -519,6 +519,11 @@ class OC_Util { * Check if the setlocal call doesn't work. This can happen if the right local packages are not available on the server. */ public static function issetlocaleworking() { + // setlocale test is pointless on Windows + if (OC_Util::runningOnWindows() ) { + return true; + } + $result=setlocale(LC_ALL, 'en_US.UTF-8'); if($result==false) { return(false); From 1fd807a7d68d254cfd372105ff672d09f13b4bb7 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 31 Jan 2013 22:04:08 +0100 Subject: [PATCH 22/31] pass the argument to the ctor Conflicts: lib/files/storage/temporary.php --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index ffc55e2750..b8bb619278 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -13,7 +13,7 @@ namespace OC\Files\Storage; */ class Temporary extends Local{ public function __construct($arguments) { - $this->datadir=\OC_Helper::tmpFolder(); + parent::__construct(array('datadir' => \OC_Helper::tmpFolder())); } public function cleanUp() { From 94460178219fcdcc3cfcb2015b1064cf19ff7f96 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Tue, 5 Feb 2013 16:24:40 +0100 Subject: [PATCH 23/31] spell check --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index b8bb619278..542d2cd9f4 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -9,7 +9,7 @@ namespace OC\Files\Storage; /** - * local storage backnd in temporary folder for testing purpores + * local storage backend in temporary folder for testing purpose */ class Temporary extends Local{ public function __construct($arguments) { From 53248a9b6069f64662e259053684c175498fe67d Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 15:35:29 +0000 Subject: [PATCH 24/31] Recryption of legacy encrypted files now working on login --- apps/files_encryption/lib/crypt.php | 9 ++++++++- apps/files_encryption/lib/util.php | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 231bfd9826..7f96702b76 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -188,10 +188,17 @@ class Crypt { $trimmed = ltrim( $path, '/' ); + // Path must not include user/files + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); + +// trigger_error("REL PATH = ".var_export($relPath, 1)); + // trigger_error( "DATA = ".var_export($data, 1). " CATFILE?: ".var_export( self::isCatfile( $data ), 1)); // Fetch all file metadata from DB - $metadata = \OC\Files\Filesystem::getFileInfo( $trimmed, '' ); + $metadata = \OC\Files\Filesystem::getFileInfo( $relPath, '' ); trigger_error("PATH = ". var_export($trimmed, 1)." METADATA = ".var_export($metadata['encrypted'], 1)); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 7e396a9145..89fe79b6ff 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -391,26 +391,32 @@ class Util { && ! empty( $newPassphrase ) ) { - foreach ( $found['legacy'] as $legacyFilePath ) { + foreach ( $found['legacy'] as $legacyFile ) { // Fetch data from file - $legacyData = $this->view->file_get_contents( $legacyFilePath ); + $legacyData = $this->view->file_get_contents( $legacyFile['path'] ); - trigger_error("\n\nlegdata = ".var_export($legacyData).' \n\npassphrase = '.var_export($legacyPassphrase).' \n\npublickey = '.var_export($publicKey).' \n\nnewpass = '.var_export($newPassphrase)); + trigger_error("\n\nlegdata = ".var_export($legacyData, 1).' \n\npassphrase = '.var_export($legacyPassphrase, 1).' \n\npublickey = '.var_export($publicKey, 1).' \n\nnewpass = '.var_export($newPassphrase, 1)); // Recrypt data, generate catfile $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); + // Format path to be relative to user files dir + $trimmed = ltrim( $legacyFile['path'], '/' ); + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); + // Save keyfile - Keymanager::setFileKey( $this->view, $plainFile['path'], $this->userId, $recrypted['key'] ); + Keymanager::setFileKey( $this->view, $relPath, $this->userId, $recrypted['key'] ); // Overwrite the existing file with the encrypted one - $this->view->file_put_contents( $plainFile['path'], $recrypted['data'] ); + $this->view->file_put_contents( $legacyFile['path'], $recrypted['data'] ); $size = strlen( $recrypted['data'] ); // Add the file to the cache - \OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' ); + \OC\Files\Filesystem::putFileInfo( $legacyFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' ); } From 50faddfa409f7afbb2a41fddaf9ce117e06d16d0 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 15:37:40 +0000 Subject: [PATCH 25/31] Minor improvement to comments --- lib/files/filesystem.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 65d9ffab48..71bf3d8708 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -527,8 +527,7 @@ class Filesystem { } /** - * normalize a path - * + * @brief Fix common problems with a file path * @param string $path * @param bool $stripTrailingSlash * @return string @@ -537,21 +536,21 @@ class Filesystem { if ($path == '') { return '/'; } -//no windows style slashes + //no windows style slashes $path = str_replace('\\', '/', $path); -//add leading slash + //add leading slash if ($path[0] !== '/') { $path = '/' . $path; } -//remove duplicate slashes + //remove duplicate slashes while (strpos($path, '//') !== false) { $path = str_replace('//', '/', $path); } -//remove trailing slash + //remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } -//normalize unicode if possible + //normalize unicode if possible if (class_exists('Normalizer')) { $path = \Normalizer::normalize($path); } From a1f200c1e5a4814d63561e581b7917270444e463 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 15:59:28 +0000 Subject: [PATCH 26/31] Cleaned up path formatting with new method stripUserFilesPath() --- apps/files_encryption/lib/crypt.php | 13 ++++--------- apps/files_encryption/lib/util.php | 29 ++++++++++++++++++----------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 7f96702b76..ff7d6dfb1f 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -182,16 +182,11 @@ class Crypt { /** * @brief Check if a file is encrypted via legacy system + * @param string $relPath The path of the file, relative to user/data; + * e.g. filename or /Docs/filename, NOT admin/files/filename * @return true / false */ - public static function isLegacyEncryptedContent( $data, $path ) { - - $trimmed = ltrim( $path, '/' ); - - // Path must not include user/files - $split = explode( '/', $trimmed ); - $sliced = array_slice( $split, 2 ); - $relPath = implode( '/', $sliced ); + public static function isLegacyEncryptedContent( $data, $relPath ) { // trigger_error("REL PATH = ".var_export($relPath, 1)); @@ -200,7 +195,7 @@ class Crypt { // Fetch all file metadata from DB $metadata = \OC\Files\Filesystem::getFileInfo( $relPath, '' ); - trigger_error("PATH = ". var_export($trimmed, 1)." METADATA = ".var_export($metadata['encrypted'], 1)); + trigger_error("PATH = ". var_export($relPath, 1)." METADATA = ".var_export($metadata['encrypted'], 1)); // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 89fe79b6ff..a16bf94160 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -251,6 +251,7 @@ class Util { ) { $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file ); + $relPath = $this->stripUserFilesPath( $filePath ); // If the path is a directory, search // its contents @@ -286,7 +287,7 @@ class Util { // If the file uses old // encryption system - } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ), $filePath ) ) { + } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ), $relPath ) ) { $found['legacy'][] = array( 'name' => $file, 'path' => $filePath ); @@ -341,6 +342,20 @@ class Util { } + /** + * @brief Format a path to be relative to the /user/files/ directory + */ + public function stripUserFilesPath( $path ) { + + $trimmed = ltrim( $path, '/' ); + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); + + return $relPath; + + } + /** * @brief Encrypt all files in a directory * @param string $publicKey the public key to encrypt files with @@ -365,11 +380,7 @@ class Util { // Encrypt data, generate catfile $encrypted = Crypt::keyEncryptKeyfile( $plainData, $publicKey ); - // Format path to be relative to user files dir - $trimmed = ltrim( $plainFile['path'], '/' ); - $split = explode( '/', $trimmed ); - $sliced = array_slice( $split, 2 ); - $relPath = implode( '/', $sliced ); + $relPath = $this->stripUserFilesPath( $plainFile['path'] ); // Save keyfile Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encrypted['key'] ); @@ -401,11 +412,7 @@ class Util { // Recrypt data, generate catfile $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); - // Format path to be relative to user files dir - $trimmed = ltrim( $legacyFile['path'], '/' ); - $split = explode( '/', $trimmed ); - $sliced = array_slice( $split, 2 ); - $relPath = implode( '/', $sliced ); + $relPath = $this->stripUserFilesPath( $legacyFile['path'] ); // Save keyfile Keymanager::setFileKey( $this->view, $relPath, $this->userId, $recrypted['key'] ); From 221b69dd0ed1c493e2bd6d19e88b5e3dec97bd6e Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 16:09:01 +0000 Subject: [PATCH 27/31] Fixed bug relating to Filesystem{} that prevented webdav logins with files_encryption --- apps/files_encryption/hooks/hooks.php | 100 +++++++++++++------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index cb9993b238..065ef9d241 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -37,61 +37,63 @@ class Hooks { * @note This method should never be called for users using client side encryption */ public static function login( $params ) { - - $view = new \OC_FilesystemView( '/' ); + + \OC\Files\Filesystem::init( $params['uid'] . '/' . 'files' . '/' ); + + $view = new \OC_FilesystemView( '/' ); - $util = new Util( $view, $params['uid'] ); - - if ( ! $util->ready() ) { - - \OC_Log::write( 'Encryption library', 'User account "' . $params['uid'] . '" is not ready for encryption; configuration started', \OC_Log::DEBUG ); - - return $util->setupServerSide( $params['password'] ); - - } + $util = new Util( $view, $params['uid'] ); - \OC_FileProxy::$enabled = false; + if ( ! $util->ready() ) { - $encryptedKey = Keymanager::getPrivateKey( $view, $params['uid'] ); + \OC_Log::write( 'Encryption library', 'User account "' . $params['uid'] . '" is not ready for encryption; configuration started', \OC_Log::DEBUG ); - \OC_FileProxy::$enabled = true; + return $util->setupServerSide( $params['password'] ); + + } + + \OC_FileProxy::$enabled = false; + + $encryptedKey = Keymanager::getPrivateKey( $view, $params['uid'] ); + + \OC_FileProxy::$enabled = true; + + $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); + + $session = new Session(); + + $session->setPrivateKey( $privateKey, $params['uid'] ); + + $view1 = new \OC_FilesystemView( '/' . $params['uid'] ); + + // Set legacy encryption key if it exists, to support + // depreciated encryption system + if ( + $view1->file_exists( 'encryption.key' ) + && $encLegacyKey = $view1->file_get_contents( 'encryption.key' ) + ) { + + $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] ); - $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); + $session->setLegacyKey( $plainLegacyKey ); + + } + + $publicKey = Keymanager::getPublicKey( $view, $params['uid'] ); + + // Encrypt existing user files: + // This serves to upgrade old versions of the encryption + // app (see appinfo/spec.txt) + if ( + $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] ) + ) { - $session = new Session(); - - $session->setPrivateKey( $privateKey, $params['uid'] ); - - $view1 = new \OC_FilesystemView( '/' . $params['uid'] ); - - // Set legacy encryption key if it exists, to support - // depreciated encryption system - if ( - $view1->file_exists( 'encryption.key' ) - && $encLegacyKey = $view1->file_get_contents( 'encryption.key' ) - ) { - - $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] ); - - $session->setLegacyKey( $plainLegacyKey ); - - } - - $publicKey = Keymanager::getPublicKey( $view, $params['uid'] ); - - // Encrypt existing user files: - // This serves to upgrade old versions of the encryption - // app (see appinfo/spec.txt) - if ( - $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] ) - ) { - - \OC_Log::write( - 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" started at login' - , \OC_Log::INFO - ); - - } + \OC_Log::write( + 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" started at login' + , \OC_Log::INFO + ); + + } return true; From 680c5b3dad9f83b912da3a0629060525d08c2165 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 16:11:50 +0000 Subject: [PATCH 28/31] Removed debugging output --- apps/files_encryption/lib/crypt.php | 6 ------ apps/files_encryption/lib/util.php | 6 ------ 2 files changed, 12 deletions(-) diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index ff7d6dfb1f..e3ffacabc9 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -187,16 +187,10 @@ class Crypt { * @return true / false */ public static function isLegacyEncryptedContent( $data, $relPath ) { - -// trigger_error("REL PATH = ".var_export($relPath, 1)); - -// trigger_error( "DATA = ".var_export($data, 1). " CATFILE?: ".var_export( self::isCatfile( $data ), 1)); // Fetch all file metadata from DB $metadata = \OC\Files\Filesystem::getFileInfo( $relPath, '' ); - trigger_error("PATH = ". var_export($relPath, 1)." METADATA = ".var_export($metadata['encrypted'], 1)); - // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the // legacy encryption system diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index a16bf94160..355ffb90ef 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -269,8 +269,6 @@ class Util { $data = $this->view->file_get_contents( $filePath ); -// trigger_error("HAKE \n".var_export($this->view->file_get_contents( $filePath ), 1)." \nfilepath = ".var_export($filePath, 1 )); - // If the file is encrypted // NOTE: If the userId is // empty or not set, file will @@ -366,8 +364,6 @@ class Util { if ( $found = $this->findFiles( $dirPath ) ) { -// trigger_error("FOUND = ".print_r($found, 1)); - // Disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; @@ -407,8 +403,6 @@ class Util { // Fetch data from file $legacyData = $this->view->file_get_contents( $legacyFile['path'] ); - trigger_error("\n\nlegdata = ".var_export($legacyData, 1).' \n\npassphrase = '.var_export($legacyPassphrase, 1).' \n\npublickey = '.var_export($publicKey, 1).' \n\nnewpass = '.var_export($newPassphrase, 1)); - // Recrypt data, generate catfile $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKey, $newPassphrase ); From b84e83261ec8caf2ce128017d703e4139e3f6211 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 17:06:15 +0000 Subject: [PATCH 29/31] Added notice to personal settings indicating what filetypes are not encrypted --- apps/files_encryption/appinfo/app.php | 5 +-- apps/files_encryption/settings-personal.php | 24 ++++------- .../templates/settings-personal.php | 42 +++++++------------ 3 files changed, 23 insertions(+), 48 deletions(-) diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 20045f34b0..e426f237bb 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -43,7 +43,6 @@ if ( } +// Reguster settings scripts OCP\App::registerAdmin( 'files_encryption', 'settings' ); - -// This is disabled until client-side encryption is supported: -// OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); \ No newline at end of file +OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); \ No newline at end of file diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index 014288f2ef..6fe4ea6d56 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -1,29 +1,19 @@ + * Copyright (c) 2013 Sam Tuke * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ -$sysEncMode = \OC_Appconfig::getValue('files_encryption', 'mode', 'none'); +$tmpl = new OCP\Template( 'files_encryption', 'settings-personal'); -if ($sysEncMode == 'user') { +$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', 'jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) ); - $tmpl = new OCP\Template( 'files_encryption', 'settings-personal'); +$tmpl->assign( 'blacklist', $blackList ); - $query = \OC_DB::prepare( "SELECT mode FROM *PREFIX*encryption WHERE uid = ?" ); - $result = $query->execute(array(\OCP\User::getUser())); - - if ($row = $result->fetchRow()){ - $mode = $row['mode']; - } else { - $mode = 'none'; - } - - OCP\Util::addscript('files_encryption','settings-personal'); - $tmpl->assign('encryption_mode', $mode); - return $tmpl->fetchPage(); -} +OCP\Util::addscript('files_encryption','settings-personal'); + +return $tmpl->fetchPage(); return null; diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index ad34a0d78b..5931a4cdeb 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -1,34 +1,20 @@
    - t( 'Choose encryption mode:' ); ?> + + t( 'Encryption' ); ?> +

    - - - - /> - t( 'Server side encryption (allows you to access your files from the web interface)' ); ?> -
    - - - /> - t( 'None (no encryption at all)' ); ?> -
    + t( 'File encryption is enabled.' ); ?>

    + +

    The following file types will not be encrypted:

    +
      + +
    • + +
    • + +

      +
    From 4ba0ab7f65160661201b1d925cec9d29b47cab09 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 17:22:59 +0000 Subject: [PATCH 30/31] Added missing translation wrapping --- apps/files_encryption/templates/settings-personal.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 5931a4cdeb..1f71efb173 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -7,7 +7,9 @@ t( 'File encryption is enabled.' ); ?>

    -

    The following file types will not be encrypted:

    +

    + t( 'The following file types will not be encrypted:' ); ?> +

    • From 20b1d12cbfc65b604acdaac84272f6af8b0d7be4 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Tue, 5 Feb 2013 17:28:26 +0000 Subject: [PATCH 31/31] Fixed comment typo, wrapped return value conditional on var assignment in session{} --- apps/files_encryption/lib/session.php | 6 ++++-- apps/files_encryption/lib/stream.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index bda22ee3a0..769a40b359 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -70,9 +70,11 @@ class Session { */ public function setLegacyKey( $legacyKey ) { - $_SESSION['legacyKey'] = $legacyKey; + if ( $_SESSION['legacyKey'] = $legacyKey ) { - return true; + return true; + + } } diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 4102a681d7..d4b993b4c0 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -347,7 +347,7 @@ class Stream { // // // Make sure we always start on a block start if ( 0 != ( $pointer % 8192 ) ) { - // if the current positoin of + // if the current position of // file indicator is not aligned to a 8192 byte block, fix it // so that it is