summaryrefslogtreecommitdiffstats
path: root/apps/files_encryption/lib/helper.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_encryption/lib/helper.php')
-rw-r--r--apps/files_encryption/lib/helper.php532
1 files changed, 0 insertions, 532 deletions
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
deleted file mode 100644
index 1ae161ce99e..00000000000
--- a/apps/files_encryption/lib/helper.php
+++ /dev/null
@@ -1,532 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Florin Peter <github@florin-peter.de>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Owen Winkler <a_github@midnightcircus.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2015, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Encryption;
-
-/**
- * Class to manage registration of hooks an various helper methods
- * @package OCA\Files_Encryption
- */
-class Helper {
-
- private static $tmpFileMapping; // Map tmp files to files in data/user/files
-
- /**
- * register share related hooks
- *
- */
- public static function registerShareHooks() {
-
- \OCP\Util::connectHook('OCP\Share', 'pre_shared', 'OCA\Files_Encryption\Hooks', 'preShared');
- \OCP\Util::connectHook('OCP\Share', 'post_shared', 'OCA\Files_Encryption\Hooks', 'postShared');
- \OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OCA\Files_Encryption\Hooks', 'postUnshare');
- }
-
- /**
- * register user related hooks
- *
- */
- public static function registerUserHooks() {
-
- \OCP\Util::connectHook('OC_User', 'post_login', 'OCA\Files_Encryption\Hooks', 'login');
- \OCP\Util::connectHook('OC_User', 'logout', 'OCA\Files_Encryption\Hooks', 'logout');
- \OCP\Util::connectHook('OC_User', 'post_setPassword', 'OCA\Files_Encryption\Hooks', 'setPassphrase');
- \OCP\Util::connectHook('OC_User', 'pre_setPassword', 'OCA\Files_Encryption\Hooks', 'preSetPassphrase');
- \OCP\Util::connectHook('OC_User', 'post_createUser', 'OCA\Files_Encryption\Hooks', 'postCreateUser');
- \OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OCA\Files_Encryption\Hooks', 'postDeleteUser');
- }
-
- /**
- * register filesystem related hooks
- *
- */
- public static function registerFilesystemHooks() {
-
- \OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Files_Encryption\Hooks', 'preRename');
- \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Files_Encryption\Hooks', 'postRenameOrCopy');
- \OCP\Util::connectHook('OC_Filesystem', 'copy', 'OCA\Files_Encryption\Hooks', 'preCopy');
- \OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Files_Encryption\Hooks', 'postRenameOrCopy');
- \OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Files_Encryption\Hooks', 'postDelete');
- \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Encryption\Hooks', 'preDelete');
- \OCP\Util::connectHook('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', 'OCA\Files_Encryption\Hooks', 'postPasswordReset');
- \OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Files_Encryption\Hooks', 'postUnmount');
- \OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Files_Encryption\Hooks', 'preUnmount');
- }
-
- /**
- * register app management related hooks
- *
- */
- public static function registerAppHooks() {
-
- \OCP\Util::connectHook('OC_App', 'pre_disable', 'OCA\Files_Encryption\Hooks', 'preDisable');
- \OCP\Util::connectHook('OC_App', 'post_disable', 'OCA\Files_Encryption\Hooks', 'postEnable');
- }
-
- /**
- * setup user for files_encryption
- *
- * @param Util $util
- * @param string $password
- * @return bool
- */
- public static function setupUser(Util $util, $password) {
- // Check files_encryption infrastructure is ready for action
- if (!$util->ready()) {
-
- \OCP\Util::writeLog('Encryption library', 'User account "' . $util->getUserId()
- . '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
-
- if (!$util->setupServerSide($password)) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * get recovery key id
- *
- * @return string|bool recovery key ID or false
- */
- public static function getRecoveryKeyId() {
- $appConfig = \OC::$server->getAppConfig();
- $key = $appConfig->getValue('files_encryption', 'recoveryKeyId');
-
- return ($key === null) ? false : $key;
- }
-
- public static function getPublicShareKeyId() {
- $appConfig = \OC::$server->getAppConfig();
- $key = $appConfig->getValue('files_encryption', 'publicShareKeyId');
-
- return ($key === null) ? false : $key;
- }
-
- /**
- * enable recovery
- *
- * @param string $recoveryKeyId
- * @param string $recoveryPassword
- * @return bool
- */
- public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) {
-
- $view = new \OC\Files\View('/');
- $appConfig = \OC::$server->getAppConfig();
-
- if ($recoveryKeyId === null) {
- $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8);
- $appConfig->setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId);
- }
-
- if (!Keymanager::recoveryKeyExists($view)) {
-
- $keypair = Crypt::createKeypair();
-
- // Save public key
- Keymanager::setPublicKey($keypair['publicKey'], $recoveryKeyId);
-
- $cipher = Helper::getCipher();
- $encryptedKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword, $cipher);
- if ($encryptedKey) {
- Keymanager::setPrivateSystemKey($encryptedKey, $recoveryKeyId);
- // Set recoveryAdmin as enabled
- $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1);
- $return = true;
- }
-
- } else { // get recovery key and check the password
- $util = new Util(new \OC\Files\View('/'), \OCP\User::getUser());
- $return = $util->checkRecoveryPassword($recoveryPassword);
- if ($return) {
- $appConfig->setValue('files_encryption', 'recoveryAdminEnabled', 1);
- }
- }
-
- return $return;
- }
-
- /**
- * Check if a path is a .part file
- * @param string $path Path that may identify a .part file
- * @return bool
- */
- public static function isPartialFilePath($path) {
-
- $extension = pathinfo($path, PATHINFO_EXTENSION);
- if ( $extension === 'part') {
- return true;
- } else {
- return false;
- }
-
- }
-
-
- /**
- * Remove .path extension from a file path
- * @param string $path Path that may identify a .part file
- * @return string File path without .part extension
- * @note this is needed for reusing keys
- */
- public static function stripPartialFileExtension($path) {
- $extension = pathinfo($path, PATHINFO_EXTENSION);
-
- if ( $extension === 'part') {
-
- $newLength = strlen($path) - 5; // 5 = strlen(".part") = strlen(".etmp")
- $fPath = substr($path, 0, $newLength);
-
- // if path also contains a transaction id, we remove it too
- $extension = pathinfo($fPath, PATHINFO_EXTENSION);
- if(substr($extension, 0, 12) === 'ocTransferId') { // 12 = strlen("ocTransferId")
- $newLength = strlen($fPath) - strlen($extension) -1;
- $fPath = substr($fPath, 0, $newLength);
- }
- return $fPath;
-
- } else {
- return $path;
- }
- }
-
- /**
- * disable recovery
- *
- * @param string $recoveryPassword
- * @return bool
- */
- public static function adminDisableRecovery($recoveryPassword) {
- $util = new Util(new \OC\Files\View('/'), \OCP\User::getUser());
- $return = $util->checkRecoveryPassword($recoveryPassword);
-
- if ($return) {
- // Set recoveryAdmin as disabled
- \OC::$server->getAppConfig()->setValue('files_encryption', 'recoveryAdminEnabled', 0);
- }
-
- return $return;
- }
-
- /**
- * checks if access is public/anonymous user
- * @return bool
- */
- public static function isPublicAccess() {
- if (\OCP\User::getUser() === false) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Format a path to be relative to the /user/files/ directory
- * @param string $path the absolute path
- * @return string e.g. turns '/admin/files/test.txt' into 'test.txt'
- */
- public static function stripUserFilesPath($path) {
- $split = self::splitPath($path);
-
- // it is not a file relative to data/user/files
- if (count($split) < 4 || $split[2] !== 'files') {
- return false;
- }
-
- $sliced = array_slice($split, 3);
- $relPath = implode('/', $sliced);
-
- return $relPath;
- }
-
- /**
- * try to get the user from the path if no user is logged in
- * @param string $path
- * @return string user
- */
- public static function getUser($path) {
-
- $user = \OCP\User::getUser();
-
-
- // if we are logged in, then we return the userid
- if ($user) {
- return $user;
- }
-
- // if no user is logged in we try to access a publicly shared files.
- // In this case we need to try to get the user from the path
- return self::getUserFromPath($path);
- }
-
- /**
- * extract user from path
- *
- * @param string $path
- * @return string user id
- * @throws Exception\EncryptionException
- */
- public static function getUserFromPath($path) {
- $split = self::splitPath($path);
-
- if (count($split) > 2 && (
- $split[2] === 'files' || $split[2] === 'files_versions' || $split[2] === 'cache' || $split[2] === 'files_trashbin')) {
-
- $user = $split[1];
-
- if (\OCP\User::userExists($user)) {
- return $user;
- }
- }
-
- throw new Exception\EncryptionException('Could not determine user', Exception\EncryptionException::GENERIC);
- }
-
- /**
- * get path to the corresponding file in data/user/files if path points
- * to a file in cache
- *
- * @param string $path path to a file in cache
- * @return string path to corresponding file relative to data/user/files
- * @throws Exception\EncryptionException
- */
- public static function getPathFromCachedFile($path) {
- $split = self::splitPath($path);
-
- if (count($split) < 5) {
- throw new Exception\EncryptionException('no valid cache file path', Exception\EncryptionException::GENERIC);
- }
-
- // we skip /user/cache/transactionId
- $sliced = array_slice($split, 4);
-
- return implode('/', $sliced);
- }
-
-
- /**
- * get path to the corresponding file in data/user/files for a version
- *
- * @param string $path path to a version
- * @return string path to corresponding file relative to data/user/files
- * @throws Exception\EncryptionException
- */
- public static function getPathFromVersion($path) {
- $split = self::splitPath($path);
-
- if (count($split) < 4) {
- throw new Exception\EncryptionException('no valid path to a version', Exception\EncryptionException::GENERIC);
- }
-
- // we skip user/files_versions
- $sliced = array_slice($split, 3);
- $relPath = implode('/', $sliced);
- //remove the last .v
- $realPath = substr($relPath, 0, strrpos($relPath, '.v'));
-
- return $realPath;
- }
-
- /**
- * create directory recursively
- *
- * @param string $path
- * @param \OC\Files\View $view
- */
- public static function mkdirr($path, \OC\Files\View $view) {
- $dirParts = self::splitPath(dirname($path));
- $dir = "";
- foreach ($dirParts as $part) {
- $dir = $dir . '/' . $part;
- if (!$view->file_exists($dir)) {
- $view->mkdir($dir);
- }
- }
- }
-
- /**
- * redirect to a error page
- * @param Session $session
- * @param int|null $errorCode
- * @throws \Exception
- */
- public static function redirectToErrorPage(Session $session, $errorCode = null) {
-
- if ($errorCode === null) {
- $init = $session->getInitialized();
- switch ($init) {
- case Session::INIT_EXECUTED:
- $errorCode = Crypt::ENCRYPTION_PRIVATE_KEY_NOT_VALID_ERROR;
- break;
- case Session::NOT_INITIALIZED:
- $errorCode = Crypt::ENCRYPTION_NOT_INITIALIZED_ERROR;
- break;
- default:
- $errorCode = Crypt::ENCRYPTION_UNKNOWN_ERROR;
- }
- }
-
- $location = \OCP\Util::linkToAbsolute('apps/files_encryption/files', 'error.php');
- $post = 0;
- if(count($_POST) > 0) {
- $post = 1;
- }
-
- if(defined('PHPUNIT_RUN') and PHPUNIT_RUN) {
- throw new \Exception("Encryption error: $errorCode");
- }
-
- header('Location: ' . $location . '?p=' . $post . '&errorCode=' . $errorCode);
- exit();
- }
-
- /**
- * check requirements for encryption app.
- * @return bool true if requirements are met
- */
- public static function checkRequirements() {
-
- //openssl extension needs to be loaded
- return extension_loaded("openssl");
-
- }
-
- /**
- * check some common errors if the server isn't configured properly for encryption
- * @return bool true if configuration seems to be OK
- */
- public static function checkConfiguration() {
- if(self::getOpenSSLPkey()) {
- return true;
- } else {
- while ($msg = openssl_error_string()) {
- \OCP\Util::writeLog('Encryption library', 'openssl_pkey_new() fails: ' . $msg, \OCP\Util::ERROR);
- }
- return false;
- }
- }
-
- /**
- * Create an openssl pkey with config-supplied settings
- * WARNING: This initializes a new private keypair, which is computationally expensive
- * @return resource The pkey resource created
- */
- public static function getOpenSSLPkey() {
- return openssl_pkey_new(self::getOpenSSLConfig());
- }
-
- /**
- * Return an array of OpenSSL config options, default + config
- * Used for multiple OpenSSL functions
- * @return array The combined defaults and config settings
- */
- public static function getOpenSSLConfig() {
- $config = array('private_key_bits' => 4096);
- $config = array_merge(\OC::$server->getConfig()->getSystemValue('openssl', array()), $config);
- return $config;
- }
-
- /**
- * remember from which file the tmp file (getLocalFile() call) was created
- * @param string $tmpFile path of tmp file
- * @param string $originalFile path of the original file relative to data/
- */
- public static function addTmpFileToMapper($tmpFile, $originalFile) {
- self::$tmpFileMapping[$tmpFile] = $originalFile;
- }
-
- /**
- * get the path of the original file
- * @param string $tmpFile path of the tmp file
- * @return string|false path of the original file or false
- */
- public static function getPathFromTmpFile($tmpFile) {
- if (isset(self::$tmpFileMapping[$tmpFile])) {
- return self::$tmpFileMapping[$tmpFile];
- }
-
- return false;
- }
-
- /**
- * detect file type, encryption can read/write regular files, versions
- * and cached files
- *
- * @param string $path
- * @return int
- * @throws Exception\EncryptionException
- */
- public static function detectFileType($path) {
- $parts = self::splitPath($path);
-
- if (count($parts) > 2) {
- switch ($parts[2]) {
- case 'files':
- return Util::FILE_TYPE_FILE;
- case 'files_versions':
- return Util::FILE_TYPE_VERSION;
- case 'cache':
- return Util::FILE_TYPE_CACHE;
- }
- }
-
- // thow exception if we couldn't detect a valid file type
- throw new Exception\EncryptionException('Could not detect file type', Exception\EncryptionException::GENERIC);
- }
-
- /**
- * read the cipher used for encryption from the config.php
- *
- * @return string
- */
- public static function getCipher() {
-
- $cipher = \OC::$server->getConfig()->getSystemValue('cipher', Crypt::DEFAULT_CIPHER);
-
- if ($cipher !== 'AES-256-CFB' && $cipher !== 'AES-128-CFB') {
- \OCP\Util::writeLog('files_encryption',
- 'wrong cipher defined in config.php, only AES-128-CFB and AES-256-CFB is supported. Fall back ' . Crypt::DEFAULT_CIPHER,
- \OCP\Util::WARN);
-
- $cipher = Crypt::DEFAULT_CIPHER;
- }
-
- return $cipher;
- }
-
- public static function splitPath($path) {
- $normalized = \OC\Files\Filesystem::normalizePath($path);
- return explode('/', $normalized);
- }
-
-}
-