Merge pull request #3552 from owncloud/files_encryption_upgrade_fix

Fix files_encryption app upgrade from 4.5 to 5.0
This commit is contained in:
Björn Schießle 2013-06-13 03:54:19 -07:00
commit dd8011925a
8 changed files with 58 additions and 105 deletions

@ -1 +1 @@
Subproject commit d59b017922d9ac3bf985dee0eb721ec1a901ac72 Subproject commit 3ef9f738a9107879dddc7d97842cf4d2198fae4c

View File

@ -10,45 +10,50 @@ OC::$CLASSPATH['OCA\Encryption\Session'] = 'files_encryption/lib/session.php';
OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php'; OC::$CLASSPATH['OCA\Encryption\Capabilities'] = 'files_encryption/lib/capabilities.php';
OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php'; OC::$CLASSPATH['OCA\Encryption\Helper'] = 'files_encryption/lib/helper.php';
OC_FileProxy::register(new OCA\Encryption\Proxy()); if (!OC_Config::getValue('maintenance', false)) {
OC_FileProxy::register(new OCA\Encryption\Proxy());
// User related hooks // User related hooks
OCA\Encryption\Helper::registerUserHooks(); OCA\Encryption\Helper::registerUserHooks();
// Sharing related hooks // Sharing related hooks
OCA\Encryption\Helper::registerShareHooks(); OCA\Encryption\Helper::registerShareHooks();
// Filesystem related hooks // Filesystem related hooks
OCA\Encryption\Helper::registerFilesystemHooks(); OCA\Encryption\Helper::registerFilesystemHooks();
stream_wrapper_register('crypt', 'OCA\Encryption\Stream'); stream_wrapper_register('crypt', 'OCA\Encryption\Stream');
// check if we are logged in // check if we are logged in
if (OCP\User::isLoggedIn()) { if (OCP\User::isLoggedIn()) {
// ensure filesystem is loaded // ensure filesystem is loaded
if(!\OC\Files\Filesystem::$loaded) { if (!\OC\Files\Filesystem::$loaded) {
\OC_Util::setupFS(); \OC_Util::setupFS();
} }
$view = new OC_FilesystemView('/'); $view = new OC_FilesystemView('/');
$session = new \OCA\Encryption\Session($view); $session = new \OCA\Encryption\Session($view);
// check if user has a private key // check if user has a private key
if ( if (
!$session->getPrivateKey(\OCP\USER::getUser()) !$session->getPrivateKey(\OCP\USER::getUser())
&& OCA\Encryption\Crypt::mode() === 'server' && OCA\Encryption\Crypt::mode() === 'server'
) { ) {
// Force the user to log-in again 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 // (happens when a user is logged in before the encryption app is
// enabled) // enabled)
OCP\User::logout(); OCP\User::logout();
header("Location: " . OC::$WEBROOT . '/'); header("Location: " . OC::$WEBROOT . '/');
exit(); exit();
}
} }
} else {
// logout user if we are in maintenance to force re-login
OCP\User::logout();
} }
// Register settings scripts // Register settings scripts

View File

@ -84,7 +84,7 @@ class Hooks {
&& $encLegacyKey = $userView->file_get_contents('encryption.key') && $encLegacyKey = $userView->file_get_contents('encryption.key')
) { ) {
$plainLegacyKey = Crypt::legacyBlockDecrypt($encLegacyKey, $params['password']); $plainLegacyKey = Crypt::legacyDecrypt($encLegacyKey, $params['password']);
$session->setLegacyKey($plainLegacyKey); $session->setLegacyKey($plainLegacyKey);

View File

@ -608,7 +608,7 @@ class Crypt {
* *
* This function decrypts an content * This function decrypts an content
*/ */
private static function legacyDecrypt($content, $passphrase = '') { public static function legacyDecrypt($content, $passphrase = '') {
$bf = self::getBlowfish($passphrase); $bf = self::getBlowfish($passphrase);
@ -637,28 +637,4 @@ class Crypt {
} }
} }
/**
* @param $legacyEncryptedContent
* @param $legacyPassphrase
* @param $publicKeys
* @return array
*/
public static function legacyKeyRecryptKeyfile($legacyEncryptedContent, $legacyPassphrase, $publicKeys) {
$decrypted = self::legacyBlockDecrypt($legacyEncryptedContent, $legacyPassphrase);
// Encrypt plain data, generate keyfile & encrypted file
$cryptedData = self::symmetricEncryptFileContentKeyfile($decrypted);
// Encrypt plain keyfile to multiple sharefiles
$multiEncrypted = Crypt::multiKeyEncrypt($cryptedData['key'], $publicKeys);
return array(
'data' => $cryptedData['encrypted'],
'filekey' => $multiEncrypted['data'],
'sharekeys' => $multiEncrypted['keys']
);
}
} }

