From 5b160edebba2a10de83b09a8010a811321dd6370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 15 May 2013 14:02:13 +0200 Subject: [PATCH] check if the user knows the correct recovery password before changing the recovery key settings --- .gitignore | 1 + apps/files_encryption/ajax/adminrecovery.php | 65 +++++++++++++++----- apps/files_encryption/hooks/hooks.php | 3 +- apps/files_encryption/js/settings-admin.js | 6 +- apps/files_encryption/lib/crypt.php | 10 ++- 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index b57dd3d205..bc0c1d53a5 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,4 @@ data-autotest /tests/coverage* /tests/autoconfig* /tests/autotest* +/l10n/.tx/ \ No newline at end of file diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index 6a056dc7b3..520c7156c8 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -15,17 +15,38 @@ use OCA\Encryption; $return = false; +function checkPassword($view, $password, $recoveryKeyId) { + $pathKey = '/owncloud_private_key/'. $recoveryKeyId . ".private.key"; + $pathControlData = '/control-file/controlfile.enc'; + + $proxyStatus = \OC_FileProxy::$enabled; + \OC_FileProxy::$enabled = false; + + $recoveryKey = $view->file_get_contents( $pathKey ); + + $decryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricDecryptFileContent($recoveryKey, $password); + + $controlData = $view->file_get_contents($pathControlData); + $decryptedControlData = \OCA\Encryption\Crypt::keyDecrypt($controlData, $decryptedRecoveryKey); + + \OC_FileProxy::$enabled = $proxyStatus; + + if ($decryptedControlData === 'ownCloud') { + return true; + } else { + return false; + } +} + + // Enable recoveryAdmin -if ( - isset($_POST['adminEnableRecovery']) - && 1 == $_POST['adminEnableRecovery'] -) { +$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + +if (isset($_POST['adminEnableRecovery']) && $_POST['adminEnableRecovery'] == 1){ $view = new \OC\Files\View('/'); - $recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); - if ($recoveryKeyId === null) { $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); @@ -38,8 +59,6 @@ if ( if ( (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key") || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key")) - && isset($_POST['recoveryPassword']) - && !empty($_POST['recoveryPassword']) ) { $keypair = \OCA\Encryption\Crypt::createKeypair(); @@ -60,25 +79,39 @@ if ( // 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 + $return = checkPassword($view, $_POST['recoveryPassword'] ,$recoveryKeyId); + if ($return) { + OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); + } } - // Set recoveryAdmin as enabled - OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); - - $return = true; - // Disable recoveryAdmin } elseif ( isset($_POST['adminEnableRecovery']) && 0 == $_POST['adminEnableRecovery'] ) { + $view = new \OC\Files\View('/'); + $return = checkPassword($view, $_POST['recoveryPassword'], $recoveryKeyId); - // Set recoveryAdmin as enabled + if ($return) { + // Set recoveryAdmin as disabled OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0); - - $return = true; + } } // Return success or failure diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 31175d1c34..ed254fd8d8 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -59,7 +59,8 @@ class Hooks { \OC_FileProxy::$enabled = true; - $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); + //$privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); + $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, "helloworld" ); $session = new Session( $view ); diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js index 2fffcf77b3..fa353901c3 100644 --- a/apps/files_encryption/js/settings-admin.js +++ b/apps/files_encryption/js/settings-admin.js @@ -25,12 +25,16 @@ $(document).ready(function(){ function() { var recoveryStatus = $( this ).val(); + var oldStatus = (1+parseInt(recoveryStatus)) % 2; var recoveryPassword = $( '#recoveryPassword' ).val(); $.post( OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword } , function( data ) { - alert( data ); + if (data.status == "error") { + alert("Couldn't switch recovery key mode, please check your recovery key password!"); + $('input:radio[name="adminEnableRecovery"][value="'+oldStatus.toString()+'"]').attr("checked", "true"); + } } ); } diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index f92930c2cb..5267ba81f5 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -217,7 +217,7 @@ class Crypt { * @returns decrypted file */ public static function decrypt( $encryptedContent, $iv, $passphrase ) { - + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $plainContent; @@ -463,9 +463,13 @@ class Crypt { */ public static function keyDecrypt( $encryptedContent, $privatekey ) { - openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); + $result = @openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); - return $plainContent; + if ( $result ) { + return $plainContent; + } + + return $result; }