From d7dca966a2a926be8b45ab337488143eac3ce9ba Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 30 Aug 2013 10:17:50 +0200 Subject: [PATCH 01/12] improved error messaging, initial commit --- apps/files_encryption/appinfo/database.xml | 7 +++ apps/files_encryption/appinfo/version | 2 +- apps/files_encryption/files/error.php | 2 +- apps/files_encryption/hooks/hooks.php | 29 +++++++----- apps/files_encryption/lib/helper.php | 44 ++++++++++++------ apps/files_encryption/lib/stream.php | 34 +++++++------- apps/files_encryption/lib/util.php | 52 ++++++++++++++++++++++ 7 files changed, 126 insertions(+), 44 deletions(-) diff --git a/apps/files_encryption/appinfo/database.xml b/apps/files_encryption/appinfo/database.xml index 4587930da0a..cd5434b8c27 100644 --- a/apps/files_encryption/appinfo/database.xml +++ b/apps/files_encryption/appinfo/database.xml @@ -34,6 +34,13 @@ 0 Whether encryption migration has been performed + + initialized + integer + true + 0 + Did the user initialized the encryption app at least once + \ No newline at end of file diff --git a/apps/files_encryption/appinfo/version b/apps/files_encryption/appinfo/version index bd73f47072b..2eb3c4fe4ee 100644 --- a/apps/files_encryption/appinfo/version +++ b/apps/files_encryption/appinfo/version @@ -1 +1 @@ -0.4 +0.5 diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php index 2dd27257abe..7a2bb1a2811 100644 --- a/apps/files_encryption/files/error.php +++ b/apps/files_encryption/files/error.php @@ -4,7 +4,7 @@ if (!isset($_)) { //also provide standalone error page $l = OC_L10N::get('files_encryption'); - $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); + $errorMsg = $l->t('Your private key is not valid! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app. If this doesn\'t help maybe your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); if(isset($_GET['p']) && $_GET['p'] === '1') { header('HTTP/1.0 404 ' . $errorMsg); diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index de306462d79..aefb274e1c4 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -70,9 +70,11 @@ class Hooks { // If migration not yet done if ($ready) { + $util->setInitialized(Util::ENCRYPTION_INITIALIZED); + $userView = new \OC_FilesystemView('/' . $params['uid']); - // Set legacy encryption key if it exists, to support + // Set legacy encryption key if it exists, to support // depreciated encryption system if ( $userView->file_exists('encryption.key') @@ -143,6 +145,7 @@ class Hooks { * @brief If the password can't be changed within ownCloud, than update the key password in advance. */ public static function preSetPassphrase($params) { + return true; if ( ! \OC_User::canUserChangePassword($params['uid']) ) { self::setPassphrase($params); } @@ -153,7 +156,7 @@ class Hooks { * @param array $params keys: uid, password */ public static function setPassphrase($params) { - + return true; // Only attempt to change passphrase if server-side encryption // is in use (client-side encryption does not have access to // the necessary keys) @@ -248,7 +251,7 @@ class Hooks { $params['run'] = false; $params['error'] = $l->t('Following users are not set up for encryption:') . ' ' . join(', ' , $notConfigured); } - + } /** @@ -259,7 +262,7 @@ class Hooks { // NOTE: $params has keys: // [itemType] => file // itemSource -> int, filecache file ID - // [parent] => + // [parent] => // [itemTarget] => /13 // shareWith -> string, uid of user being shared to // fileTarget -> path of file being shared @@ -300,13 +303,13 @@ class Hooks { // NOTE: parent is folder but shared was a file! // we try to rebuild the missing path // some examples we face here - // user1 share folder1 with user2 folder1 has - // the following structure + // user1 share folder1 with user2 folder1 has + // the following structure // /folder1/subfolder1/subsubfolder1/somefile.txt // user2 re-share subfolder2 with user3 // user3 re-share somefile.txt user4 - // so our path should be - // /Shared/subfolder1/subsubfolder1/somefile.txt + // so our path should be + // /Shared/subfolder1/subsubfolder1/somefile.txt // while user3 is sharing if ($params['itemType'] === 'file') { @@ -537,14 +540,18 @@ class Hooks { } /** - * set migration status back to '0' so that all new files get encrypted + * set migration status and the init status back to '0' so that all new files get encrypted * if the app gets enabled again * @param array $params contains the app ID */ public static function preDisable($params) { if ($params['app'] === 'files_encryption') { - $query = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); - $query->execute(); + + $setMigrationStatus = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); + $setMigrationStatus->execute(); + + $setInitStatus = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `initialized`=0'); + $setInitStatus->execute(); } } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 0209a5d18b7..105c5357e96 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -199,12 +199,12 @@ class Helper { public static function stripUserFilesPath($path) { $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); - + // it is not a file relative to data/user/files if (count($split) < 3 || $split[1] !== 'files') { return false; } - + $sliced = array_slice($split, 2); $relPath = implode('/', $sliced); @@ -219,30 +219,46 @@ class Helper { public static function getPathToRealFile($path) { $trimmed = ltrim($path, '/'); $split = explode('/', $trimmed); - + if (count($split) < 3 || $split[1] !== "files_versions") { return false; } - + $sliced = array_slice($split, 2); $realPath = implode('/', $sliced); //remove the last .v $realPath = substr($realPath, 0, strrpos($realPath, '.v')); return $realPath; - } - + } + /** * @brief redirect to a error page */ - public static function redirectToErrorPage() { - $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php'); - $post = 0; - if(count($_POST) > 0) { - $post = 1; + public static function redirectToErrorPage($util) { + + $l = \OC_L10N::get('files_encryption'); + + if ($util->getInitialized() === false) { + $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); + } else { + $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); } - header('Location: ' . $location . '?p=' . $post); - exit(); + + if(count($_POST) > 0) { + header('HTTP/1.0 404 ' . $errorMsg); + } + + // check if ajax request + if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { + \OCP\JSON::error(array('data' => array('message' => $errorMsg))); + } else { + header('HTTP/1.0 404 ' . $errorMsg); + $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); + $tmpl->printPage(); + } + + exit; } /** @@ -259,7 +275,7 @@ class Helper { return (bool) $result; } - + /** * check some common errors if the server isn't configured properly for encryption * @return bool true if configuration seems to be OK diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 335ea3733eb..87b8dc3ee2f 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -81,7 +81,7 @@ class Stream { * @return bool */ public function stream_open($path, $mode, $options, &$opened_path) { - + // assume that the file already exist before we decide it finally in getKey() $this->newFile = false; @@ -106,12 +106,12 @@ class Stream { if ($this->relPath === false) { $this->relPath = Helper::getPathToRealFile($this->rawPath); } - + if($this->relPath === false) { \OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '" expecting a path to user/files or to user/files_versions', \OCP\Util::ERROR); return false; } - + // Disable fileproxies so we can get the file size and open the source file without recursive encryption $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -131,7 +131,7 @@ class Stream { if($this->privateKey === false) { // if private key is not valid redirect user to a error page - \OCA\Encryption\Helper::redirectToErrorPage(); + \OCA\Encryption\Helper::redirectToErrorPage($util); } $this->size = $this->rootView->filesize($this->rawPath, $mode); @@ -272,7 +272,7 @@ class Stream { } else { $this->newFile = true; - + return false; } @@ -296,9 +296,9 @@ class Stream { return strlen($data); } - // Disable the file proxies so that encryption is not - // automatically attempted when the file is written to disk - - // we are handling that separately here and we don't want to + // Disable the file proxies so that encryption is not + // automatically attempted when the file is written to disk - + // we are handling that separately here and we don't want to // get into an infinite loop $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -311,7 +311,7 @@ class Stream { $pointer = ftell($this->handle); // Get / generate the keyfile for the file we're handling - // If we're writing a new file (not overwriting an existing + // If we're writing a new file (not overwriting an existing // one), save the newly generated keyfile if (!$this->getKey()) { @@ -319,7 +319,7 @@ class Stream { } - // If extra data is left over from the last round, make sure it + // If extra data is left over from the last round, make sure it // is integrated into the next 6126 / 8192 block if ($this->writeCache) { @@ -344,12 +344,12 @@ class Stream { if ($remainingLength < 6126) { // Set writeCache to contents of $data - // The writeCache will be carried over to the - // next write round, and added to the start of - // $data to ensure that written blocks are - // always the correct length. If there is still - // data in writeCache after the writing round - // has finished, then the data will be written + // The writeCache will be carried over to the + // next write round, and added to the start of + // $data to ensure that written blocks are + // always the correct length. If there is still + // data in writeCache after the writing round + // has finished, then the data will be written // to disk by $this->flush(). $this->writeCache = $data; @@ -363,7 +363,7 @@ class Stream { $encrypted = $this->preWriteEncrypt($chunk, $this->plainKey); - // Write the data chunk to disk. This will be + // Write the data chunk to disk. This will be // attended to the last data chunk if the file // being handled totals more than 6126 bytes fwrite($this->handle, $encrypted); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index b8d68623493..edb9564e73a 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -37,6 +37,8 @@ class Util { const MIGRATION_IN_PROGRESS = -1; // migration is running const MIGRATION_OPEN = 0; // user still needs to be migrated + const ENCRYPTION_INITIALIZED = 1; + const ENCRYPTION_NOT_INITIALIZED = 0; private $view; // OC_FilesystemView object for filesystem operations private $userId; // ID of the currently logged-in user @@ -1216,6 +1218,56 @@ class Util { return $return; } + /** + * set remember if the encryption app was already initialized or not + * @param type $status + */ + public function setInitialized($status) { + $sql = 'UPDATE `*PREFIX*encryption` SET `initialized` = ? WHERE `uid` = ?'; + $args = array($status, $this->userId); + $query = \OCP\DB::prepare($sql); + $query->execute($args); + } + + /** + * set remember if the encryption app was already initialized or not + */ + public function getInitialized() { + $sql = 'SELECT `initialized` FROM `*PREFIX*encryption` WHERE `uid` = ?'; + $args = array($this->userId); + $query = \OCP\DB::prepare($sql); + + $result = $query->execute($args); + $initializedStatus = null; + + if (\OCP\DB::isError($result)) { + \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); + } else { + if ($result->numRows() > 0) { + $row = $result->fetchRow(); + if (isset($row['initialized'])) { + $initializedStatus = (int)$row['initialized']; + } + } + } + + // If no record is found + if (empty($initializedStatus)) { + \OCP\Util::writeLog('Encryption library', "Could not get initialized status for " . $this->userId . ", no record found", \OCP\Util::ERROR); + return false; + // If a record is found + } else { + return (bool)$initializedStatus; + } + + + + $sql = 'UPDATE `*PREFIX*encryption` SET `initialized` = ? WHERE `uid` = ?'; + $args = array($status, $this->userId); + $query = \OCP\DB::prepare($sql); + $query->execute($args); + } + /** * @brief close migration mode after users data has been encrypted successfully * @return boolean From bab63c22eea058ea619de5c021d16803ba48ab8d Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 2 Sep 2013 11:26:11 +0200 Subject: [PATCH 02/12] encryption error messages, distinguish between a re-enabled encryption app and a password change from outside --- apps/files_encryption/appinfo/database.xml | 7 --- apps/files_encryption/hooks/hooks.php | 8 +-- apps/files_encryption/lib/helper.php | 4 +- apps/files_encryption/lib/session.php | 27 +++++++++ apps/files_encryption/lib/stream.php | 2 +- apps/files_encryption/lib/util.php | 60 ++----------------- apps/files_encryption/settings-personal.php | 5 +- .../templates/settings-personal.php | 10 ++-- settings/ajax/changepassword.php | 2 +- settings/templates/personal.php | 2 +- 10 files changed, 48 insertions(+), 79 deletions(-) diff --git a/apps/files_encryption/appinfo/database.xml b/apps/files_encryption/appinfo/database.xml index cd5434b8c27..4587930da0a 100644 --- a/apps/files_encryption/appinfo/database.xml +++ b/apps/files_encryption/appinfo/database.xml @@ -34,13 +34,6 @@ 0 Whether encryption migration has been performed - - initialized - integer - true - 0 - Did the user initialized the encryption app at least once - \ No newline at end of file diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index aefb274e1c4..4c6122b7c2b 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -70,8 +70,6 @@ class Hooks { // If migration not yet done if ($ready) { - $util->setInitialized(Util::ENCRYPTION_INITIALIZED); - $userView = new \OC_FilesystemView('/' . $params['uid']); // Set legacy encryption key if it exists, to support @@ -145,7 +143,6 @@ class Hooks { * @brief If the password can't be changed within ownCloud, than update the key password in advance. */ public static function preSetPassphrase($params) { - return true; if ( ! \OC_User::canUserChangePassword($params['uid']) ) { self::setPassphrase($params); } @@ -156,7 +153,6 @@ class Hooks { * @param array $params keys: uid, password */ public static function setPassphrase($params) { - return true; // Only attempt to change passphrase if server-side encryption // is in use (client-side encryption does not have access to // the necessary keys) @@ -550,8 +546,8 @@ class Hooks { $setMigrationStatus = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `migration_status`=0'); $setMigrationStatus->execute(); - $setInitStatus = \OC_DB::prepare('UPDATE `*PREFIX*encryption` SET `initialized`=0'); - $setInitStatus->execute(); + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $session->setInitialized(false); } } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 105c5357e96..7d466b88523 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -235,11 +235,11 @@ class Helper { /** * @brief redirect to a error page */ - public static function redirectToErrorPage($util) { + public static function redirectToErrorPage($session) { $l = \OC_L10N::get('files_encryption'); - if ($util->getInitialized() === false) { + if ($session->getInitialized() === false) { $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); } else { $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 1911386cd12..f5ce7083af0 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -112,6 +112,33 @@ class Session { } + /** + * @brief Sets status if we tried to initialize the encyption app + * @param bool $privateKey true=initialized false=not initialized + * @return bool + */ + public function setInitialized($init) { + + \OC::$session->set('encryptionInitialized', $init); + + return true; + + } + + + /** + * @brief Gets status if we already tried to initialize the encryption app + * @returns bool + * + */ + public function getInitialized() { + if (!is_null(\OC::$session->get('encryptionInitialized'))) { + return \OC::$session->get('encryptionInitialized'); + } else { + return false; + } + } + /** * @brief Gets user or public share private key from session * @returns string $privateKey The user's plaintext private key diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 87b8dc3ee2f..9215352aa78 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -131,7 +131,7 @@ class Stream { if($this->privateKey === false) { // if private key is not valid redirect user to a error page - \OCA\Encryption\Helper::redirectToErrorPage($util); + \OCA\Encryption\Helper::redirectToErrorPage($this->session); } $this->size = $this->rootView->filesize($this->rawPath, $mode); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index edb9564e73a..17096a787f2 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -37,9 +37,6 @@ class Util { const MIGRATION_IN_PROGRESS = -1; // migration is running const MIGRATION_OPEN = 0; // user still needs to be migrated - const ENCRYPTION_INITIALIZED = 1; - const ENCRYPTION_NOT_INITIALIZED = 0; - private $view; // OC_FilesystemView object for filesystem operations private $userId; // ID of the currently logged-in user private $client; // Client side encryption mode flag @@ -1218,56 +1215,6 @@ class Util { return $return; } - /** - * set remember if the encryption app was already initialized or not - * @param type $status - */ - public function setInitialized($status) { - $sql = 'UPDATE `*PREFIX*encryption` SET `initialized` = ? WHERE `uid` = ?'; - $args = array($status, $this->userId); - $query = \OCP\DB::prepare($sql); - $query->execute($args); - } - - /** - * set remember if the encryption app was already initialized or not - */ - public function getInitialized() { - $sql = 'SELECT `initialized` FROM `*PREFIX*encryption` WHERE `uid` = ?'; - $args = array($this->userId); - $query = \OCP\DB::prepare($sql); - - $result = $query->execute($args); - $initializedStatus = null; - - if (\OCP\DB::isError($result)) { - \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); - } else { - if ($result->numRows() > 0) { - $row = $result->fetchRow(); - if (isset($row['initialized'])) { - $initializedStatus = (int)$row['initialized']; - } - } - } - - // If no record is found - if (empty($initializedStatus)) { - \OCP\Util::writeLog('Encryption library', "Could not get initialized status for " . $this->userId . ", no record found", \OCP\Util::ERROR); - return false; - // If a record is found - } else { - return (bool)$initializedStatus; - } - - - - $sql = 'UPDATE `*PREFIX*encryption` SET `initialized` = ? WHERE `uid` = ?'; - $args = array($status, $this->userId); - $query = \OCP\DB::prepare($sql); - $query->execute($args); - } - /** * @brief close migration mode after users data has been encrypted successfully * @return boolean @@ -1774,6 +1721,11 @@ class Util { */ public function initEncryption($params) { + $session = new \OCA\Encryption\Session($this->view); + + // we tried to initialize the encryption app for this session + $session->setInitialized(true); + $encryptedKey = Keymanager::getPrivateKey($this->view, $params['uid']); $privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']); @@ -1784,8 +1736,6 @@ class Util { return false; } - $session = new \OCA\Encryption\Session($this->view); - $session->setPrivateKey($privateKey); return $session; diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index 589219f32ad..c0c91bdf652 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -16,7 +16,9 @@ $view = new \OC_FilesystemView('/'); $util = new \OCA\Encryption\Util($view, $user); $session = new \OCA\Encryption\Session($view); -$privateKeySet = $session->getPrivateKey() !== false; +$privateKeySet = $session->getPrivateKey() !== false; +// was the key successfully initialized during log-in +$initialized = $session->getInitialized(); $recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); @@ -31,6 +33,7 @@ if ($recoveryAdminEnabled || !$privateKeySet) { $tmpl->assign('recoveryEnabled', $recoveryAdminEnabled); $tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser); $tmpl->assign('privateKeySet', $privateKeySet); + $tmpl->assign('initialized', $initialized); $result = $tmpl->fetchPage(); } diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 38512453207..ff04556dd53 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -4,7 +4,7 @@ t( 'Encryption' ) ); ?> - +


t( "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" ) ); ?>
- /> t( "Enabled" ) ); ?>
- - t('Your password was changed');?>

