From 14451bdaf07f88c6ac46092c74b987a360b04547 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Fri, 29 Mar 2013 21:11:29 +0100 Subject: Development snapshot; Fixed errors from Hooks::login(); Work on enable/disable recoveryAdmin for lost passwords in settings page (template, ajax, js); Work on fixing sharing files to users (still broken); --- apps/files_encryption/js/settings.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'apps/files_encryption/js/settings.js') diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 0be857bb73e..4f367f880db 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -6,12 +6,26 @@ $(document).ready(function(){ + // Trigger ajax on filetype blacklist change $('#encryption_blacklist').multiSelect({ oncheck:blackListChange, onuncheck:blackListChange, createText:'...' }); + // Trigger ajax on recoveryAdmin status change + $( 'input:radio[name="adminEnableRecovery"]' ).change( + function() { + $.post( + '../ajax/adminrecovery.php' + , $( this ).val() + , function( data ) { + // TODO: provide user with feedback of outcome + } + ); + } + ); + function blackListChange(){ var blackList=$('#encryption_blacklist').val().join(','); OC.AppConfig.setValue('files_encryption','type_blacklist',blackList); -- cgit v1.2.3 From f378a7f572e1da4b24280c1fcbf830e026186c83 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 10 Apr 2013 17:37:03 +0200 Subject: Fixed proxy class handing of read / write files Various work on other classes --- apps/files_encryption/ajax/adminrecovery.php | 12 +++-- apps/files_encryption/appinfo/app.php | 6 ++- apps/files_encryption/hooks/hooks.php | 10 ++-- apps/files_encryption/js/settings.js | 9 ++-- apps/files_encryption/lib/proxy.php | 49 +++++++++---------- apps/files_encryption/lib/stream.php | 2 +- apps/files_encryption/lib/util.php | 70 ++++++++++++++++++++++------ apps/files_encryption/test/proxy.php | 2 +- apps/files_encryption/test/util.php | 12 +++++ 9 files changed, 114 insertions(+), 58 deletions(-) (limited to 'apps/files_encryption/js/settings.js') diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index f22114f8514..cec0cd4ddda 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -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 diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 9747fb20ad6..c2de9d0b441 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -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() ) diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 82de80a1cf4..e65f0945f41 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -63,7 +63,7 @@ class Hooks { $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); - $session = new Session($view); + $session = new Session( $view ); $session->setPrivateKey( $privateKey, $params['uid'] ); @@ -116,8 +116,8 @@ class Hooks { // is in use (client-side encryption does not have access to // the necessary keys) if ( Crypt::mode() == 'server' ) { - $view = new \OC_FilesystemView( '/' ); - $session = new Session($view); + + $session = new Session(); // Get existing decrypted private key $privateKey = $session->getPrivateKey(); @@ -189,7 +189,7 @@ class Hooks { if ( $params['itemType'] === 'file' ) { $view = new \OC_FilesystemView( '/' ); - $session = new Session($view); + $session = new Session(); $userId = \OCP\User::getUser(); $util = new Util( $view, $userId ); $path = $util->fileIdToPath( $params['itemSource'] ); @@ -244,7 +244,7 @@ class Hooks { if ( $params['itemType'] === 'file' ) { $view = new \OC_FilesystemView( '/' ); - $session = new Session($view); + $session = new Session(); $userId = \OCP\User::getUser(); $util = new Util( $view, $userId ); $path = $util->fileIdToPath( $params['itemSource'] ); diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 4f367f880db..9a0bebf2478 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -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 ); } ); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7e18ec9b104..44a2e1aae55 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -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)); diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index d269a562404..7315245fcce 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -236,7 +236,7 @@ class Stream { $this->getUser(); - $session = new Session($this->rootView); + $session = new Session( $this->rootView ); $privateKey = $session->getPrivateKey( $this->userId ); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 420e3398a8d..dc4e37150c5 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -24,13 +24,17 @@ # 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 . '"' ); + + } + } } diff --git a/apps/files_encryption/test/proxy.php b/apps/files_encryption/test/proxy.php index 709730f7609..5a2d851ff7c 100644 --- a/apps/files_encryption/test/proxy.php +++ b/apps/files_encryption/test/proxy.php @@ -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----- diff --git a/apps/files_encryption/test/util.php b/apps/files_encryption/test/util.php index e2767a2ec39..3ebc484809b 100755 --- a/apps/files_encryption/test/util.php +++ b/apps/files_encryption/test/util.php @@ -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 -- cgit v1.2.3 From ba29147e34a22142c4bfd2afa3f5b9f1e6efcd63 Mon Sep 17 00:00:00 2001 From: Sam Tuke Date: Wed, 1 May 2013 19:18:31 +0200 Subject: Fixed recoveryadmin settings in user and admin settings pages (js, templates, ajax) Renamed recovery methods in Util{} for clarity Added note about bug causing slow page load and redundant keypair generation recoveryAdmin functionality not yet complete --- apps/files_encryption/ajax/adminrecovery.php | 27 ++++++-- apps/files_encryption/ajax/userrecovery.php | 9 +-- apps/files_encryption/appinfo/app.php | 4 +- apps/files_encryption/js/settings-admin.js | 37 ++++++++++ apps/files_encryption/js/settings-personal.js | 23 +++++++ apps/files_encryption/js/settings.js | 36 ---------- apps/files_encryption/lib/keymanager.php | 2 +- apps/files_encryption/lib/session.php | 18 +++-- apps/files_encryption/lib/util.php | 79 ++++++++++++++-------- apps/files_encryption/settings-admin.php | 28 ++++++++ apps/files_encryption/settings-personal.php | 20 ++++++ apps/files_encryption/settings.php | 27 -------- apps/files_encryption/templates/settings-admin.php | 39 +++++++++++ .../templates/settings-personal.php | 22 ++++++ apps/files_encryption/templates/settings.php | 39 ----------- apps/files_encryption/tests/util.php | 14 ++-- 16 files changed, 267 insertions(+), 157 deletions(-) create mode 100644 apps/files_encryption/js/settings-admin.js create mode 100644 apps/files_encryption/js/settings-personal.js delete mode 100644 apps/files_encryption/js/settings.js create mode 100644 apps/files_encryption/settings-admin.php delete mode 100644 apps/files_encryption/settings.php create mode 100644 apps/files_encryption/templates/settings-admin.php delete mode 100644 apps/files_encryption/templates/settings.php (limited to 'apps/files_encryption/js/settings.js') diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index cec0cd4ddda..157fc8f313c 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -17,11 +17,12 @@ use OCA\Encryption; $return = $doSetup = false; +// Enable recoveryAdmin if ( isset( $_POST['adminEnableRecovery'] ) - && $_POST['adminEnableRecovery'] == 1 - && isset( $_POST['recoveryPassword'] ) - && ! empty ( $_POST['recoveryPassword'] ) + && 1 == $_POST['adminEnableRecovery'] +// && isset( $_POST['recoveryPassword'] ) +// && ! empty ( $_POST['recoveryPassword'] ) ) { // TODO: Let the admin set this themselves @@ -29,7 +30,7 @@ if ( // If desired recoveryAdmin UID is already in use if ( ! \OC_User::userExists( $recoveryAdminUid ) ) { - + // Create new recoveryAdmin user \OC_User::createUser( $recoveryAdminUid, $_POST['recoveryPassword'] ); @@ -55,11 +56,11 @@ if ( } - // If recoveryAdmin has passed other checks + // Setup recoveryAdmin user for encryption if ( $doSetup ) { $view = new \OC_FilesystemView( '/' ); - $util = new Util( $view, $recoveryAdminUid ); + $util = new \OCA\Encryption\Util( $view, $recoveryAdminUid ); // Ensure recoveryAdmin is ready for encryption (has usable keypair etc.) $util->setupServerSide( $_POST['recoveryPassword'] ); @@ -71,6 +72,20 @@ if ( } + // Set recoveryAdmin as enabled + OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminEnabled', 1 ); + +// Disable recoveryAdmin +} elseif ( + isset( $_POST['adminEnableRecovery'] ) + && 0 == $_POST['adminEnableRecovery'] +) { + + // Set recoveryAdmin as enabled + OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminEnabled', 0 ); + + $return = true; + } ($return) ? OC_JSON::success() : OC_JSON::error(); \ No newline at end of file diff --git a/apps/files_encryption/ajax/userrecovery.php b/apps/files_encryption/ajax/userrecovery.php index 56c18f7ad5b..f72be3181ef 100644 --- a/apps/files_encryption/ajax/userrecovery.php +++ b/apps/files_encryption/ajax/userrecovery.php @@ -13,21 +13,18 @@ use OCA\Encryption; \OCP\JSON::checkLoggedIn(); \OCP\JSON::checkAppEnabled( 'files_encryption' ); -\OCP\JSON::callCheck(); if ( isset( $_POST['userEnableRecovery'] ) + && ( 0 == $_POST['userEnableRecovery'] || 1 == $_POST['userEnableRecovery'] ) ) { - // Ensure preference is an integer - $recoveryEnabled = intval( $_POST['userEnableRecovery'] ); - $userId = \OCP\USER::getUser(); $view = new \OC_FilesystemView( '/' ); - $util = new Util( $view, $userId ); + $util = new \OCA\Encryption\Util( $view, $userId ); // Save recovery preference to DB - $result = $util->setRecovery( $recoveryEnabled ); + $result = $util->setRecoveryForUser( $_POST['userEnableRecovery'] ); if ( $result ) { diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 9ae6c8331f8..a7253c43332 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -28,7 +28,7 @@ OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'p stream_wrapper_register( 'crypt', 'OCA\Encryption\Stream' ); -$view = new OC_FilesystemView( '/' ); +$view = new \OC\Files\View( '/' ); $session = new OCA\Encryption\Session( $view ); @@ -50,5 +50,5 @@ if ( } // Register settings scripts -OCP\App::registerAdmin( 'files_encryption', 'settings' ); +OCP\App::registerAdmin( 'files_encryption', 'settings-admin' ); OCP\App::registerPersonal( 'files_encryption', 'settings-personal' ); diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js new file mode 100644 index 00000000000..48b5598d524 --- /dev/null +++ b/apps/files_encryption/js/settings-admin.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2013, Sam Tuke , Robin Appelman + * + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + + +$(document).ready(function(){ + // Trigger ajax on filetype blacklist change + $('#encryption_blacklist').multiSelect({ + oncheck:blackListChange, + onuncheck:blackListChange, + createText:'...' + }); + + // Trigger ajax on recoveryAdmin status change + $( 'input:radio[name="adminEnableRecovery"]' ).change( + function() { + + var recoveryStatus = $( this ).val(); + + $.post( + OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) + , { adminEnableRecovery: recoveryStatus, recoveryPassword: 'password' } + , function( data ) { + alert( data ); + } + ); + } + ); + + function blackListChange(){ + var blackList=$( '#encryption_blacklist' ).val().join( ',' ); + OC.AppConfig.setValue( 'files_encryption', 'type_blacklist', blackList ); + } +}) \ No newline at end of file diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js new file mode 100644 index 00000000000..e4a1b7448f4 --- /dev/null +++ b/apps/files_encryption/js/settings-personal.js @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2013, Sam Tuke + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +$(document).ready(function(){ + // Trigger ajax on recoveryAdmin status change + $( 'input:radio[name="userEnableRecovery"]' ).change( + function() { + + var recoveryStatus = $( this ).val(); + + $.post( + OC.filePath( 'files_encryption', 'ajax', 'userrecovery.php' ) + , { userEnableRecovery: recoveryStatus } + , function( data ) { + alert( data ); + } + ); + } + ); +}) \ No newline at end of file diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js deleted file mode 100644 index 9a0bebf2478..00000000000 --- a/apps/files_encryption/js/settings.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2011, Robin Appelman - * This file is licensed under the Affero General Public License version 3 or later. - * See the COPYING-README file. - */ - - -$(document).ready(function(){ - // Trigger ajax on filetype blacklist change - $('#encryption_blacklist').multiSelect({ - oncheck:blackListChange, - onuncheck:blackListChange, - createText:'...' - }); - - // Trigger ajax on recoveryAdmin status change - $( 'input:radio[name="adminEnableRecovery"]' ).change( - function() { - - var foo = $( this ).val(); - - $.post( - OC.filePath('files_encryption', 'ajax', 'adminrecovery.php') - , { adminEnableRecovery: foo, recoveryPassword: 'password' } - , function( data ) { - alert( data ); - } - ); - } - ); - - function blackListChange(){ - var blackList=$('#encryption_blacklist').val().join(','); - OC.AppConfig.setValue('files_encryption','type_blacklist',blackList); - } -}) \ No newline at end of file diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 9f3cb8120ca..51d4f8ffc04 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -32,7 +32,7 @@ class Keymanager { /** * @brief retrieve the ENCRYPTED private key from a user * - * @return string private key or false + * @return string private key or false (hopefully) * @note the key returned by this method must be decrypted before use */ public static function getPrivateKey( \OC_FilesystemView $view, $user ) { diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 0c6a7131fd9..0e6bb96605f 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -35,22 +35,28 @@ class Session { * * The ownCloud key pair is used to allow public link sharing even if encryption is enabled */ - public function __construct( \OC_FilesystemView $view ) { + public function __construct( $view ) { $this->view = $view; if ( ! $this->view->is_dir( 'owncloud_private_key' ) ) { - $this->view->mkdir('owncloud_private_key'); + $this->view->mkdir( 'owncloud_private_key' ); + } - if ( - ! $this->view->file_exists("/public-keys/owncloud.public.key") - || ! $this->view->file_exists("/owncloud_private_key/owncloud.private.key" ) + ! $this->view->file_exists( "/public-keys/owncloud.public.key" ) + || ! $this->view->file_exists( "/owncloud_private_key/owncloud.private.key" ) ) { - + + //FIXME: Bug: for some reason file_exists is returning + // false in above if statement, and causing new keys + // to be generated on each page load. At last check + // our app.php is being executed 18 times per page load + // , causing 18 new keypairs and huge performance hit. + $keypair = Crypt::createKeypair(); \OC_FileProxy::$enabled = false; diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index eabb34f7ab0..015125370bc 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -24,11 +24,8 @@ # 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 (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) -# encryptAll during login mangles paths: /files/files/ -# encryptAll is accessing files via encryption proxy - perhaps proxies should be disabled? # Missing features @@ -204,12 +201,18 @@ class Util { $this->view->file_put_contents( $this->privateKeyPath, $encryptedPrivateKey ); \OC_FileProxy::$enabled = true; - - // create database configuration - $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery`) VALUES (?,?,?)'; - $args = array( $this->userId, 'server-side', 0); - $query = \OCP\DB::prepare( $sql ); - $query->execute( $args ); + + } + + // If there's no record for this user's encryption preferences + if ( false === $this->recoveryEnabledForUser() ) { + + // create database configuration + $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery`) VALUES (?,?,?)'; + $args = array( $this->userId, 'server-side', 0); + $query = \OCP\DB::prepare( $sql ); + $query->execute( $args ); + } return true; @@ -218,11 +221,11 @@ class Util { /** * @brief Check whether pwd recovery is enabled for a given user - * @return bool + * @return 1 = yes, 0 = no, false = no record * @note If records are not being returned, check for a hidden space * at the start of the uid in db */ - public function recoveryEnabled() { + public function recoveryEnabledForUser() { $sql = 'SELECT recovery @@ -237,16 +240,25 @@ class Util { $result = $query->execute( $args ); - // Set default in case no records found - $recoveryEnabled = 0; + $recoveryEnabled = array(); while( $row = $result->fetchRow() ) { - $recoveryEnabled = $row['recovery']; + $recoveryEnabled[] = $row['recovery']; } - return $recoveryEnabled; + // If no record is found + if ( empty( $recoveryEnabled ) ) { + + return false; + + // If a record is found + } else { + + return $recoveryEnabled[0]; + + } } @@ -255,20 +267,33 @@ class Util { * @param bool $enabled Whether to enable or disable recovery * @return bool */ - public function setRecovery( $enabled ) { + public function setRecoveryForUser( $enabled ) { - $sql = 'UPDATE - *PREFIX*encryption - SET - recovery = ? - WHERE - uid = ?'; + $recoveryStatus = $this->recoveryEnabledForUser(); + + // If a record for this user already exists, update it + if ( false === $recoveryStatus ) { - // Ensure value is an integer - $enabled = intval( $enabled ); + $sql = 'INSERT INTO `*PREFIX*encryption` + (`uid`,`mode`,`recovery`) + VALUES (?,?,?)'; + + $args = array( $this->userId, 'server-side', $enabled ); - $args = array( $enabled, $this->userId ); - + // Create a new record instead + } else { + + $sql = 'UPDATE + *PREFIX*encryption + SET + recovery = ? + WHERE + uid = ?'; + + $args = array( $enabled, $this->userId ); + + } + $query = \OCP\DB::prepare( $sql ); if ( $query->execute( $args ) ) { @@ -888,7 +913,7 @@ class Util { public function getSharingUsersArray( $sharingEnabled, $filePath, $currentUserId = false ) { // Check if key recovery is enabled - $recoveryEnabled = $this->recoveryEnabled(); + $recoveryEnabled = $this->recoveryEnabledForUser(); // Make sure that a share key is generated for the owner too list($owner, $ownerPath) = $this->getUidAndFilename($filePath); diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php new file mode 100644 index 00000000000..b09515f0c33 --- /dev/null +++ b/apps/files_encryption/settings-admin.php @@ -0,0 +1,28 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +\OC_Util::checkAdminUser(); + +$tmpl = new OCP\Template( 'files_encryption', 'settings-admin' ); + +$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', '' ) ); + +// Check if an adminRecovery account is enabled for recovering files after lost pwd +$view = new OC_FilesystemView( '' ); + +$recoveryAdminEnabled = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' ); +$recoveryAdminUid = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminUid' ); + +$tmpl->assign( 'blacklist', $blackList ); +$tmpl->assign( 'encryption_mode', \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ) ); +$tmpl->assign( 'recoveryEnabled', $recoveryAdminEnabled ); + +\OCP\Util::addscript( 'files_encryption', 'settings-admin' ); +\OCP\Util::addscript( 'core', 'multiselect' ); + +return $tmpl->fetchPage(); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index c001bb0d725..f7ebc425120 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -10,6 +10,26 @@ $tmpl = new OCP\Template( 'files_encryption', 'settings-personal'); $blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', '' ) ); +// Add human readable message in case nothing is blacklisted +if ( + 1 == count( $blackList ) + && $blackList[0] == '' +) { + + // FIXME: Make this string translatable + $blackList[0] = "(None - all filetypes will be encrypted)"; + +} + +$user = \OCP\USER::getUser(); +$view = new \OC_FilesystemView( '/' ); +$util = new \OCA\Encryption\Util( $view, $user ); + +$recoveryEnabledForUser = $util->recoveryEnabledForUser(); + +\OCP\Util::addscript( 'files_encryption', 'settings-personal' ); + +$tmpl->assign( 'recoveryEnabled', $recoveryEnabledForUser ); $tmpl->assign( 'blacklist', $blackList ); return $tmpl->fetchPage(); diff --git a/apps/files_encryption/settings.php b/apps/files_encryption/settings.php deleted file mode 100644 index 71d47f061af..00000000000 --- a/apps/files_encryption/settings.php +++ /dev/null @@ -1,27 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -\OC_Util::checkAdminUser(); - -$tmpl = new OCP\Template( 'files_encryption', 'settings' ); - -$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', '' ) ); - -// Check if an adminRecovery account is enabled for recovering files after lost pwd -$view = new OC_FilesystemView( '' ); -$util = new \OCA\Encryption\Util( $view, \OCP\USER::getUser() ); -$recoveryEnabled = $util->recoveryEnabled(); - -$tmpl->assign( 'blacklist', $blackList ); -$tmpl->assign( 'encryption_mode', \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ) ); -$tmpl->assign( 'recoveryEnabled', $recoveryEnabled ); - -\OCP\Util::addscript( 'files_encryption', 'settings' ); -\OCP\Util::addscript( 'core', 'multiselect' ); - -return $tmpl->fetchPage(); diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php new file mode 100644 index 00000000000..6499d0c8e80 --- /dev/null +++ b/apps/files_encryption/templates/settings-admin.php @@ -0,0 +1,39 @@ +
+
+ +

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

+

+ t( "Enable encryption passwords recovery account (allow sharing to recovery account):" )); ?> +
+ /> + t( "Enabled" )); ?> +
+ + /> + t( "Disabled" )); ?> +

