summaryrefslogtreecommitdiffstats
path: root/apps/files_encryption
diff options
context:
space:
mode:
authorBjörn Schießle <schiessle@owncloud.com>2013-05-17 11:20:17 +0200
committerBjörn Schießle <schiessle@owncloud.com>2013-05-17 11:20:17 +0200
commit0b40c1d08a107ddb0637a2793d3f044d4dfefa88 (patch)
tree34441fde8776d90c6e8bccae98828de863b9601c /apps/files_encryption
parentca6a77d39b738aeead0bbbfdfdf2a06382431f6f (diff)
parentd7dc710c8b1d46947cb2afe13152e0adc9ee5594 (diff)
downloadnextcloud-server-0b40c1d08a107ddb0637a2793d3f044d4dfefa88.tar.gz
nextcloud-server-0b40c1d08a107ddb0637a2793d3f044d4dfefa88.zip
Merge branch 'files_encryption' of github.com:owncloud/core into files_encryption
Diffstat (limited to 'apps/files_encryption')
-rw-r--r--apps/files_encryption/ajax/adminrecovery.php64
-rwxr-xr-xapps/files_encryption/lib/helper.php92
-rw-r--r--apps/files_encryption/lib/util.php4
-rwxr-xr-xapps/files_encryption/tests/crypt.php17
-rw-r--r--apps/files_encryption/tests/keymanager.php23
-rwxr-xr-xapps/files_encryption/tests/share.php144
6 files changed, 277 insertions, 67 deletions
diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php
index 0ab449709c3..dc13bc57c11 100644
--- a/apps/files_encryption/ajax/adminrecovery.php
+++ b/apps/files_encryption/ajax/adminrecovery.php
@@ -21,74 +21,14 @@ $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] == 1){
- $view = new \OC\Files\View('/');
-
- if ($recoveryKeyId === null) {
- $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8);
- \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId);
- }
-
- if (!$view->is_dir('/owncloud_private_key')) {
- $view->mkdir('/owncloud_private_key');
- }
-
- if (
- (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key")
- || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key"))
- ) {
-
- $keypair = \OCA\Encryption\Crypt::createKeypair();
-
- \OC_FileProxy::$enabled = false;
-
- // Save public key
-
- if (!$view->is_dir('/public-keys')) {
- $view->mkdir('/public-keys');
- }
-
- $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']);
-
- // Encrypt private key empthy passphrase
- $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $_POST['recoveryPassword']);
-
- // Save private key
- $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
-
- // create control file which let us check later on if the entered password was correct.
- $encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt("ownCloud", $keypair['publicKey']);
- if (!$view->is_dir('/control-file')) {
- $view->mkdir('/control-file');
- }
- $view->file_put_contents('/control-file/controlfile.enc', $encryptedControlData);
-
- \OC_FileProxy::$enabled = true;
-
- // Set recoveryAdmin as enabled
- OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
-
- $return = true;
-
- } else { // get recovery key and check the password
- $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
- $return = $util->checkRecoveryPassword($_POST['recoveryPassword']);
- if ($return) {
- OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
- }
- }
+ $return = \Helper::adminEnableRecovery($recoveryKeyId, $_POST['recoveryPassword']);
// Disable recoveryAdmin
} elseif (
isset($_POST['adminEnableRecovery'])
&& 0 == $_POST['adminEnableRecovery']
) {
- $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
- $return = $util->checkRecoveryPassword($_POST['recoveryPassword']);
-
- if ($return) {
- // Set recoveryAdmin as disabled
- OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0);
- }
+ $return = \Helper::adminDisableRecovery($_POST['recoveryPassword']);
}
// Return success or failure
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 86d860465e6..a04c65e251f 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -26,6 +26,10 @@ namespace OCA\Encryption;
/**
* @brief Class to manage registration of hooks an various helper methods
*/
+/**
+ * Class Helper
+ * @package OCA\Encryption
+ */
class Helper {
/**
@@ -89,4 +93,92 @@ class Helper {
return true;
}
+
+ /**
+ * @brief enable recovery
+ *
+ * @param $recoveryKeyId
+ * @param $recoveryPassword
+ * @internal param \OCA\Encryption\Util $util
+ * @internal param string $password
+ * @return bool
+ */
+ public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) {
+ $view = new \OC\Files\View('/');
+
+ if ($recoveryKeyId === null) {
+ $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8);
+ \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId);
+ }
+
+ if (!$view->is_dir('/owncloud_private_key')) {
+ $view->mkdir('/owncloud_private_key');
+ }
+
+ if (
+ (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key")
+ || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key"))
+ ) {
+
+ $keypair = \OCA\Encryption\Crypt::createKeypair();
+
+ \OC_FileProxy::$enabled = false;
+
+ // Save public key
+
+ if (!$view->is_dir('/public-keys')) {
+ $view->mkdir('/public-keys');
+ }
+
+ $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']);
+
+ // Encrypt private key empthy passphrase
+ $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword);
+
+ // Save private key
+ $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
+
+ // create control file which let us check later on if the entered password was correct.
+ $encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt("ownCloud", $keypair['publicKey']);
+ if (!$view->is_dir('/control-file')) {
+ $view->mkdir('/control-file');
+ }
+ $view->file_put_contents('/control-file/controlfile.enc', $encryptedControlData);
+
+ \OC_FileProxy::$enabled = true;
+
+ // Set recoveryAdmin as enabled
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
+
+ $return = true;
+
+ } else { // get recovery key and check the password
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ $return = $util->checkRecoveryPassword($_POST['recoveryPassword']);
+ if ($return) {
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
+ }
+ }
+
+ return $return;
+ }
+
+
+ /**
+ * @brief disable recovery
+ *
+ * @param $recoveryPassword
+ * @return bool
+ */
+ public static function adminDisableRecovery($recoveryPassword) {
+ $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
+ $return = $util->checkRecoveryPassword($recoveryPassword);
+
+ if ($return) {
+ // Set recoveryAdmin as disabled
+ \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0);
+ }
+
+ return $return;
+ }
} \ No newline at end of file
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 5a6583465e0..b312b502c14 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -1328,7 +1328,7 @@ class Util {
foreach ($dirContent as $item) {
$filePath = substr($item['path'], 25);
if ($item['type'] == 'dir') {
- $this->addRecoveryKey($filePath.'/');
+ $this->addRecoveryKeys($filePath.'/');
} else {
$session = new Session(new \OC_FilesystemView('/'));
$sharingEnabled = \OCP\Share::isEnabled();
@@ -1409,7 +1409,7 @@ class Util {
foreach ($dirContent as $item) {
$filePath = substr($item['path'], 25);
if ($item['type'] == 'dir') {
- $this->addRecoveryKey($filePath . '/', $privateKey);
+ $this->recoverAllFiles($filePath . '/', $privateKey);
} else {
$file = substr($filePath, 0, -4);
$this->recoverFile($file, $privateKey);
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php
index 1caa9ea7da7..bfb5ca0ec8b 100755
--- a/apps/files_encryption/tests/crypt.php
+++ b/apps/files_encryption/tests/crypt.php
@@ -62,8 +62,17 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
// Filesystem related hooks
\OCA\Encryption\Helper::registerFilesystemHooks();
+ // Filesystem related hooks
+ \OCA\Encryption\Helper::registerUserHooks();
+
\OC_FileProxy::register(new OCA\Encryption\Proxy());
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+
\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
@@ -78,6 +87,13 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
function tearDown() {
\OC_FileProxy::clearProxies();
+
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ } else {
+ OC_App::disable('files_trashbin');
+ }
}
function testGenerateKey() {
@@ -686,7 +702,6 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertEquals( $this->dataLong, $newDecrypt );
// tear down
- $view->unlink( $newFolder . '/' . $newFilename );
$view->unlink( $newFolder );
}
diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php
index 28452d779ca..3f6b936373c 100644
--- a/apps/files_encryption/tests/keymanager.php
+++ b/apps/files_encryption/tests/keymanager.php
@@ -57,6 +57,12 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
\OC_FileProxy::register(new OCA\Encryption\Proxy());
+ // remember files_trashbin state
+ $this->stateFilesTrashbin = OC_App::isEnabled('files_trashbin');
+
+ // we don't want to tests with app files_trashbin enabled
+ \OC_App::disable('files_trashbin');
+
\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
@@ -72,6 +78,13 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
\OC_FileProxy::$enabled = true;
\OC_FileProxy::clearProxies();
+
+ // reset app files_trashbin
+ if ($this->stateFilesTrashbin) {
+ OC_App::enable('files_trashbin');
+ } else {
+ OC_App::disable('files_trashbin');
+ }
}
function testGetPrivateKey() {
@@ -116,6 +129,16 @@ class Test_Keymanager extends \PHPUnit_Framework_TestCase {
//$view = new \OC_FilesystemView( '/' . $this->userId . '/files_encryption/keyfiles' );
Encryption\Keymanager::setFileKey( $this->view, $file, $this->userId, $key['key'] );
+
+ // Disable encryption proxy to prevent recursive calls
+ $proxyStatus = \OC_FileProxy::$enabled;
+ \OC_FileProxy::$enabled = true;
+
+ // cleanup
+ $this->view->unlink('/'.$this->userId . '/files/' . $file);
+
+ // Re-enable proxy - our work is done
+ \OC_FileProxy::$enabled = $proxyStatus;
}
diff --git a/apps/files_encryption/tests/share.php b/apps/files_encryption/tests/share.php
index e5427fdf504..a40a992b804 100755
--- a/apps/files_encryption/tests/share.php
+++ b/apps/files_encryption/tests/share.php
@@ -528,12 +528,152 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase
}
- function loginHelper($user, $create = false)
+ function testRecoveryFile()
+ {
+ // login as admin
+ $this->loginHelper('admin');
+
+ \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
+ $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+ // check if control file created
+ $this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
+
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), 'admin');
+
+ // check if recovery password match
+ $this->assertTrue($util->checkRecoveryPassword('test123'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(true));
+
+ // create folder structure
+ $this->view->mkdir('/admin/files' . $this->folder1);
+ $this->view->mkdir('/admin/files' . $this->folder1 . $this->subfolder);
+ $this->view->mkdir('/admin/files' . $this->folder1 . $this->subfolder . $this->subsubfolder);
+
+ // save file with content
+ $cryptedFile1 = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+ $cryptedFile2 = file_put_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile1));
+ $this->assertTrue(is_int($cryptedFile2));
+
+ // check if share key for admin and recovery exists
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->filename . '.admin.shareKey'));
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.admin.shareKey'));
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+
+ // disable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(false));
+
+ // remove all recovery keys
+ $util->removeRecoveryKeys('/');
+
+ // check if share key for recovery not exists
+ $this->assertFalse($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertFalse($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(true));
+
+ // remove all recovery keys
+ $util->addRecoveryKeys('/');
+
+ // check if share key for admin and recovery exists
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertTrue($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+
+ // cleanup
+ $this->view->unlink('/admin/files/' . $this->filename);
+ $this->view->unlink('/admin/files/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename);
+
+ // check if share key for recovery not exists
+ $this->assertFalse($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertFalse($this->view->file_exists('/admin/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ }
+
+ function testRecoveryForUser()
+ {
+ // login as admin
+ $this->loginHelper('admin');
+
+ \OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
+ $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
+
+ // check if control file created
+ $this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
+
+ // login as user1
+ $this->loginHelper('user1');
+
+ $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), 'user1');
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(true));
+
+ // create folder structure
+ $this->view->mkdir('/user1/files' . $this->folder1);
+ $this->view->mkdir('/user1/files' . $this->folder1 . $this->subfolder);
+ $this->view->mkdir('/user1/files' . $this->folder1 . $this->subfolder . $this->subsubfolder);
+
+ // save file with content
+ $cryptedFile1 = file_put_contents('crypt://' . $this->filename, $this->dataShort);
+ $cryptedFile2 = file_put_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename, $this->dataShort);
+
+ // test that data was successfully written
+ $this->assertTrue(is_int($cryptedFile1));
+ $this->assertTrue(is_int($cryptedFile2));
+
+ // check if share key for user and recovery exists
+ $this->assertTrue($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->filename . '.user1.shareKey'));
+ $this->assertTrue($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertTrue($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.user1.shareKey'));
+ $this->assertTrue($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+
+ // login as admin
+ $this->loginHelper('admin');
+
+ // change password
+ \OC_User::setPassword('user1', 'test', 'test123');
+
+ // login as user1
+ $this->loginHelper('user1', false, 'test');
+
+ // get file contents
+ $retrievedCryptedFile1 = file_get_contents('crypt://' . $this->filename);
+ $retrievedCryptedFile2 = file_get_contents('crypt://' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename);
+
+ // check if data is the same as we previously written
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile1);
+ $this->assertEquals($this->dataShort, $retrievedCryptedFile2);
+
+ // cleanup
+ $this->view->unlink('/user1/files' . $this->folder1);
+ $this->view->unlink('/user1/files' . $this->filename);
+
+ // check if share key for user and recovery exists
+ $this->assertFalse($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->filename . '.user1.shareKey'));
+ $this->assertFalse($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+ $this->assertFalse($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.user1.shareKey'));
+ $this->assertFalse($this->view->file_exists('/user1/files_encryption/share-keys/' . $this->folder1 . $this->subfolder . $this->subsubfolder .'/'. $this->filename . '.'.$recoveryKeyId.'.shareKey'));
+
+ // enable recovery for admin
+ $this->assertTrue($util->setRecoveryForUser(false));
+ }
+
+ function loginHelper($user, $create = false, $password = false)
{
if ($create) {
\OC_User::createUser($user, $user);
}
+ if($password === false) {
+ $password = $user;
+ }
+
\OC_Util::tearDownFS();
\OC_User::setUserId('');
\OC\Files\Filesystem::tearDown();
@@ -541,7 +681,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase
\OC_User::setUserId($user);
$params['uid'] = $user;
- $params['password'] = $user;
+ $params['password'] = $password;
OCA\Encryption\Hooks::login($params);
}
}