Ejemplo n.º 1
0
 /**
  * @brief Startup encryption backend upon user login
  * @note This method should never be called for users using client side encryption
  */
 public static function login($params)
 {
     if (\OCP\App::isEnabled('files_encryption') === false) {
         return true;
     }
     $l = new \OC_L10N('files_encryption');
     $view = new \OC_FilesystemView('/');
     // ensure filesystem is loaded
     if (!\OC\Files\Filesystem::$loaded) {
         \OC_Util::setupFS($params['uid']);
     }
     $privateKey = \OCA\Encryption\Keymanager::getPrivateKey($view, $params['uid']);
     // if no private key exists, check server configuration
     if (!$privateKey) {
         //check if all requirements are met
         if (!Helper::checkRequirements() || !Helper::checkConfiguration()) {
             $error_msg = $l->t("Missing requirements.");
             $hint = $l->t('Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled.');
             \OC_App::disable('files_encryption');
             \OCP\Util::writeLog('Encryption library', $error_msg . ' ' . $hint, \OCP\Util::ERROR);
             \OCP\Template::printErrorPage($error_msg, $hint);
         }
     }
     $util = new Util($view, $params['uid']);
     // setup user, if user not ready force relogin
     if (Helper::setupUser($util, $params['password']) === false) {
         return false;
     }
     $session = $util->initEncryption($params);
     // Check if first-run file migration has already been performed
     $ready = false;
     if ($util->getMigrationStatus() === Util::MIGRATION_OPEN) {
         $ready = $util->beginMigration();
     }
     // If migration not yet done
     if ($ready) {
         $userView = new \OC_FilesystemView('/' . $params['uid']);
         // Set legacy encryption key if it exists, to support
         // depreciated encryption system
         if ($userView->file_exists('encryption.key') && ($encLegacyKey = $userView->file_get_contents('encryption.key'))) {
             $plainLegacyKey = Crypt::legacyDecrypt($encLegacyKey, $params['password']);
             $session->setLegacyKey($plainLegacyKey);
         }
         // Encrypt existing user files:
         if ($util->encryptAll('/' . $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->finishMigration();
     }
     return true;
 }
Ejemplo n.º 2
0
 /**
  * @medium
  * @brief Test that data that is written by the crypto stream wrapper
  * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
  * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
  * reassembly of its data
  */
 function testSymmetricStreamEncryptLongFileContent()
 {
     // Generate a a random filename
     $filename = 'tmp-' . uniqid() . '.test';
     $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
     // Save long data as encrypted file using stream wrapper
     $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Get file contents without using any wrapper to get it's actual contents on disk
     $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
     // Re-enable proxy - our work is done
     \OC_FileProxy::$enabled = $proxyStatus;
     // Check that the file was encrypted before being written to disk
     $this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
     // Manuallly split saved file into separate IVs and encrypted chunks
     $r = preg_split('/(00iv00.{16,18})/', $retreivedCryptedFile, NULL, PREG_SPLIT_DELIM_CAPTURE);
     //print_r($r);
     // Join IVs and their respective data chunks
     $e = array();
     $i = 0;
     while ($i < count($r) - 1) {
         $e[] = $r[$i] . $r[$i + 1];
         $i = $i + 2;
     }
     //print_r($e);
     // Get the encrypted keyfile
     $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $util, $filename);
     // Attempt to fetch the user's shareKey
     $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $util, $filename);
     // get session
     $session = new \OCA\Encryption\Session($this->view);
     // get private key
     $privateKey = $session->getPrivateKey($this->userId);
     // Decrypt keyfile with shareKey
     $plainKeyfile = Encryption\Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
     // Set var for reassembling decrypted content
     $decrypt = '';
     // Manually decrypt chunk
     foreach ($e as $chunk) {
         $chunkDecrypt = Encryption\Crypt::symmetricDecryptFileContent($chunk, $plainKeyfile);
         // Assemble decrypted chunks
         $decrypt .= $chunkDecrypt;
     }
     $this->assertEquals($this->dataLong . $this->dataLong, $decrypt);
     // Teardown
     $this->view->unlink($this->userId . '/files/' . $filename);
     Encryption\Keymanager::deleteFileKey($this->view, $filename);
 }