+
+
diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 5f0accaed5f..0cefde36b61 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -3,6 +3,7 @@ t( 'Encryption' )); ?> +

t( 'File encryption is enabled.' )); ?>

@@ -10,6 +11,7 @@

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

+
  • @@ -18,5 +20,25 @@
+ +

+ t( "Enable password recovery by sharing all files with administrator:" )); ?> +
+ /> + t( "Enabled" )); ?> +
+ + /> + t( "Disabled" )); ?> +

+ diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php deleted file mode 100644 index 6499d0c8e80..00000000000 --- a/apps/files_encryption/templates/settings.php +++ /dev/null @@ -1,39 +0,0 @@ -
-
- -

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

-

- t( "Enable encryption passwords recovery account (allow sharing to recovery account):" )); ?> -
- /> - t( "Enabled" )); ?> -
- - /> - t( "Disabled" )); ?> -

-
-
diff --git a/apps/files_encryption/tests/util.php b/apps/files_encryption/tests/util.php index e3ec0860fa5..d0a988f96b9 100755 --- a/apps/files_encryption/tests/util.php +++ b/apps/files_encryption/tests/util.php @@ -179,23 +179,23 @@ class Test_Enc_Util extends \PHPUnit_Framework_TestCase { } - function testRecoveryEnabled() { + function testRecoveryEnabledForUser() { $util = new Encryption\Util( $this->view, $this->userId ); // Record the value so we can return it to it's original state later - $enabled = $util->recoveryEnabled(); + $enabled = $util->recoveryEnabledForUser(); - $this->assertTrue( $util->setRecovery( 1 ) ); + $this->assertTrue( $util->setRecoveryForUser( 1 ) ); - $this->assertEquals( 1, $util->recoveryEnabled() ); + $this->assertEquals( 1, $util->recoveryEnabledForUser() ); - $this->assertTrue( $util->setRecovery( 0 ) ); + $this->assertTrue( $util->setRecoveryForUser( 0 ) ); - $this->assertEquals( 0, $util->recoveryEnabled() ); + $this->assertEquals( 0, $util->recoveryEnabledForUser() ); // Return the setting to it's previous state - $this->assertTrue( $util->setRecovery( $enabled ) ); + $this->assertTrue( $util->setRecoveryForUser( $enabled ) ); } -- cgit v1.2.3