- From 5e508f1ccbd3b83ed11f7eab35fea43e1583caf3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 2 Sep 2013 11:34:28 +0200 Subject: [PATCH 03/12] improved documentation of the methods --- apps/files_encryption/lib/session.php | 3 +++ apps/files_encryption/settings-personal.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index f5ce7083af0..648e6e9ab07 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -116,6 +116,8 @@ class Session { * @brief Sets status if we tried to initialize the encyption app * @param bool $privateKey true=initialized false=not initialized * @return bool + * + * @note this doesn not indicate of the init was successful, we just remeber the try! */ public function setInitialized($init) { @@ -130,6 +132,7 @@ class Session { * @brief Gets status if we already tried to initialize the encryption app * @returns bool * + * @note this doesn not indicate of the init was successful, we just remeber the try! */ public function getInitialized() { if (!is_null(\OC::$session->get('encryptionInitialized'))) { diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index c0c91bdf652..ffcb99602e2 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -17,7 +17,7 @@ $util = new \OCA\Encryption\Util($view, $user); $session = new \OCA\Encryption\Session($view); $privateKeySet = $session->getPrivateKey() !== false; -// was the key successfully initialized during log-in +// did we tried to initialize the keys for this session? $initialized = $session->getInitialized(); $recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled'); From 6572ca811fc56c71b4efc970668741630acbd63c Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 2 Sep 2013 11:36:20 +0200 Subject: [PATCH 04/12] error.php no longer needed --- apps/files_encryption/files/error.php | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 apps/files_encryption/files/error.php diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php deleted file mode 100644 index 7a2bb1a2811..00000000000 --- a/apps/files_encryption/files/error.php +++ /dev/null @@ -1,23 +0,0 @@ -t('Your private key is not valid! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app. If this doesn\'t help maybe your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); - - if(isset($_GET['p']) && $_GET['p'] === '1') { - header('HTTP/1.0 404 ' . $errorMsg); - } - - // check if ajax request - if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { - \OCP\JSON::error(array('data' => array('message' => $errorMsg))); - } else { - header('HTTP/1.0 404 ' . $errorMsg); - $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); - $tmpl->printPage(); - } - - exit; -} From 69b1625f0e368e65771fef473f4b4d4a13456354 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 6 Sep 2013 12:27:25 +0200 Subject: [PATCH 05/12] re-added error.php --- apps/files_encryption/files/error.php | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 apps/files_encryption/files/error.php diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php new file mode 100644 index 00000000000..ac0c0269164 --- /dev/null +++ b/apps/files_encryption/files/error.php @@ -0,0 +1,33 @@ +t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); + $init = '0'; + } else { + $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); + $init = '1'; + } + + if (isset($_GET['p']) && $_GET['p'] === '1') { + header('HTTP/1.0 404 ' . $errorMsg); + } + +// check if ajax request + if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { + \OCP\JSON::error(array('data' => array('message' => $errorMsg))); + } else { + header('HTTP/1.0 404 ' . $errorMsg); + $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); + $tmpl->assign('message', $errorMsg); + $tmpl->assign('init', $init); + $tmpl->printPage(); + } + + exit; +} + From fb462e83ccde5c46565c23545c5eb894acbd6fd3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 6 Sep 2013 12:27:40 +0200 Subject: [PATCH 06/12] no longer enforce log out, but provide useful errors/warnings instead --- apps/files/index.php | 7 ++++- apps/files/js/files.js | 9 +++++++ apps/files/templates/index.php | 1 + .../ajax/updatePrivateKeyPassword.php | 1 + apps/files_encryption/appinfo/app.php | 17 ------------ apps/files_encryption/hooks/hooks.php | 2 +- apps/files_encryption/lib/helper.php | 27 +++++-------------- apps/files_encryption/lib/session.php | 15 +++++++---- apps/files_encryption/lib/stream.php | 2 +- apps/files_encryption/lib/util.php | 3 ++- .../templates/invalid_private_key.php | 6 +++-- 11 files changed, 42 insertions(+), 48 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index f1e120c872c..b81ba2bdde9 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -124,8 +124,12 @@ if ($needUpgrade) { $storageInfo=OC_Helper::getStorageInfo($dir); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); + // if the encryption app is disabled, than everything is fine + $encryptionInitStatus = \OCA\Encryption\Session::INIT_SUCCESSFUL; if (OC_App::isEnabled('files_encryption')) { $publicUploadEnabled = 'no'; + $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); + $encryptionInitStatus = $session->getInitialized(); } $trashEnabled = \OCP\App::isEnabled('files_trashbin'); @@ -133,7 +137,7 @@ if ($needUpgrade) { if ($trashEnabled) { $trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user); } - + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); @@ -153,5 +157,6 @@ if ($needUpgrade) { $tmpl->assign('isPublic', false); $tmpl->assign('publicUploadEnabled', $publicUploadEnabled); $tmpl->assign("encryptedFiles", \OCP\Util::encryptedFiles()); + $tmpl->assign("encryptionInitStatus", $encryptionInitStatus); $tmpl->printPage(); } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index d729077ea72..63c3544b53d 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -90,6 +90,15 @@ Files={ } var encryptedFiles = $('#encryptedFiles').val(); + var initStatus = $('#encryptionInitStatus').val(); + if (initStatus === '0') { // enc not initialized, but should be + OC.Notification.show(t('files_encryption', 'Encryption App is enabled but your keys are not initialized, please log-out and log-in again')); + return; + } + if (initStatus === '1') { // encryption tried to init but failed + OC.Notification.show(t('files_encryption', 'Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.')); + return; + } if (encryptedFiles === '1') { OC.Notification.show(t('files_encryption', 'Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files.')); return; diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 24cb8c2fe58..e17273e47b1 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -123,3 +123,4 @@ + \ No newline at end of file diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php index 1e6644da576..29c72952ae9 100644 --- a/apps/files_encryption/ajax/updatePrivateKeyPassword.php +++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php @@ -48,6 +48,7 @@ if ($decryptedKey) { // success or failure if ($return) { + $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.')))); } else { \OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.')))); diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php index 90a9984e27f..cd26cd10cd9 100644 --- a/apps/files_encryption/appinfo/app.php +++ b/apps/files_encryption/appinfo/app.php @@ -41,23 +41,6 @@ if (!OC_Config::getValue('maintenance', false)) { if($sessionReady) { $session = new \OCA\Encryption\Session($view); } - - $user = \OCP\USER::getUser(); - // check if user has a private key - if ($sessionReady === false - || (!$view->file_exists('/' . $user . '/files_encryption/' . $user . '.private.key') - && OCA\Encryption\Crypt::mode() === 'server') - ) { - - // 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 - // enabled) - OCP\User::logout(); - - header("Location: " . OC::$WEBROOT . '/'); - - exit(); - } } } else { // logout user if we are in maintenance to force re-login diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 4c6122b7c2b..c945deeea0c 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -547,7 +547,7 @@ class Hooks { $setMigrationStatus->execute(); $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); - $session->setInitialized(false); + $session->setInitialized(\OCA\Encryption\Session::NOT_INITIALIZED); } } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 7d466b88523..048473ce846 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -237,28 +237,15 @@ class Helper { */ public static function redirectToErrorPage($session) { - $l = \OC_L10N::get('files_encryption'); - - if ($session->getInitialized() === false) { - $errorMsg = $l->t('Encryption app not initialized! Maybe the encryption app was re-enabled during your session. Please try to log out and log back in to initialize the encryption app.'); - } else { - $errorMsg = $l->t('Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.'); - } + $init = $session->getInitialized(); + $location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php'); + $post = 0; if(count($_POST) > 0) { - header('HTTP/1.0 404 ' . $errorMsg); - } - - // check if ajax request - if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { - \OCP\JSON::error(array('data' => array('message' => $errorMsg))); - } else { - header('HTTP/1.0 404 ' . $errorMsg); - $tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest'); - $tmpl->printPage(); - } - - exit; + $post = 1; + } + header('Location: ' . $location . '?p=' . $post . '&i=' . $init); + exit(); } /** diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 648e6e9ab07..25f2198181f 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -30,6 +30,11 @@ class Session { private $view; + const NOT_INITIALIZED = '0'; + const INIT_EXECUTED = '1'; + const INIT_SUCCESSFUL = '2'; + + /** * @brief if session is started, check if ownCloud key pair is set up, if not create it * @param \OC_FilesystemView $view @@ -113,10 +118,10 @@ class Session { } /** - * @brief Sets status if we tried to initialize the encyption app - * @param bool $privateKey true=initialized false=not initialized + * @brief Sets status of encryption app + * @param string $init INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED * @return bool - * + * * @note this doesn not indicate of the init was successful, we just remeber the try! */ public function setInitialized($init) { @@ -130,7 +135,7 @@ class Session { /** * @brief Gets status if we already tried to initialize the encryption app - * @returns bool + * @returns init status INIT_SUCCESSFUL, INIT_EXECUTED, NOT_INOITIALIZED * * @note this doesn not indicate of the init was successful, we just remeber the try! */ @@ -138,7 +143,7 @@ class Session { if (!is_null(\OC::$session->get('encryptionInitialized'))) { return \OC::$session->get('encryptionInitialized'); } else { - return false; + return self::NOT_INITIALIZED; } } diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index 9215352aa78..c6db10ce40d 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -128,7 +128,7 @@ class Stream { $this->unencryptedSize = 0; } else { - +\OCA\Encryption\Helper::redirectToErrorPage($this->session); if($this->privateKey === false) { // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session); diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index 17096a787f2..7a19f954643 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -1724,7 +1724,7 @@ class Util { $session = new \OCA\Encryption\Session($this->view); // we tried to initialize the encryption app for this session - $session->setInitialized(true); + $session->setInitialized(\OCA\Encryption\Session::INIT_EXECUTED); $encryptedKey = Keymanager::getPrivateKey($this->view, $params['uid']); @@ -1737,6 +1737,7 @@ class Util { } $session->setPrivateKey($privateKey); + $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); return $session; } diff --git a/apps/files_encryption/templates/invalid_private_key.php b/apps/files_encryption/templates/invalid_private_key.php index 5c086d6514c..9af65f831b4 100644 --- a/apps/files_encryption/templates/invalid_private_key.php +++ b/apps/files_encryption/templates/invalid_private_key.php @@ -2,9 +2,11 @@
  • - t('Your private key is not valid! Maybe the your password was changed from outside.')); ?> +
    - t('You can unlock your private key in your ')); ?>
    t('personal settings')); ?>. + + p($l->t('Go directly to your ')); ?> t('personal settings')); ?>. +
  • From 1558cb860c2fb26fdde14fce2a16acbb29d12b3e Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 6 Sep 2013 13:16:48 +0200 Subject: [PATCH 07/12] remove test code --- apps/files_encryption/lib/stream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index c6db10ce40d..9215352aa78 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -128,7 +128,7 @@ class Stream { $this->unencryptedSize = 0; } else { -\OCA\Encryption\Helper::redirectToErrorPage($this->session); + if($this->privateKey === false) { // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session); From 54965ce065ba7447cee2f4f60fe1babcc7371214 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 23 Sep 2013 10:40:23 +0200 Subject: [PATCH 08/12] revert changes to 3rdparty submodule --- 3rdparty | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty b/3rdparty index dc87ea63028..98fdc3a4e2f 160000 --- a/3rdparty +++ b/3rdparty @@ -1 +1 @@ -Subproject commit dc87ea630287f27502eba825fbb19fcc33c34c86 +Subproject commit 98fdc3a4e2f56f7d231470418222162dbf95f46a From 67d4b77e8e3bab2fe555ef589f5047c9325974e8 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Mon, 30 Sep 2013 15:11:01 +0200 Subject: [PATCH 09/12] revert changes in personal template --- settings/templates/personal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings/templates/personal.php b/settings/templates/personal.php index e2a4dff82d2..d2ca8154f16 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -40,7 +40,7 @@ if($_['passwordChangeSupported']) {
    t('Your password was changed');?>
    t('Unable to change your password');?>
    - From 47f59d2e421ab38dbf0625d6dfd9c2f21fa11ec1 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 4 Oct 2013 10:37:58 +0200 Subject: [PATCH 10/12] we don't know \OCA\Encryption\Session if the encryption app is not enabled, so we have to set the status manually --- apps/files/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index ecd539dbed4..42eac209b23 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -104,8 +104,8 @@ if ($needUpgrade) { $storageInfo=OC_Helper::getStorageInfo($dir); $maxUploadFilesize=OCP\Util::maxUploadFilesize($dir); $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - // if the encryption app is disabled, than everything is fine - $encryptionInitStatus = \OCA\Encryption\Session::INIT_SUCCESSFUL; + // if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code) + $encryptionInitStatus = 2; if (OC_App::isEnabled('files_encryption')) { $publicUploadEnabled = 'no'; $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); From b7c3af11bf22f3d8cfb227f1eca134940dc26469 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Fri, 4 Oct 2013 10:46:55 +0200 Subject: [PATCH 11/12] fix hidden fieled name --- apps/files/templates/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index fac540939e4..75984b075d4 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -116,4 +116,4 @@ - + From 9d2595a7c59048fc6ed3777a888e03d43a8f03f9 Mon Sep 17 00:00:00 2001 From: Vincent Petry Date: Fri, 4 Oct 2013 11:11:24 +0200 Subject: [PATCH 12/12] Shortened notification message that was too long The message for invalid private key was too long and didn't fit in the notification box. This fix reduces the message to fit properly by removing the extra information. --- apps/files/js/files.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 55ee89e17a2..899bc6469e5 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -69,7 +69,7 @@ Files={ return; } if (initStatus === '1') { // encryption tried to init but failed - OC.Notification.show(t('files_encryption', 'Your private key is not valid! Likely your password was changed outside the ownCloud system (e.g. your corporate directory). You can update your private key password in your personal settings to recover access to your encrypted files.')); + OC.Notification.showHtml(t('files_encryption', 'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.')); return; } if (encryptedFiles === '1') {