aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_encryption
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_encryption')
-rw-r--r--apps/files_encryption/hooks/hooks.php73
-rw-r--r--apps/files_encryption/js/settings-admin.js2
-rwxr-xr-xapps/files_encryption/lib/helper.php2
-rw-r--r--apps/files_encryption/lib/util.php84
4 files changed, 138 insertions, 23 deletions
diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index f843c7027d5..0af0845d7c1 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -142,32 +142,67 @@ class Hooks {
* @brief Change a user's encryption passphrase
* @param array $params keys: uid, password
*/
- public static function setPassphrase( $params ) {
-
+ public static function setPassphrase($params) {
+
// Only attempt to change passphrase if server-side encryption
// is in use (client-side encryption does not have access to
// the necessary keys)
- if ( Crypt::mode() == 'server' ) {
+ if (Crypt::mode() == 'server') {
- $view = new \OC_FilesystemView( '/' );
+ if ($params['uid'] == \OCP\User::getUser()) {
- $session = new Session($view);
-
- // Get existing decrypted private key
- $privateKey = $session->getPrivateKey();
-
- // Encrypt private key with new user pwd as passphrase
- $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $privateKey, $params['password'] );
-
- // Save private key
- Keymanager::setPrivateKey( $encryptedPrivateKey );
-
- // NOTE: Session does not need to be updated as the
- // private key has not changed, only the passphrase
- // used to decrypt it has changed
+ $view = new \OC_FilesystemView('/');
+
+ $session = new Session($view);
+
+ // Get existing decrypted private key
+ $privateKey = $session->getPrivateKey();
+
+ // Encrypt private key with new user pwd as passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($privateKey, $params['password']);
+
+ // Save private key
+ Keymanager::setPrivateKey($encryptedPrivateKey);
+
+ // NOTE: Session does not need to be updated as the
+ // private key has not changed, only the passphrase
+ // used to decrypt it has changed
+
+ } else { // admin changed the password for a different user, create new keys and reencrypt file keys
+
+ $user = $params['uid'];
+ $recoveryPassword = $params['recoveryPassword'];
+ $newUserPassword = $params['password'];
+
+ $view = new \OC_FilesystemView('/');
+
+ // make sure that the users home is mounted
+ \OC\Files\Filesystem::initMountPoints($user);
+
+ $keypair = Crypt::createKeypair();
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ // Save public key
+ $view->file_put_contents( '/public-keys/'.$user.'.public.key', $keypair['publicKey'] );
+
+ // Encrypt private key empthy passphrase
+ $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $newUserPassword );
+
+ // Save private key
+ $view->file_put_contents( '/'.$user.'/files_encryption/'.$user.'.private.key', $encryptedPrivateKey );
+
+ if ( $recoveryPassword ) { // if recovery key is set we can re-encrypt the key files
+ $util = new Util($view, $user);
+ $util->recoverUsersFiles($recoveryPassword);
+ }
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
}
-
}
/*
diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js
index 9bc6ab6433c..dbae42b011c 100644
--- a/apps/files_encryption/js/settings-admin.js
+++ b/apps/files_encryption/js/settings-admin.js
@@ -69,7 +69,7 @@ $(document).ready(function(){
}
);
- // change password
+ // change recovery password
$('input:password[name="changeRecoveryPassword"]').keyup(function(event) {
var oldRecoveryPassword = $('input:password[id="oldRecoveryPassword"]').val();
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 6d5aae4e8b5..86d860465e6 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -46,7 +46,7 @@ class Helper {
public static function registerUserHooks() {
\OCP\Util::connectHook( 'OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login' );
- \OCP\Util::connectHook( 'OC_User', 'pre_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' );
+ \OCP\Util::connectHook( 'OC_User', 'post_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' );
\OCP\Util::connectHook( 'OC_User', 'post_createUser', 'OCA\Encryption\Hooks', 'postCreateUser' );
\OCP\Util::connectHook( 'OC_User', 'post_deleteUser', 'OCA\Encryption\Hooks', 'postDeleteUser' );
}
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 91d86cc8558..fab807b0141 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -929,7 +929,7 @@ class Util {
// Get the current users's private key for decrypting existing keyfile
$privateKey = $session->getPrivateKey();
-
+
$fileOwner = \OC\Files\Filesystem::getOwner( $filePath );
// Decrypt keyfile
@@ -1336,7 +1336,7 @@ class Util {
}
}
- /**
+ /**
* @brief remove recovery key to all encrypted files
*/
public function removeRecoveryKeys($path = '/') {
@@ -1351,4 +1351,84 @@ class Util {
}
}
}
+
+ /**
+ * @brief decrypt given file with recovery key and encrypt it again to the owner and his new key
+ * @param type $file
+ * @param type $privateKey recovery key to decrypt the file
+ */
+ private function recoverFile($file, $privateKey) {
+
+ $sharingEnabled = \OCP\Share::isEnabled();
+
+ // Find out who, if anyone, is sharing the file
+ if ($sharingEnabled) {
+ $result = \OCP\Share::getUsersSharingFile($file, $this->userId, true, true, true);
+ $userIds = $result['users'];
+ $userIds[] = $this->recoveryKeyId;
+ if ($result['public']) {
+ $userIds[] = $this->publicShareKeyId;
+ }
+ } else {
+ $userIds = array($this->userId, $this->recoveryKeyId);
+ }
+ $filteredUids = $this->filterShareReadyUsers($userIds);
+
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ //decrypt file key
+ $encKeyfile = $this->view->file_get_contents($this->keyfilesPath.$file.".key");
+ $shareKey = $this->view->file_get_contents($this->shareKeysPath.$file.".".$this->recoveryKeyId.".shareKey");
+ $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
+ // encrypt file key again to all users, this time with the new public key for the recovered use
+ $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
+ $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys);
+
+ // write new keys to filesystem TDOO!
+ $this->view->file_put_contents($this->keyfilesPath.$file.'.key', $multiEncKey['data']);
+ foreach ($multiEncKey['keys'] as $userId => $shareKey) {
+ $shareKeyPath = $this->shareKeysPath.$file.'.'.$userId.'.shareKey';
+ $this->view->file_put_contents($shareKeyPath, $shareKey);
+ }
+
+ // Return proxy to original status
+ \OC_FileProxy::$enabled = $proxyStatus;
+ }
+
+ /**
+ * @brief collect all files and recover them one by one
+ * @param type $path to look for files keys
+ * @param type $privateKey private recovery key which is used to decrypt the files
+ */
+ private function recoverAllFiles($path, $privateKey) {
+ $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path);
+ foreach ($dirContent as $item) {
+ $filePath = substr($item['path'], 25);
+ if ($item['type'] == 'dir') {
+ $this->addRecoveryKey($filePath . '/', $privateKey);
+ } else {
+ $file = substr($filePath, 0, -4);
+ $this->recoverFile($file, $privateKey);
+ }
+ }
+ }
+
+ /**
+ * @brief recover users files in case of password lost
+ * @param type $recoveryPassword
+ */
+ public function recoverUsersFiles($recoveryPassword) {
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = false;
+
+ $encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/'.$this->recoveryKeyId.'.private.key' );
+ $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $recoveryPassword );
+
+ \OC_FileProxy::$enabled = $proxyStatus;
+
+ $this->recoverAllFiles('/', $privateKey);
+ }
}