View File

@ -256,6 +256,8 @@ class Proxy extends \OC_FileProxy {
*/ */
public function postFopen($path, &$result) { public function postFopen($path, &$result) {
$path = \OC\Files\Filesystem::normalizePath($path);
if (!$result) { if (!$result) {
return $result; return $result;

View File

@ -725,40 +725,28 @@ class Util {
// Fetch data from file // Fetch data from file
$legacyData = $this->view->file_get_contents($legacyFile['path']); $legacyData = $this->view->file_get_contents($legacyFile['path']);
$sharingEnabled = \OCP\Share::isEnabled(); // decrypt data, generate catfile
$decrypted = Crypt::legacyBlockDecrypt($legacyData, $legacyPassphrase);
// if file exists try to get sharing users
if ($this->view->file_exists($legacyFile['path'])) {
$uniqueUserIds = $this->getSharingUsersArray($sharingEnabled, $legacyFile['path'], $this->userId);
} else {
$uniqueUserIds[] = $this->userId;
}
// Fetch public keys for all users who will share the file
$publicKeys = Keymanager::getPublicKeys($this->view, $uniqueUserIds);
// Recrypt data, generate catfile
$recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKeys );
$rawPath = $legacyFile['path']; $rawPath = $legacyFile['path'];
$relPath = \OCA\Encryption\Helper::stripUserFilesPath($rawPath);
// Save keyfile // enable proxy the ensure encryption is handled
Keymanager::setFileKey($this->view, $relPath, $this->userId, $recrypted['filekey']); \OC_FileProxy::$enabled = true;
// Save sharekeys to user folders // Open enc file handle for binary writing, with same filename as original plain file
Keymanager::setShareKeys($this->view, $relPath, $recrypted['sharekeys']); $encHandle = $this->view->fopen( $rawPath, 'wb' );
// Overwrite the existing file with the encrypted one if (is_resource($encHandle)) {
$this->view->file_put_contents($rawPath, $recrypted['data']);
$size = strlen($recrypted['data']); // write data to stream
fwrite($encHandle, $decrypted);
// Add the file to the cache // close stream
\OC\Files\Filesystem::putFileInfo($rawPath, array( fclose($encHandle);
'encrypted' => true, }
'size' => $size
), ''); // disable proxy to prevent file being encrypted twice
\OC_FileProxy::$enabled = false;
} }
} }

View File

@ -611,24 +611,6 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
} }
/**
* @medium
* @brief test decryption using legacy blowfish method
* @depends testLegacyEncryptLong
*/
function testLegacyKeyRecryptKeyfileEncrypt($crypted) {
$recrypted = Encryption\Crypt::LegacyKeyRecryptKeyfile($crypted, $this->pass, array($this->genPublicKey));
$this->assertNotEquals($this->dataLong, $recrypted['data']);
return $recrypted;
# TODO: search inencrypted text for actual content to ensure it
# genuine transformation
}
/** /**
* @medium * @medium
*/ */

View File

@ -75,7 +75,7 @@ class Test_Encryption_Util extends \PHPUnit_Framework_TestCase {
$this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt'); $this->legacyData = realpath(dirname(__FILE__) . '/legacy-text.txt');
$this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt'); $this->legacyEncryptedData = realpath(dirname(__FILE__) . '/legacy-encrypted-text.txt');
$this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key'); $this->legacyEncryptedDataKey = realpath(dirname(__FILE__) . '/encryption.key');
$this->legacyKey = '30943623843030686906'; $this->legacyKey = "30943623843030686906\0\0\0\0";
$keypair = Encryption\Crypt::createKeypair(); $keypair = Encryption\Crypt::createKeypair();