Added method for setting user keyfile recovery preference
Fixed method for checking if keyfile recovery is enabled for a user Added unit test for above 2 methods Made proxy{} always use sharing Made proxy{} work regardless of sharing API enabled or not Implemented proxy-based sharing to admin if user keyfile recovery is enabled
This commit is contained in:
parent
c89fd49870
commit
fd4e59b748
|
@ -40,7 +40,6 @@ class Hooks {
|
|||
\OC\Files\Filesystem::init( $params['uid'] . '/' . 'files' . '/' );
|
||||
|
||||
$view = new \OC_FilesystemView( '/' );
|
||||
|
||||
$util = new Util( $view, $params['uid'] );
|
||||
|
||||
// Check files_encryption infrastructure is ready for action
|
||||
|
@ -61,7 +60,6 @@ class Hooks {
|
|||
$privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] );
|
||||
|
||||
$session = new Session();
|
||||
|
||||
$session->setPrivateKey( $privateKey, $params['uid'] );
|
||||
|
||||
$view1 = new \OC_FilesystemView( '/' . $params['uid'] );
|
||||
|
|
|
@ -57,6 +57,7 @@ class Keymanager {
|
|||
return $view->file_get_contents( '/public-keys/' . '/' . $userId . '.public.key' );
|
||||
|
||||
\OC_FileProxy::$enabled = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -131,32 +131,50 @@ class Proxy extends \OC_FileProxy {
|
|||
// Encrypt data
|
||||
$encData = Crypt::symmetricEncryptFileContent( $data, $plainKey );
|
||||
|
||||
// Check if the keyfile needs to be shared
|
||||
if ( $userIds = \OCP\Share::getUsersSharingFile( $filePath, true ) ) {
|
||||
// Check if key recovery is enabled
|
||||
$recoveryEnabled = $util->recoveryEnabled();
|
||||
|
||||
$publicKeys = Keymanager::getPublicKeys( $rootView, $userIds );
|
||||
// Make sure that a share key is generated for the owner too
|
||||
$userIds = array( $userId );
|
||||
|
||||
\OC_FileProxy::$enabled = false;
|
||||
if ( \OCP\Share::isEnabled() ) {
|
||||
|
||||
// Encrypt plain keyfile to multiple sharefiles
|
||||
$multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys );
|
||||
// Find out who, if anyone, is sharing the file
|
||||
$shareUids = \OCP\Share::getUsersSharingFile( $filePath, true );
|
||||
|
||||
// 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
|
||||
$encKey = $multiEncrypted['encrypted'];
|
||||
|
||||
} else {
|
||||
|
||||
$publicKey = Keymanager::getPublicKey( $rootView, $userId );
|
||||
|
||||
// Encrypt plain data to a single user
|
||||
$encKey = Crypt::keyEncrypt( $plainKey, $publicKey );
|
||||
$userIds = array_merge( $userIds, $shareUids );
|
||||
|
||||
}
|
||||
|
||||
// If recovery is enabled, add the
|
||||
// Admin UID to list of users to share to
|
||||
if ( $recoveryEnabled ) {
|
||||
|
||||
// FIXME: Create a separate admin user purely for recovery, and create method in util for fetching this id from DB?
|
||||
$adminUid = 'recoveryAdmin';
|
||||
|
||||
$userIds[] = $adminUid;
|
||||
|
||||
}
|
||||
|
||||
// Remove duplicate UIDs
|
||||
$uniqueUserIds = array_unique ( $userIds );
|
||||
|
||||
// Fetch public keys for all users who will share the file
|
||||
$publicKeys = Keymanager::getPublicKeys( $rootView, $uniqueUserIds );
|
||||
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
// Encrypt plain keyfile to multiple sharefiles
|
||||
$multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys );
|
||||
|
||||
// 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
|
||||
$encKey = $multiEncrypted['data'];
|
||||
|
||||
// Save the key if its new
|
||||
if ( ! $keyPreExists ) {
|
||||
|
||||
|
|
|
@ -31,7 +31,12 @@
|
|||
# ----------------
|
||||
# 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
|
||||
# Trashbin support
|
||||
|
||||
|
||||
# Test
|
||||
# ----
|
||||
# Test that writing files works when recovery is enabled, and sharing API is disabled
|
||||
# Test trashbin support
|
||||
|
||||
|
||||
// Old Todo:
|
||||
|
@ -202,16 +207,69 @@ class Util {
|
|||
|
||||
}
|
||||
|
||||
public function recoveryEnabled( ) {
|
||||
/**
|
||||
* @brief Check whether pwd recovery is enabled for a given user
|
||||
* @return bool
|
||||
* @note If records are not being returned, check for a hidden space
|
||||
* at the start of the uid in db
|
||||
*/
|
||||
public function recoveryEnabled() {
|
||||
|
||||
$sql = 'SELECT * FROM `*PREFIX*myusers` WHERE id = ?';
|
||||
$args = array(1);
|
||||
$sql = 'SELECT
|
||||
recovery
|
||||
FROM
|
||||
`*PREFIX*encryption`
|
||||
WHERE
|
||||
uid = ?';
|
||||
|
||||
$query = \OCP\DB::prepare($sql);
|
||||
$result = $query->execute($args);
|
||||
$args = array( $this->userId );
|
||||
|
||||
$query = \OCP\DB::prepare( $sql );
|
||||
|
||||
$result = $query->execute( $args );
|
||||
|
||||
// Set default in case no records found
|
||||
$recoveryEnabled = 0;
|
||||
|
||||
while( $row = $result->fetchRow() ) {
|
||||
|
||||
$recoveryEnabled = $row['recovery'];
|
||||
|
||||
}
|
||||
|
||||
return $recoveryEnabled;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / disable pwd recovery for a given user
|
||||
* @param bool $enabled Whether to enable or disable recovery
|
||||
* @return bool
|
||||
*/
|
||||
public function setRecovery( $enabled ) {
|
||||
|
||||
$sql = 'UPDATE
|
||||
*PREFIX*encryption
|
||||
SET
|
||||
recovery = ?
|
||||
WHERE
|
||||
uid = ?';
|
||||
|
||||
// Ensure value is an integer
|
||||
$enabled = intval( $enabled );
|
||||
|
||||
$args = array( $enabled, $this->userId );
|
||||
|
||||
$query = \OCP\DB::prepare( $sql );
|
||||
|
||||
if ( $query->execute( $args ) ) {
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
while($row = $result->fetchRow()) {
|
||||
$userName = $row['username'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -165,6 +165,26 @@ class Test_Enc_Util extends \PHPUnit_Framework_TestCase {
|
|||
|
||||
}
|
||||
|
||||
function testRecoveryEnabled() {
|
||||
|
||||
$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();
|
||||
|
||||
$this->assertTrue( $util->setRecovery( 1 ) );
|
||||
|
||||
$this->assertEquals( 1, $util->recoveryEnabled() );
|
||||
|
||||
$this->assertTrue( $util->setRecovery( 0 ) );
|
||||
|
||||
$this->assertEquals( 0, $util->recoveryEnabled() );
|
||||
|
||||
// Return the setting to it's previous state
|
||||
$this->assertTrue( $util->setRecovery( $enabled ) );
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @brief test decryption using legacy blowfish method
|
||||
// * @depends testLegacyEncryptLong
|
||||
|
|
Loading…
Reference in New Issue