Ejemplo n.º 3
0
 /**
  * @brief if the file was really deleted we remove the encryption keys
  * @param array $params
  * @return boolean
  */
 public static function postDelete($params)
 {
     if (!isset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
         return true;
     }
     $deletedFile = self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]];
     $path = $deletedFile['path'];
     $user = $deletedFile['uid'];
     // we don't need to remember the file any longer
     unset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]);
     $view = new \OC\Files\View('/');
     // return if the file still exists and wasn't deleted correctly
     if ($view->file_exists('/' . $user . '/files/' . $path)) {
         return true;
     }
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Delete keyfile & shareKey so it isn't orphaned
     if (!Keymanager::deleteFileKey($view, $path, $user)) {
         \OCP\Util::writeLog('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $user . '/files/' . $path . '"', \OCP\Util::ERROR);
     }
     Keymanager::delAllShareKeys($view, $user, $path);
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Ejemplo n.º 4
0
 /**
  * @medium
  * Test that data that is written by the crypto stream wrapper with AES 128
  * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
  * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
  * reassembly of its data
  */
 public function testStreamDecryptLongFileContentWithoutHeader()
 {
     // Generate a a random filename
     $filename = 'tmp-' . $this->getUniqueID() . '.test';
     \OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
     // Save long data as encrypted file using stream wrapper
     $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
     \OCP\Config::deleteSystemValue('cipher');
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Get file contents without using any wrapper to get it's actual contents on disk
     $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
     // Check that the file was encrypted before being written to disk
     $this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
     // remove the header to check if we can also decrypt old files without a header,
     //  this files should fall back to AES-128
     $cryptedWithoutHeader = substr($retreivedCryptedFile, Encryption\Crypt::BLOCKSIZE);
     $this->view->file_put_contents($this->userId . '/files/' . $filename, $cryptedWithoutHeader);
     // Re-enable proxy - our work is done
     \OC_FileProxy::$enabled = $proxyStatus;
     $decrypted = file_get_contents('crypt:///' . $this->userId . '/files/' . $filename);
     $this->assertEquals($this->dataLong . $this->dataLong, $decrypted);
     // Teardown
     $this->view->unlink($this->userId . '/files/' . $filename);
     Encryption\Keymanager::deleteFileKey($this->view, $filename);
 }
Ejemplo n.º 5
0
 function testDelAllShareKeysFile()
 {
     $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/existingFile.txt', 'data');
     // create folder structure for some dummy share key files
     $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1');
     // create some dummy share keys for the existing file
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data');
     // create some dummy share keys for a non-existing file
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user1.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user2.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user3.shareKey', 'data');
     $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data');
     // try to del all share keys from a existing file, should fail because the file still exists
     $result = Encryption\Keymanager::delAllShareKeys($this->view, Test_Encryption_Keymanager::TEST_USER, 'folder1/existingFile.txt');
     $this->assertFalse($result);
     // check if share keys still exists
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey'));
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey'));
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey'));
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey'));
     // try to del all share keys from file, should succeed because the does not exist any more
     $result2 = Encryption\Keymanager::delAllShareKeys($this->view, Test_Encryption_Keymanager::TEST_USER, 'folder1/nonexistingFile.txt');
     $this->assertTrue($result2);
     // check if share keys are really gone
     $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey'));
     // check that it only deleted keys or users who had access, others remain
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user1.shareKey'));
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user2.shareKey'));
     $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user3.shareKey'));
     // cleanup
     $this->view->deleteAll('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1');
 }
Ejemplo n.º 6
0
 /**
  * @brief replacing encryption keys during password change should be allowed
  *        until the user logged in for the first time
  */
 public function testSetPassphrase()
 {
     $view = new \OC\Files\View();
     // set user password for the first time
     \OCA\Encryption\Hooks::postCreateUser(array('uid' => 'newUser', 'password' => 'newUserPassword'));
     $this->assertTrue($view->file_exists('public-keys/newUser.public.key'));
     $this->assertTrue($view->file_exists('newUser/files_encryption/newUser.private.key'));
     // check if we are able to decrypt the private key
     $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser');
     $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'newUserPassword');
     $this->assertTrue(is_string($privateKey));
     // change the password before the user logged-in for the first time,
     // we can replace the encryption keys
     \OCA\Encryption\Hooks::setPassphrase(array('uid' => 'newUser', 'password' => 'passwordChanged'));
     $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser');
     $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged');
     $this->assertTrue(is_string($privateKey));
     // now create a files folder to simulate a already used account
     $view->mkdir('/newUser/files');
     // change the password after the user logged in, now the password should not change
     \OCA\Encryption\Hooks::setPassphrase(array('uid' => 'newUser', 'password' => 'passwordChanged2'));
     $encryptedKey = \OCA\Encryption\Keymanager::getPrivateKey($view, 'newUser');
     $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged2');
     $this->assertFalse($privateKey);
     $privateKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged');
     $this->assertTrue(is_string($privateKey));
 }
