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)'); ?>
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