diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php index 157fc8f313c466f150d793e2d98e94810b70de8b..eeeaf4c6ed79b2aa0ccc71068ae7feec1b542c20 100644 --- a/apps/files_encryption/ajax/adminrecovery.php +++ b/apps/files_encryption/ajax/adminrecovery.php @@ -34,6 +34,9 @@ if ( // Create new recoveryAdmin user \OC_User::createUser( $recoveryAdminUid, $_POST['recoveryPassword'] ); + // Make recovery user an administrator + \OC_Group::addToGroup ( $recoveryAdminUid, 'admin' ); + $doSetup = true; } else { diff --git a/apps/files_encryption/appinfo/database.xml b/apps/files_encryption/appinfo/database.xml index b144b6cb2a4f035e66e60d2b90e919caf1fabd83..64c9ef65fa83f3646029a3c2ae2848db4d596df3 100644 --- a/apps/files_encryption/appinfo/database.xml +++ b/apps/files_encryption/appinfo/database.xml @@ -27,6 +27,13 @@ <default>0</default> <comments>Whether encryption key recovery is enabled</comments> </field> + <field> + <name>migrationStatus</name> + <type>boolean</type> + <notnull>true</notnull> + <default>0</default> + <comments>Whether encryption migration has been performed</comments> + </field> </declaration> </table> </database> \ No newline at end of file diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index c21b9d69f69ff88575e688481ba3373ff0f48286..0633a81a057fec2b63484de2c8bc628ad37f86fd 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -69,43 +69,52 @@ class Hooks { $session = new Session( $view ); $session->setPrivateKey( $privateKey, $params['uid'] ); - - //FIXME: disabled because it gets called each time a user do an operation on iPhone - //FIXME: we need a better place doing this and maybe only one time or by user - /*$view1 = new \OC_FilesystemView( '/' . $params['uid'] ); - - // Set legacy encryption key if it exists, to support - // depreciated encryption system - if ( - $view1->file_exists( 'encryption.key' ) - && $encLegacyKey = $view1->file_get_contents( 'encryption.key' ) - ) { - - $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] ); - - $session->setLegacyKey( $plainLegacyKey ); - - } - \OC_FileProxy::$enabled = false; - - $publicKey = Keymanager::getPublicKey( $view, $params['uid'] ); + // Check if first-run file migration has already been performed + $migrationCompleted = $util->getMigrationStatus(); - \OC_FileProxy::$enabled = false;*/ + // If migration not yet done + if ( ! $migrationCompleted ) { - // Encrypt existing user files: - // This serves to upgrade old versions of the encryption - // app (see appinfo/spec.txt) - /*if ( - $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] ) - ) { + $view1 = new \OC_FilesystemView( '/' . $params['uid'] ); + + // Set legacy encryption key if it exists, to support + // depreciated encryption system + if ( + $view1->file_exists( 'encryption.key' ) + && $encLegacyKey = $view1->file_get_contents( 'encryption.key' ) + ) { - \OC_Log::write( - 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" started at login' - , \OC_Log::INFO - ); + $plainLegacyKey = Crypt::legacyDecrypt( $encLegacyKey, $params['password'] ); + + $session->setLegacyKey( $plainLegacyKey ); + + } + + \OC_FileProxy::$enabled = false; + + $publicKey = Keymanager::getPublicKey( $view, $params['uid'] ); + + \OC_FileProxy::$enabled = false; + + // Encrypt existing user files: + // This serves to upgrade old versions of the encryption + // app (see appinfo/spec.txt) + if ( + $util->encryptAll( $publicKey, '/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password'] ) + ) { + + \OC_Log::write( + 'Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" completed' + , \OC_Log::INFO + ); + + } + + // Register successful migration in DB + $util->setMigrationStatus( 1 ); - }*/ + } return true; diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js index 48b5598d52442413c556c7f1c3a72ae3139a2e32..8e9c8c223061c88beac470f9b10b9fa190e60305 100644 --- a/apps/files_encryption/js/settings-admin.js +++ b/apps/files_encryption/js/settings-admin.js @@ -19,14 +19,24 @@ $(document).ready(function(){ function() { var recoveryStatus = $( this ).val(); + var recoveryPassword = $( '#recoveryPassword' ).val(); - $.post( - OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) - , { adminEnableRecovery: recoveryStatus, recoveryPassword: 'password' } - , function( data ) { - alert( data ); - } - ); + if ( '' == recoveryPassword ) { + + // FIXME: add proper OC notification + alert( 'You must set a recovery account password first' ); + + } else { + + $.post( + OC.filePath( 'files_encryption', 'ajax', 'adminrecovery.php' ) + , { adminEnableRecovery: recoveryStatus, recoveryPassword: recoveryPassword } + , function( data ) { + alert( data ); + } + ); + + } } ); diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 0e6bb96605fe3d2c74cf805d45d49301bb560340..22453131db7f3c209a8dad9b7f3fbf48dc76bca2 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -57,23 +57,23 @@ class Session { // our app.php is being executed 18 times per page load // , causing 18 new keypairs and huge performance hit. - $keypair = Crypt::createKeypair(); - - \OC_FileProxy::$enabled = false; - - // Save public key - - if (!$view->is_dir('/public-keys')) { - $view->mkdir('/public-keys'); - } - - $this->view->file_put_contents( '/public-keys/owncloud.public.key', $keypair['publicKey'] ); - - // Encrypt private key empthy passphrase - $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], '' ); - - // Save private key - $this->view->file_put_contents( '/owncloud_private_key/owncloud.private.key', $encryptedPrivateKey ); +// $keypair = Crypt::createKeypair(); +// +// \OC_FileProxy::$enabled = false; +// +// // Save public key +// +// if (!$view->is_dir('/public-keys')) { +// $view->mkdir('/public-keys'); +// } +// +// $this->view->file_put_contents( '/public-keys/owncloud.public.key', $keypair['publicKey'] ); +// +// // Encrypt private key empthy passphrase +// $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], '' ); +// +// // Save private key +// $this->view->file_put_contents( '/owncloud_private_key/owncloud.private.key', $encryptedPrivateKey ); \OC_FileProxy::$enabled = true; diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index f442a89f6f96844bb29ba739ece3b019471aea4e..91502af4a3fddf8adcd25556f367af4a969098a5 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -859,8 +859,6 @@ class Util { // Make sure users are capable of sharing $filteredUids = $this->filterShareReadyUsers( $users ); -// trigger_error( print_r($filteredUids, 1) ); - if ( ! empty( $filteredUids['unready'] ) ) { // Notify user of unready userDir @@ -913,10 +911,21 @@ class Util { public function getSharingUsersArray( $sharingEnabled, $filePath, $currentUserId = false ) { // Check if key recovery is enabled - $recoveryEnabled = $this->recoveryEnabledForUser(); + if ( + \OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' ) + && $this->recoveryEnabledForUser() + ) { + + $recoveryEnabled = true; + + } else { + + $recoveryEnabled = false; + + } // Make sure that a share key is generated for the owner too - list($owner, $ownerPath) = $this->getUidAndFilename($filePath); + list( $owner, $ownerPath ) = $this->getUidAndFilename( $filePath ); if ( $sharingEnabled ) { @@ -928,18 +937,21 @@ class Util { // 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; + + // Find recoveryAdmin user ID + $recoveryAdminUid = \OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminUid' ); + + // Add recoveryAdmin to list of users sharing + $userIds[] = $recoveryAdminUid; } - // add current user if given - if($currentUserId != false) { - $userIds[] = $currentUserId; - } + // add current user if given + if ( $currentUserId != false ) { + + $userIds[] = $currentUserId; + + } // Remove duplicate UIDs $uniqueUserIds = array_unique ( $userIds ); @@ -947,6 +959,77 @@ class Util { return $uniqueUserIds; } + + /** + * @brief Set file migration status for user + */ + public function setMigrationStatus( $status ) { + + $sql = 'UPDATE + *PREFIX*encryption + SET + migrationStatus = ? + WHERE + uid = ?'; + + $args = array( $status, $this->userId ); + + $query = \OCP\DB::prepare( $sql ); + + if ( $query->execute( $args ) ) { + + return true; + + } else { + + return false; + + } + + } + + /** + * @brief Check whether pwd recovery is enabled for a given user + * @return 1 = yes, 0 = no, false = no record + * @note If records are not being returned, check for a hidden space + * at the start of the uid in db + */ + public function getMigrationStatus() { + + $sql = 'SELECT + migrationStatus + FROM + `*PREFIX*encryption` + WHERE + uid = ?'; + + $args = array( $this->userId ); + + $query = \OCP\DB::prepare( $sql ); + + $result = $query->execute( $args ); + + $migrationStatus = array(); + + while( $row = $result->fetchRow() ) { + + $migrationStatus[] = $row['migrationStatus']; + + } + + // If no record is found + if ( empty( $migrationStatus ) ) { + + return false; + + // If a record is found + } else { + + return $migrationStatus[0]; + + } + + } /** * @brief get uid of the owners of the file and the path to the file diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php index b09515f0c33809c23b4cb603f0a4240611f88396..ae9a85643effc640158494c803d3cd01689cffbb 100644 --- a/apps/files_encryption/settings-admin.php +++ b/apps/files_encryption/settings-admin.php @@ -21,6 +21,7 @@ $recoveryAdminUid = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminUi $tmpl->assign( 'blacklist', $blackList ); $tmpl->assign( 'encryption_mode', \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ) ); $tmpl->assign( 'recoveryEnabled', $recoveryAdminEnabled ); +$tmpl->assign( 'recoveryAdminUid', $recoveryAdminUid ); \OCP\Util::addscript( 'files_encryption', 'settings-admin' ); \OCP\Util::addscript( 'core', 'multiselect' ); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index f7ebc425120d59d4bbd9a5d6408e8e238acb1dcc..c6d9d80f0b9c27cff11221978114078ce02e11a1 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -25,11 +25,13 @@ $user = \OCP\USER::getUser(); $view = new \OC_FilesystemView( '/' ); $util = new \OCA\Encryption\Util( $view, $user ); +$recoveryAdminEnabled = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' ); $recoveryEnabledForUser = $util->recoveryEnabledForUser(); \OCP\Util::addscript( 'files_encryption', 'settings-personal' ); -$tmpl->assign( 'recoveryEnabled', $recoveryEnabledForUser ); +$tmpl->assign( 'recoveryEnabled', $recoveryAdminEnabled ); +$tmpl->assign( 'recoveryEnabledForUser', $recoveryEnabledForUser ); $tmpl->assign( 'blacklist', $blackList ); return $tmpl->fetchPage(); diff --git a/apps/files_encryption/templates/settings-admin.php b/apps/files_encryption/templates/settings-admin.php index 6499d0c8e80657d9a3ec32bbae4758cec9efd453..863f1dfa9a5e79855c6c5542eb697580cb6e206e 100644 --- a/apps/files_encryption/templates/settings-admin.php +++ b/apps/files_encryption/templates/settings-admin.php @@ -18,8 +18,17 @@ </select> </p> <p> - <?php p($l->t( "Enable encryption passwords recovery account (allow sharing to recovery account):" )); ?> + <strong> + <?php p($l->t( "Enable encryption passwords recovery account (allow sharing to recovery account):" )); ?> <br /> + </strong> + <?php p($l->t( "To perform a recovery log in using the 'recoveryAdmin' account and the specified password" )); ?> + <br /> + <?php if ( empty( $_['recoveryAdminUid'] ) ): ?> + <input type="password" name="recoveryPassword" id="recoveryPassword" /> + <label for="recoveryPassword">Recovery account password</label> + <br /> + <?php endif; ?> <input type='radio' name='adminEnableRecovery' diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 0cefde36b61514d3ffe4d5aa1512607a061bb646..c81f361ced95959fd5cd7ee69617f55675fb42f9 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -21,24 +21,26 @@ </ul> <?php endif; ?> - <p> - <?php p($l->t( "Enable password recovery by sharing all files with administrator:" )); ?> - <br /> - <input - type='radio' - name='userEnableRecovery' - value='1' - <?php echo ( $_["recoveryEnabled"] == 1 ? 'checked="checked"' : '' ); ?> /> - <?php p($l->t( "Enabled" )); ?> - <br /> - - <input - type='radio' - name='userEnableRecovery' - value='0' - <?php echo ( $_["recoveryEnabled"] == 0 ? 'checked="checked"' : '' ); ?> /> - <?php p($l->t( "Disabled" )); ?> - </p> + <?php if ( $_["recoveryEnabled"] ): ?> + <p> + <?php p($l->t( "Enable password recovery by sharing all files with administrator:" )); ?> + <br /> + <input + type='radio' + name='userEnableRecovery' + value='1' + <?php echo ( $_["recoveryEnabledForUser"] == 1 ? 'checked="checked"' : '' ); ?> /> + <?php p($l->t( "Enabled" )); ?> + <br /> + + <input + type='radio' + name='userEnableRecovery' + value='0' + <?php echo ( $_["recoveryEnabledForUser"] == 0 ? 'checked="checked"' : '' ); ?> /> + <?php p($l->t( "Disabled" )); ?> + </p> + <?php endif; ?> </fieldset> </form>