Ejemplo n.º 7
0
\OCP\JSON::checkAppEnabled('files_encryption');
\OCP\JSON::callCheck();
$l = \OC::$server->getL10N('core');
$return = false;
$oldPassword = $_POST['oldPassword'];
$newPassword = $_POST['newPassword'];
$view = new \OC\Files\View('/');
$session = new \OCA\Encryption\Session($view);
$user = \OCP\User::getUser();
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key';
$encryptedKey = $view->file_get_contents($keyPath);
$decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword);
if ($decryptedKey) {
    $cipher = \OCA\Encryption\Helper::getCipher();
    $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword, $cipher);
    if ($encryptedKey) {
        \OCA\Encryption\Keymanager::setPrivateKey($encryptedKey, $user);
        $session->setPrivateKey($decryptedKey);
        $return = true;
    }
}
\OC_FileProxy::$enabled = $proxyStatus;
// 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.'))));
}
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
if ($_POST['newPassword'] !== $_POST['confirmPassword']) {
    $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password');
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
$view = new \OC\Files\View('/');
$util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser());
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$keyId = $util->getRecoveryKeyId();
$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
$encryptedRecoveryKey = $view->file_get_contents($keyPath);
$decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword);
if ($decryptedRecoveryKey) {
    $cipher = \OCA\Encryption\Helper::getCipher();
    $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword, $cipher);
    if ($encryptedKey) {
        \OCA\Encryption\Keymanager::setPrivateSystemKey($encryptedKey, $keyId . '.private.key');
        $return = true;
    }
}
\OC_FileProxy::$enabled = $proxyStatus;
// success or failure
if ($return) {
    \OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
} else {
    \OCP\JSON::error(array('data' => array('message' => $l->t('Could not change the password. Maybe the old password was not correct.'))));
}
Ejemplo n.º 9
0
 /**
  * @brief
  */
 public static function postUnshare($params)
 {
     // NOTE: $params has keys:
     // [itemType] => file
     // [itemSource] => 13
     // [shareType] => 0
     // [shareWith] => test1
     // [itemParent] =>
     if (\OCP\App::isEnabled('files_encryption') === false) {
         return true;
     }
     if ($params['itemType'] === 'file' || $params['itemType'] === 'folder') {
         $view = new \OC_FilesystemView('/');
         $userId = \OCP\User::getUser();
         $util = new Util($view, $userId);
         $path = $util->fileIdToPath($params['itemSource']);
         // check if this is a re-share
         if ($params['itemParent']) {
             // get the parent from current share
             $parent = $util->getShareParent($params['itemParent']);
             // get target path
             $targetPath = $util->fileIdToPath($params['itemSource']);
             $targetPathSplit = array_reverse(explode('/', $targetPath));
             // init values
             $path = '';
             $sharedPart = ltrim($parent['file_target'], '/');
             // rebuild path
             foreach ($targetPathSplit as $pathPart) {
                 if ($pathPart !== $sharedPart) {
                     $path = '/' . $pathPart . $path;
                 } else {
                     break;
                 }
             }
             // prefix path with Shared
             $path = '/Shared' . $parent['file_target'] . $path;
         }
         // for group shares get a list of the group members
         if ($params['shareType'] === \OCP\Share::SHARE_TYPE_GROUP) {
             $userIds = \OC_Group::usersInGroup($params['shareWith']);
         } else {
             if ($params['shareType'] === \OCP\Share::SHARE_TYPE_LINK) {
                 $userIds = array($util->getPublicShareKeyId());
             } else {
                 $userIds = array($params['shareWith']);
             }
         }
         // get the path including mount point only if not a shared folder
         if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
             // get path including the the storage mount point
             $path = $util->getPathWithMountPoint($params['itemSource']);
         }
         // if we unshare a folder we need a list of all (sub-)files
         if ($params['itemType'] === 'folder') {
             $allFiles = $util->getAllFiles($path);
         } else {
             $allFiles = array($path);
         }
         foreach ($allFiles as $path) {
             // check if the user still has access to the file, otherwise delete share key
             $sharingUsers = $util->getSharingUsersArray(true, $path);
             // Unshare every user who no longer has access to the file
             $delUsers = array_diff($userIds, $sharingUsers);
             // delete share key
             Keymanager::delShareKey($view, $delUsers, $path);
         }
     }
 }
Ejemplo n.º 10
0
 /**
  * @medium
  */
 function testRecursiveDelShareKeys()
 {
     // generate filename
     $filename = '/tmp-' . time() . '.txt';
     // create folder structure
     $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1');
     $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/subfolder');
     $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/subfolder/subsubfolder');
     // enable encryption proxy
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = true;
     // save file with content
     $cryptedFile = file_put_contents('crypt:///' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/subfolder/subsubfolder' . $filename, $this->dataShort);
     // test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // change encryption proxy to previous state
     \OC_FileProxy::$enabled = $proxyStatus;
     // recursive delete keys
     Encryption\Keymanager::delShareKey($this->view, array('admin'), '/folder1/');
     // check if share key not exists
     $this->assertFalse($this->view->file_exists('/admin/files_encryption/share-keys/folder1/subfolder/subsubfolder/' . $filename . '.admin.shareKey'));
     // enable encryption proxy
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = true;
     // cleanup
     $this->view->unlink('/admin/files/folder1');
     // change encryption proxy to previous state
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Ejemplo n.º 11
0
 /**
  * unmount file from yourself
  */
 public static function postUmount($params)
 {
     if (!isset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
         return true;
     }
     $umountedFile = self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]];
     $path = $umountedFile['path'];
     $user = $umountedFile['uid'];
     $itemType = $umountedFile['itemType'];
     $view = new \OC\Files\View();
     $util = new Util($view, $user);
     // we don't need to remember the file any longer
     unset(self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]]);
     // if we unshare a folder we need a list of all (sub-)files
     if ($itemType === 'folder') {
         $allFiles = $util->getAllFiles($path);
     } else {
         $allFiles = array($path);
     }
     foreach ($allFiles as $path) {
         // check if the user still has access to the file, otherwise delete share key
         $sharingUsers = \OCP\Share::getUsersSharingFile($path, $user);
         if (!in_array(\OCP\User::getUser(), $sharingUsers['users'])) {
             Keymanager::delShareKey($view, array(\OCP\User::getUser()), $path, $user);
         }
     }
 }
Ejemplo n.º 12
0
 /**
  * Startup encryption backend upon user login
  * @note This method should never be called for users using client side encryption
  */
 public static function login($params)
 {
     if (\OCP\App::isEnabled('files_encryption') === false) {
         return true;
     }
     $l = new \OC_L10N('files_encryption');
     $view = new \OC\Files\View('/');
     // ensure filesystem is loaded
     if (!\OC\Files\Filesystem::$loaded) {
         \OC_Util::setupFS($params['uid']);
     }
     $privateKey = \OCA\Encryption\Keymanager::getPrivateKey($view, $params['uid']);
     // if no private key exists, check server configuration
     if (!$privateKey) {
         //check if all requirements are met
         if (!Helper::checkRequirements() || !Helper::checkConfiguration()) {
             $error_msg = $l->t("Missing requirements.");
             $hint = $l->t('Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled.');
             \OC_App::disable('files_encryption');
             \OCP\Util::writeLog('Encryption library', $error_msg . ' ' . $hint, \OCP\Util::ERROR);
             \OCP\Template::printErrorPage($error_msg, $hint);
         }
     }
     $util = new Util($view, $params['uid']);
     // setup user, if user not ready force relogin
     if (Helper::setupUser($util, $params['password']) === false) {
         return false;
     }
     $session = $util->initEncryption($params);
     // Check if first-run file migration has already been performed
     $ready = false;
     $migrationStatus = $util->getMigrationStatus();
     if ($migrationStatus === Util::MIGRATION_OPEN && $session !== false) {
         $ready = $util->beginMigration();
     } elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) {
         // refuse login as long as the initial encryption is running
         sleep(5);
         \OCP\User::logout();
         return false;
     }
     $result = true;
     // If migration not yet done
     if ($ready) {
         // Encrypt existing user files
         try {
             $result = $util->encryptAll('/' . $params['uid'] . '/' . 'files');
         } catch (\Exception $ex) {
             \OCP\Util::writeLog('Encryption library', 'Initial encryption failed! Error: ' . $ex->getMessage(), \OCP\Util::FATAL);
             $result = false;
         }
         if ($result) {
             \OC_Log::write('Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" completed', \OC_Log::INFO);
             // Register successful migration in DB
             $util->finishMigration();
         } else {
             \OCP\Util::writeLog('Encryption library', 'Initial encryption failed!', \OCP\Util::FATAL);
             $util->resetMigrationStatus();
             \OCP\User::logout();
         }
     }
     return $result;
 }
Ejemplo n.º 13
0
 /**
  * decrypt private key and add it to the current session
  * @param array $params with 'uid' and 'password'
  * @return mixed session or false
  */
 public function initEncryption($params)
 {
     $session = new \OCA\Encryption\Session($this->view);
     // we tried to initialize the encryption app for this session
     $session->setInitialized(\OCA\Encryption\Session::INIT_EXECUTED);
     $encryptedKey = Keymanager::getPrivateKey($this->view, $params['uid']);
     $privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']);
     if ($privateKey === false) {
         \OCP\Util::writeLog('Encryption library', 'Private key for user "' . $params['uid'] . '" is not valid! Maybe the user password was changed from outside if so please change it back to gain access', \OCP\Util::ERROR);
         return false;
     }
     $session->setPrivateKey($privateKey);
     $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL);
     return $session;
 }