From: Florin Peter Date: Thu, 23 May 2013 21:56:31 +0000 (+0200) Subject: fixes after review from @DeepDiver1975 X-Git-Tag: v6.0.0alpha2~743^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6c8de5ae6d11886d498e810808484a2bdfeaef12;p=nextcloud-server.git fixes after review from @DeepDiver1975 --- diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php index 53afefc721b..2066300a163 100644 --- a/apps/files_encryption/hooks/hooks.php +++ b/apps/files_encryption/hooks/hooks.php @@ -189,7 +189,7 @@ class Hooks { // Save public key $view->file_put_contents( '/public-keys/'.$user.'.public.key', $keypair['publicKey'] ); - // Encrypt private key empthy passphrase + // Encrypt private key empty passphrase $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $newUserPassword ); // Save private key diff --git a/apps/files_encryption/js/settings-admin.js b/apps/files_encryption/js/settings-admin.js index c58d75341df..7c1866445ee 100644 --- a/apps/files_encryption/js/settings-admin.js +++ b/apps/files_encryption/js/settings-admin.js @@ -99,4 +99,4 @@ $(document).ready(function(){ ); }); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/apps/files_encryption/js/settings-personal.js b/apps/files_encryption/js/settings-personal.js index 3b9b00dc797..312b672ad46 100644 --- a/apps/files_encryption/js/settings-personal.js +++ b/apps/files_encryption/js/settings-personal.js @@ -57,4 +57,4 @@ $(document).ready(function(){ } ); -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 1a5c9300a27..f5b7a8a0a40 100755 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -26,7 +26,7 @@ namespace OCA\Encryption; //require_once '../3rdparty/Crypt_Blowfish/Blowfish.php'; -require_once realpath(dirname(__FILE__) . '/../3rdparty/Crypt_Blowfish/Blowfish.php'); +require_once realpath( dirname( __FILE__ ) . '/../3rdparty/Crypt_Blowfish/Blowfish.php' ); /** * Class for common cryptography functionality @@ -40,8 +40,7 @@ class Crypt * @param string $user name (use system wide setting if name=null) * @return string 'client' or 'server' */ - public static function mode($user = null) - { + public static function mode( $user = null ) { return 'server'; @@ -51,20 +50,19 @@ class Crypt * @brief Create a new encryption keypair * @return array publicKey, privatekey */ - public static function createKeypair() - { + public static function createKeypair() { - $res = openssl_pkey_new(array('private_key_bits' => 4096)); + $res = openssl_pkey_new( array( 'private_key_bits' => 4096 ) ); // Get private key - openssl_pkey_export($res, $privateKey); + openssl_pkey_export( $res, $privateKey ); // Get public key - $publicKey = openssl_pkey_get_details($res); + $publicKey = openssl_pkey_get_details( $res ); $publicKey = $publicKey['key']; - return (array('publicKey' => $publicKey, 'privateKey' => $privateKey)); + return ( array( 'publicKey' => $publicKey, 'privateKey' => $privateKey ) ); } @@ -77,8 +75,7 @@ class Crypt * blocks with encryption alone, hence padding is added to achieve the * required length. */ - public static function addPadding($data) - { + public static function addPadding( $data ) { $padded = $data . 'xx'; @@ -91,12 +88,11 @@ class Crypt * @param string $padded padded data to remove padding from * @return string unpadded data on success, false on error */ - public static function removePadding($padded) - { + public static function removePadding( $padded ) { - if (substr($padded, -2) == 'xx') { + if ( substr( $padded, -2 ) == 'xx' ) { - $data = substr($padded, 0, -2); + $data = substr( $padded, 0, -2 ); return $data; @@ -115,27 +111,26 @@ class Crypt * @return boolean * @note see also OCA\Encryption\Util->isEncryptedPath() */ - public static function isCatfileContent($content) - { + public static function isCatfileContent( $content ) { - if (!$content) { + if ( !$content ) { return false; } - $noPadding = self::removePadding($content); + $noPadding = self::removePadding( $content ); // Fetch encryption metadata from end of file - $meta = substr($noPadding, -22); + $meta = substr( $noPadding, -22 ); // Fetch IV from end of file - $iv = substr($meta, -16); + $iv = substr( $meta, -16 ); // Fetch identifier from start of metadata - $identifier = substr($meta, 0, 6); + $identifier = substr( $meta, 0, 6 ); - if ($identifier == '00iv00') { + if ( $identifier == '00iv00' ) { return true; @@ -152,16 +147,15 @@ class Crypt * @param string $path * @return bool */ - public static function isEncryptedMeta($path) - { + public static function isEncryptedMeta( $path ) { // TODO: Use DI to get \OC\Files\Filesystem out of here // Fetch all file metadata from DB - $metadata = \OC\Files\Filesystem::getFileInfo($path); + $metadata = \OC\Files\Filesystem::getFileInfo( $path ); // Return encryption status - return isset($metadata['encrypted']) and ( bool )$metadata['encrypted']; + return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted']; } @@ -172,19 +166,18 @@ class Crypt * e.g. filename or /Docs/filename, NOT admin/files/filename * @return boolean */ - public static function isLegacyEncryptedContent($data, $relPath) - { + public static function isLegacyEncryptedContent( $data, $relPath ) { // Fetch all file metadata from DB - $metadata = \OC\Files\Filesystem::getFileInfo($relPath, ''); + $metadata = \OC\Files\Filesystem::getFileInfo( $relPath, '' ); // If a file is flagged with encryption in DB, but isn't a // valid content + IV combination, it's probably using the // legacy encryption system if ( - isset($metadata['encrypted']) + isset( $metadata['encrypted'] ) and $metadata['encrypted'] === true - and !self::isCatfileContent($data) + and !self::isCatfileContent( $data ) ) { return true; @@ -199,18 +192,20 @@ class Crypt /** * @brief Symmetrically encrypt a string + * @param $plainContent + * @param $iv + * @param string $passphrase * @return string encrypted file content */ - public static function encrypt($plainContent, $iv, $passphrase = '') - { + public static function encrypt( $plainContent, $iv, $passphrase = '' ) { - if ($encryptedContent = openssl_encrypt($plainContent, 'AES-128-CFB', $passphrase, false, $iv)) { + if ( $encryptedContent = openssl_encrypt( $plainContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $encryptedContent; } else { - \OC_Log::write('Encryption library', 'Encryption (symmetric) of content failed', \OC_Log::ERROR); + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of content failed', \OC_Log::ERROR ); return false; @@ -220,21 +215,21 @@ class Crypt /** * @brief Symmetrically decrypt a string + * @param $encryptedContent + * @param $iv + * @param $passphrase + * @throws \Exception * @return string decrypted file content */ - public static function decrypt($encryptedContent, $iv, $passphrase) - { + public static function decrypt( $encryptedContent, $iv, $passphrase ) { - if ($plainContent = openssl_decrypt($encryptedContent, 'AES-128-CFB', $passphrase, false, $iv)) { + if ( $plainContent = openssl_decrypt( $encryptedContent, 'AES-128-CFB', $passphrase, false, $iv ) ) { return $plainContent; - } else { - throw new \Exception('Encryption library: Decryption (symmetric) of content failed'); - - return false; + throw new \Exception( 'Encryption library: Decryption (symmetric) of content failed' ); } @@ -246,8 +241,7 @@ class Crypt * @param string $iv IV to be concatenated * @returns string concatenated content */ - public static function concatIv($content, $iv) - { + public static function concatIv( $content, $iv ) { $combined = $content . '00iv00' . $iv; @@ -260,17 +254,16 @@ class Crypt * @param string $catFile concatenated data to be split * @returns array keys: encrypted, iv */ - public static function splitIv($catFile) - { + public static function splitIv( $catFile ) { // Fetch encryption metadata from end of file - $meta = substr($catFile, -22); + $meta = substr( $catFile, -22 ); // Fetch IV from end of file - $iv = substr($meta, -16); + $iv = substr( $meta, -16 ); // Remove IV and IV identifier text to expose encrypted content - $encrypted = substr($catFile, 0, -22); + $encrypted = substr( $catFile, 0, -22 ); $split = array( 'encrypted' => $encrypted @@ -290,10 +283,9 @@ class Crypt * @note IV need not be specified, as it will be stored in the returned keyfile * and remain accessible therein. */ - public static function symmetricEncryptFileContent($plainContent, $passphrase = '') - { + public static function symmetricEncryptFileContent( $plainContent, $passphrase = '' ) { - if (!$plainContent) { + if ( !$plainContent ) { return false; @@ -301,18 +293,18 @@ class Crypt $iv = self::generateIv(); - if ($encryptedContent = self::encrypt($plainContent, $iv, $passphrase)) { + if ( $encryptedContent = self::encrypt( $plainContent, $iv, $passphrase ) ) { // Combine content to encrypt with IV identifier and actual IV - $catfile = self::concatIv($encryptedContent, $iv); + $catfile = self::concatIv( $encryptedContent, $iv ); - $padded = self::addPadding($catfile); + $padded = self::addPadding( $catfile ); return $padded; } else { - \OC_Log::write('Encryption library', 'Encryption (symmetric) of keyfile content failed', \OC_Log::ERROR); + \OC_Log::write( 'Encryption library', 'Encryption (symmetric) of keyfile content failed', \OC_Log::ERROR ); return false; @@ -334,25 +326,26 @@ class Crypt * * This function decrypts a file */ - public static function symmetricDecryptFileContent($keyfileContent, $passphrase = '') - { + public static function symmetricDecryptFileContent( $keyfileContent, $passphrase = '' ) { - if (!$keyfileContent) { + if ( !$keyfileContent ) { - throw new \Exception('Encryption library: no data provided for decryption'); + throw new \Exception( 'Encryption library: no data provided for decryption' ); } // Remove padding - $noPadding = self::removePadding($keyfileContent); + $noPadding = self::removePadding( $keyfileContent ); // Split into enc data and catfile - $catfile = self::splitIv($noPadding); + $catfile = self::splitIv( $noPadding ); - if ($plainContent = self::decrypt($catfile['encrypted'], $catfile['iv'], $passphrase)) { + if ( $plainContent = self::decrypt( $catfile['encrypted'], $catfile['iv'], $passphrase ) ) { return $plainContent; + } else { + return false; } } @@ -365,16 +358,15 @@ class Crypt * * This function decrypts a file */ - public static function symmetricEncryptFileContentKeyfile($plainContent) - { + public static function symmetricEncryptFileContentKeyfile( $plainContent ) { $key = self::generateKey(); - if ($encryptedContent = self::symmetricEncryptFileContent($plainContent, $key)) { + if ( $encryptedContent = self::symmetricEncryptFileContent( $plainContent, $key ) ) { return array( - 'key' => $key - , 'encrypted' => $encryptedContent + 'key' => $key, + 'encrypted' => $encryptedContent ); } else { @@ -392,29 +384,28 @@ class Crypt * @returns array keys: keys (array, key = userId), data * @note symmetricDecryptFileContent() can decrypt files created using this method */ - public static function multiKeyEncrypt($plainContent, array $publicKeys) - { + public static function multiKeyEncrypt( $plainContent, array $publicKeys ) { // openssl_seal returns false without errors if $plainContent // is empty, so trigger our own error - if (empty($plainContent)) { + if ( empty( $plainContent ) ) { - trigger_error("Cannot mutliKeyEncrypt empty plain content"); - throw new \Exception('Cannot mutliKeyEncrypt empty plain content'); + throw new \Exception( 'Cannot mutliKeyEncrypt empty plain content' ); } // Set empty vars to be set by openssl by reference $sealed = ''; $shareKeys = array(); + $mappedShareKeys = array(); - if (openssl_seal($plainContent, $sealed, $shareKeys, $publicKeys)) { + if ( openssl_seal( $plainContent, $sealed, $shareKeys, $publicKeys ) ) { $i = 0; // Ensure each shareKey is labelled with its // corresponding userId - foreach ($publicKeys as $userId => $publicKey) { + foreach ( $publicKeys as $userId => $publicKey ) { $mappedShareKeys[$userId] = $shareKeys[$i]; $i++; @@ -422,8 +413,8 @@ class Crypt } return array( - 'keys' => $mappedShareKeys - , 'data' => $sealed + 'keys' => $mappedShareKeys, + 'data' => $sealed ); } else { @@ -446,22 +437,21 @@ class Crypt * * This function decrypts a file */ - public static function multiKeyDecrypt($encryptedContent, $shareKey, $privateKey) - { + public static function multiKeyDecrypt( $encryptedContent, $shareKey, $privateKey ) { - if (!$encryptedContent) { + if ( !$encryptedContent ) { return false; } - if (openssl_open($encryptedContent, $plainContent, $shareKey, $privateKey)) { + if ( openssl_open( $encryptedContent, $plainContent, $shareKey, $privateKey ) ) { return $plainContent; } else { - \OC_Log::write('Encryption library', 'Decryption (asymmetric) of sealed content failed', \OC_Log::ERROR); + \OC_Log::write( 'Encryption library', 'Decryption (asymmetric) of sealed content failed', \OC_Log::ERROR ); return false; @@ -473,10 +463,9 @@ class Crypt * @brief Asymetrically encrypt a string using a public key * @return string encrypted file */ - public static function keyEncrypt($plainContent, $publicKey) - { + public static function keyEncrypt( $plainContent, $publicKey ) { - openssl_public_encrypt($plainContent, $encryptedContent, $publicKey); + openssl_public_encrypt( $plainContent, $encryptedContent, $publicKey ); return $encryptedContent; @@ -486,12 +475,11 @@ class Crypt * @brief Asymetrically decrypt a file using a private key * @return string decrypted file */ - public static function keyDecrypt($encryptedContent, $privatekey) - { + public static function keyDecrypt( $encryptedContent, $privatekey ) { - $result = @openssl_private_decrypt($encryptedContent, $plainContent, $privatekey); + $result = @openssl_private_decrypt( $encryptedContent, $plainContent, $privatekey ); - if ($result) { + if ( $result ) { return $plainContent; } @@ -503,27 +491,26 @@ class Crypt * @brief Generates a pseudo random initialisation vector * @return String $iv generated IV */ - public static function generateIv() - { + public static function generateIv() { - if ($random = openssl_random_pseudo_bytes(12, $strong)) { + if ( $random = openssl_random_pseudo_bytes( 12, $strong ) ) { - if (!$strong) { + if ( !$strong ) { // If OpenSSL indicates randomness is insecure, log error - \OC_Log::write('Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()', \OC_Log::WARN); + \OC_Log::write( 'Encryption library', 'Insecure symmetric key was generated using openssl_random_pseudo_bytes()', \OC_Log::WARN ); } // We encode the iv purely for string manipulation // purposes - it gets decoded before use - $iv = base64_encode($random); + $iv = base64_encode( $random ); return $iv; } else { - throw new \Exception('Generating IV failed'); + throw new \Exception( 'Generating IV failed' ); } @@ -533,16 +520,15 @@ class Crypt * @brief Generate a pseudo random 1024kb ASCII key * @returns $key Generated key */ - public static function generateKey() - { + public static function generateKey() { // Generate key - if ($key = base64_encode(openssl_random_pseudo_bytes(183, $strong))) { + if ( $key = base64_encode( openssl_random_pseudo_bytes( 183, $strong ) ) ) { - if (!$strong) { + if ( !$strong ) { // If OpenSSL indicates randomness is insecure, log error - throw new \Exception('Encryption library, Insecure symmetric key was generated using openssl_random_pseudo_bytes()'); + throw new \Exception( 'Encryption library, Insecure symmetric key was generated using openssl_random_pseudo_bytes()' ); } @@ -563,12 +549,11 @@ class Crypt * * if the key is left out, the default handeler will be used */ - public static function getBlowfish($key = '') - { + public static function getBlowfish( $key = '' ) { - if ($key) { + if ( $key ) { - return new \Crypt_Blowfish($key); + return new \Crypt_Blowfish( $key ); } else { @@ -582,14 +567,13 @@ class Crypt * @param $passphrase * @return mixed */ - public static function legacyCreateKey($passphrase) - { + public static function legacyCreateKey( $passphrase ) { // Generate a random integer - $key = mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999); + $key = mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ) . mt_rand( 10000, 99999 ); // Encrypt the key with the passphrase - $legacyEncKey = self::legacyEncrypt($key, $passphrase); + $legacyEncKey = self::legacyEncrypt( $key, $passphrase ); return $legacyEncKey; @@ -605,12 +589,11 @@ class Crypt * * This function encrypts an content */ - public static function legacyEncrypt($content, $passphrase = '') - { + public static function legacyEncrypt( $content, $passphrase = '' ) { - $bf = self::getBlowfish($passphrase); + $bf = self::getBlowfish( $passphrase ); - return $bf->encrypt($content); + return $bf->encrypt( $content ); } @@ -624,14 +607,13 @@ class Crypt * * This function decrypts an content */ - public static function legacyDecrypt($content, $passphrase = '') - { + public static function legacyDecrypt( $content, $passphrase = '' ) { - $bf = self::getBlowfish($passphrase); + $bf = self::getBlowfish( $passphrase ); - $decrypted = $bf->decrypt($content); + $decrypted = $bf->decrypt( $content ); - return rtrim($decrypted, "\0");; + return rtrim( $decrypted, "\0" );; } @@ -641,17 +623,16 @@ class Crypt * @param int $maxLength * @return string */ - private static function legacyBlockDecrypt($data, $key = '', $maxLength = 0) - { + private static function legacyBlockDecrypt( $data, $key = '', $maxLength = 0 ) { $result = ''; - while (strlen($data)) { - $result .= self::legacyDecrypt(substr($data, 0, 8192), $key); - $data = substr($data, 8192); + while ( strlen( $data ) ) { + $result .= self::legacyDecrypt( substr( $data, 0, 8192 ), $key ); + $data = substr( $data, 8192 ); } - if ($maxLength > 0) { - return substr($result, 0, $maxLength); + if ( $maxLength > 0 ) { + return substr( $result, 0, $maxLength ); } else { - return rtrim($result, "\0"); + return rtrim( $result, "\0" ); } } @@ -663,18 +644,17 @@ class Crypt * @param $path * @return array */ - public static function legacyKeyRecryptKeyfile($legacyEncryptedContent, $legacyPassphrase, $publicKeys, $newPassphrase, $path) - { + public static function legacyKeyRecryptKeyfile( $legacyEncryptedContent, $legacyPassphrase, $publicKeys, $newPassphrase, $path ) { - $decrypted = self::legacyBlockDecrypt($legacyEncryptedContent, $legacyPassphrase); + $decrypted = self::legacyBlockDecrypt( $legacyEncryptedContent, $legacyPassphrase ); // Encrypt plain data, generate keyfile & encrypted file - $cryptedData = self::symmetricEncryptFileContentKeyfile($decrypted); + $cryptedData = self::symmetricEncryptFileContentKeyfile( $decrypted ); // Encrypt plain keyfile to multiple sharefiles - $multiEncrypted = Crypt::multiKeyEncrypt($cryptedData['key'], $publicKeys); + $multiEncrypted = Crypt::multiKeyEncrypt( $cryptedData['key'], $publicKeys ); - return array('data' => $cryptedData['encrypted'], 'filekey' => $multiEncrypted['data'], 'sharekeys' => $multiEncrypted['keys']); + return array( 'data' => $cryptedData['encrypted'], 'filekey' => $multiEncrypted['data'], 'sharekeys' => $multiEncrypted['keys'] ); } diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index e4bf2c1226a..43f573c16b9 100755 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -37,35 +37,32 @@ class Helper * @brief register share related hooks * */ - public static function registerShareHooks() - { + public static function registerShareHooks() { - \OCP\Util::connectHook('OCP\Share', 'pre_shared', 'OCA\Encryption\Hooks', 'preShared'); - \OCP\Util::connectHook('OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared'); - \OCP\Util::connectHook('OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare'); + \OCP\Util::connectHook( 'OCP\Share', 'pre_shared', 'OCA\Encryption\Hooks', 'preShared' ); + \OCP\Util::connectHook( 'OCP\Share', 'post_shared', 'OCA\Encryption\Hooks', 'postShared' ); + \OCP\Util::connectHook( 'OCP\Share', 'post_unshare', 'OCA\Encryption\Hooks', 'postUnshare' ); } /** * @brief register user related hooks * */ - public static function registerUserHooks() - { + public static function registerUserHooks() { - \OCP\Util::connectHook('OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login'); - \OCP\Util::connectHook('OC_User', 'post_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase'); - \OCP\Util::connectHook('OC_User', 'post_createUser', 'OCA\Encryption\Hooks', 'postCreateUser'); - \OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OCA\Encryption\Hooks', 'postDeleteUser'); + \OCP\Util::connectHook( 'OC_User', 'post_login', 'OCA\Encryption\Hooks', 'login' ); + \OCP\Util::connectHook( 'OC_User', 'post_setPassword', 'OCA\Encryption\Hooks', 'setPassphrase' ); + \OCP\Util::connectHook( 'OC_User', 'post_createUser', 'OCA\Encryption\Hooks', 'postCreateUser' ); + \OCP\Util::connectHook( 'OC_User', 'post_deleteUser', 'OCA\Encryption\Hooks', 'postDeleteUser' ); } /** * @brief register filesystem related hooks * */ - public static function registerFilesystemHooks() - { + public static function registerFilesystemHooks() { - \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename'); + \OCP\Util::connectHook( 'OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename' ); } /** @@ -75,14 +72,13 @@ class Helper * @param string $password * @return bool */ - public static function setupUser($util, $password) - { + public static function setupUser( $util, $password ) { // Check files_encryption infrastructure is ready for action - if (!$util->ready()) { + if ( !$util->ready() ) { - \OC_Log::write('Encryption library', 'User account "' . $util->getUserId() . '" is not ready for encryption; configuration started', \OC_Log::DEBUG); + \OC_Log::write( 'Encryption library', 'User account "' . $util->getUserId() . '" is not ready for encryption; configuration started', \OC_Log::DEBUG ); - if (!$util->setupServerSide($password)) { + if ( !$util->setupServerSide( $password ) ) { return false; } } @@ -99,22 +95,21 @@ class Helper * @internal param string $password * @return bool */ - public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) - { - $view = new \OC\Files\View('/'); + public static function adminEnableRecovery( $recoveryKeyId, $recoveryPassword ) { + $view = new \OC\Files\View( '/' ); - if ($recoveryKeyId === null) { - $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); - \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); + if ( $recoveryKeyId === null ) { + $recoveryKeyId = 'recovery_' . substr( md5( time() ), 0, 8 ); + \OC_Appconfig::setValue( 'files_encryption', 'recoveryKeyId', $recoveryKeyId ); } - if (!$view->is_dir('/owncloud_private_key')) { - $view->mkdir('/owncloud_private_key'); + if ( !$view->is_dir( '/owncloud_private_key' ) ) { + $view->mkdir( '/owncloud_private_key' ); } if ( - (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key") - || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key")) + ( !$view->file_exists( "/public-keys/" . $recoveryKeyId . ".public.key" ) + || !$view->file_exists( "/owncloud_private_key/" . $recoveryKeyId . ".private.key" ) ) ) { $keypair = \OCA\Encryption\Crypt::createKeypair(); @@ -123,37 +118,37 @@ class Helper // Save public key - if (!$view->is_dir('/public-keys')) { - $view->mkdir('/public-keys'); + if ( !$view->is_dir( '/public-keys' ) ) { + $view->mkdir( '/public-keys' ); } - $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']); + $view->file_put_contents( '/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey'] ); // Encrypt private key empthy passphrase - $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword); + $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $recoveryPassword ); // Save private key - $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey); + $view->file_put_contents( '/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey ); // create control file which let us check later on if the entered password was correct. - $encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt("ownCloud", $keypair['publicKey']); - if (!$view->is_dir('/control-file')) { - $view->mkdir('/control-file'); + $encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt( "ownCloud", $keypair['publicKey'] ); + if ( !$view->is_dir( '/control-file' ) ) { + $view->mkdir( '/control-file' ); } - $view->file_put_contents('/control-file/controlfile.enc', $encryptedControlData); + $view->file_put_contents( '/control-file/controlfile.enc', $encryptedControlData ); \OC_FileProxy::$enabled = true; // Set recoveryAdmin as enabled - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); + \OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminEnabled', 1 ); $return = true; } else { // get recovery key and check the password - $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); - $return = $util->checkRecoveryPassword($_POST['recoveryPassword']); - if ($return) { - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); + $util = new \OCA\Encryption\Util( new \OC_FilesystemView( '/' ), \OCP\User::getUser() ); + $return = $util->checkRecoveryPassword( $_POST['recoveryPassword'] ); + if ( $return ) { + \OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminEnabled', 1 ); } } @@ -167,14 +162,13 @@ class Helper * @param $recoveryPassword * @return bool */ - public static function adminDisableRecovery($recoveryPassword) - { - $util = new Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); - $return = $util->checkRecoveryPassword($recoveryPassword); + public static function adminDisableRecovery( $recoveryPassword ) { + $util = new Util( new \OC_FilesystemView( '/' ), \OCP\User::getUser() ); + $return = $util->checkRecoveryPassword( $recoveryPassword ); - if ($return) { + if ( $return ) { // Set recoveryAdmin as disabled - \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 0); + \OC_Appconfig::setValue( 'files_encryption', 'recoveryAdminEnabled', 0 ); } return $return; diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index a8cbc19d401..aaa2e4ba1b5 100755 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -38,15 +38,14 @@ class Keymanager * @return string private key or false (hopefully) * @note the key returned by this method must be decrypted before use */ - public static function getPrivateKey(\OC_FilesystemView $view, $user) - { + public static function getPrivateKey( \OC_FilesystemView $view, $user ) { $path = '/' . $user . '/' . 'files_encryption' . '/' . $user . '.private.key'; $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $key = $view->file_get_contents($path); + $key = $view->file_get_contents( $path ); \OC_FileProxy::$enabled = $proxyStatus; @@ -59,13 +58,12 @@ class Keymanager * @param $userId * @return string public key or false */ - public static function getPublicKey(\OC_FilesystemView $view, $userId) - { + public static function getPublicKey( \OC_FilesystemView $view, $userId ) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $result = $view->file_get_contents('/public-keys/' . $userId . '.public.key'); + $result = $view->file_get_contents( '/public-keys/' . $userId . '.public.key' ); \OC_FileProxy::$enabled = $proxyStatus; @@ -79,12 +77,11 @@ class Keymanager * @param $userId * @return array keys: privateKey, publicKey */ - public static function getUserKeys(\OC_FilesystemView $view, $userId) - { + public static function getUserKeys( \OC_FilesystemView $view, $userId ) { return array( - 'publicKey' => self::getPublicKey($view, $userId) - , 'privateKey' => self::getPrivateKey($view, $userId) + 'publicKey' => self::getPublicKey( $view, $userId ) + , 'privateKey' => self::getPrivateKey( $view, $userId ) ); } @@ -95,14 +92,13 @@ class Keymanager * @param array $userIds * @return array of public keys for the specified users */ - public static function getPublicKeys(\OC_FilesystemView $view, array $userIds) - { + public static function getPublicKeys( \OC_FilesystemView $view, array $userIds ) { $keys = array(); - foreach ($userIds as $userId) { + foreach ( $userIds as $userId ) { - $keys[$userId] = self::getPublicKey($view, $userId); + $keys[$userId] = self::getPublicKey( $view, $userId ); } @@ -122,41 +118,40 @@ class Keymanager * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - public static function setFileKey(\OC_FilesystemView $view, $path, $userId, $catfile) - { + public static function setFileKey( \OC_FilesystemView $view, $path, $userId, $catfile ) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); - list($owner, $filename) = $util->getUidAndFilename($path); + $util = new Util( $view, \OCP\User::getUser() ); + list( $owner, $filename ) = $util->getUidAndFilename( $path ); $basePath = '/' . $owner . '/files_encryption/keyfiles'; - $targetPath = self::keySetPreparation($view, $filename, $basePath, $owner); + $targetPath = self::keySetPreparation( $view, $filename, $basePath, $owner ); - if (!$view->is_dir($basePath . '/' . $targetPath)) { + if ( !$view->is_dir( $basePath . '/' . $targetPath ) ) { // create all parent folders - $info = pathinfo($basePath . '/' . $targetPath); - $keyfileFolderName = $view->getLocalFolder($info['dirname']); + $info = pathinfo( $basePath . '/' . $targetPath ); + $keyfileFolderName = $view->getLocalFolder( $info['dirname'] ); - if (!file_exists($keyfileFolderName)) { + if ( !file_exists( $keyfileFolderName ) ) { - mkdir($keyfileFolderName, 0750, true); + mkdir( $keyfileFolderName, 0750, true ); } } // try reusing key file if part file - if (self::isPartialFilePath($targetPath)) { + if ( self::isPartialFilePath( $targetPath ) ) { - $result = $view->file_put_contents($basePath . '/' . self::fixPartialFilePath($targetPath) . '.key', $catfile); + $result = $view->file_put_contents( $basePath . '/' . self::fixPartialFilePath( $targetPath ) . '.key', $catfile ); } else { - $result = $view->file_put_contents($basePath . '/' . $targetPath . '.key', $catfile); + $result = $view->file_put_contents( $basePath . '/' . $targetPath . '.key', $catfile ); } @@ -172,13 +167,12 @@ class Keymanager * @return string File path without .part extension * @note this is needed for reusing keys */ - public static function fixPartialFilePath($path) - { + public static function fixPartialFilePath( $path ) { - if (preg_match('/\.part$/', $path)) { + if ( preg_match( '/\.part$/', $path ) ) { - $newLength = strlen($path) - 5; - $fPath = substr($path, 0, $newLength); + $newLength = strlen( $path ) - 5; + $fPath = substr( $path, 0, $newLength ); return $fPath; @@ -195,10 +189,9 @@ class Keymanager * @param string $path Path that may identify a .part file * @return bool */ - public static function isPartialFilePath($path) - { + public static function isPartialFilePath( $path ) { - if (preg_match('/\.part$/', $path)) { + if ( preg_match( '/\.part$/', $path ) ) { return true; @@ -220,15 +213,14 @@ class Keymanager * @note The keyfile returned is asymmetrically encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getFileKey(\OC_FilesystemView $view, $userId, $filePath) - { + public static function getFileKey( \OC_FilesystemView $view, $userId, $filePath ) { // try reusing key file if part file - if (self::isPartialFilePath($filePath)) { + if ( self::isPartialFilePath( $filePath ) ) { - $result = self::getFileKey($view, $userId, self::fixPartialFilePath($filePath)); + $result = self::getFileKey( $view, $userId, self::fixPartialFilePath( $filePath ) ); - if ($result) { + if ( $result ) { return $result; @@ -236,19 +228,19 @@ class Keymanager } - $util = new Util($view, \OCP\User::getUser()); + $util = new Util( $view, \OCP\User::getUser() ); - list($owner, $filename) = $util->getUidAndFilename($filePath); - $filePath_f = ltrim($filename, '/'); + list( $owner, $filename ) = $util->getUidAndFilename( $filePath ); + $filePath_f = ltrim( $filename, '/' ); $keyfilePath = '/' . $owner . '/files_encryption/keyfiles/' . $filePath_f . '.key'; $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - if ($view->file_exists($keyfilePath)) { + if ( $view->file_exists( $keyfilePath ) ) { - $result = $view->file_get_contents($keyfilePath); + $result = $view->file_get_contents( $keyfilePath ); } else { @@ -272,27 +264,26 @@ class Keymanager * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT * /data/admin/files/mydoc.txt */ - public static function deleteFileKey(\OC_FilesystemView $view, $userId, $path) - { + public static function deleteFileKey( \OC_FilesystemView $view, $userId, $path ) { - $trimmed = ltrim($path, '/'); + $trimmed = ltrim( $path, '/' ); $keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed; $result = false; - if ($view->is_dir($keyPath)) { + if ( $view->is_dir( $keyPath ) ) { - $result = $view->unlink($keyPath); + $result = $view->unlink( $keyPath ); - } else if ($view->file_exists($keyPath . '.key')) { + } else if ( $view->file_exists( $keyPath . '.key' ) ) { - $result = $view->unlink($keyPath . '.key'); + $result = $view->unlink( $keyPath . '.key' ); } - if (!$result) { + if ( !$result ) { - \OC_Log::write('Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR); + \OC_Log::write( 'Encryption library', 'Could not delete keyfile; does not exist: "' . $keyPath, \OC_Log::ERROR ); } @@ -307,19 +298,19 @@ class Keymanager * @note Encryption of the private key must be performed by client code * as no encryption takes place here */ - public static function setPrivateKey($key) - { + public static function setPrivateKey( $key ) { $user = \OCP\User::getUser(); - $view = new \OC_FilesystemView('/' . $user . '/files_encryption'); + $view = new \OC_FilesystemView( '/' . $user . '/files_encryption' ); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - if (!$view->file_exists('')) $view->mkdir(''); + if ( !$view->file_exists( '' ) ) + $view->mkdir( '' ); - $result = $view->file_put_contents($user . '.private.key', $key); + $result = $view->file_put_contents( $user . '.private.key', $key ); \OC_FileProxy::$enabled = $proxyStatus; @@ -340,22 +331,21 @@ class Keymanager * @note The keyfile is not encrypted here. Client code must * asymmetrically encrypt the keyfile before passing it to this method */ - public static function setShareKey(\OC_FilesystemView $view, $path, $userId, $shareKey) - { + public static function setShareKey( \OC_FilesystemView $view, $path, $userId, $shareKey ) { // Here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); + $util = new Util( $view, \OCP\User::getUser() ); - list($owner, $filename) = $util->getUidAndFilename($path); + list( $owner, $filename ) = $util->getUidAndFilename( $path ); $basePath = '/' . $owner . '/files_encryption/share-keys'; - $shareKeyPath = self::keySetPreparation($view, $filename, $basePath, $owner); + $shareKeyPath = self::keySetPreparation( $view, $filename, $basePath, $owner ); // try reusing key file if part file - if (self::isPartialFilePath($shareKeyPath)) { + if ( self::isPartialFilePath( $shareKeyPath ) ) { - $writePath = $basePath . '/' . self::fixPartialFilePath($shareKeyPath) . '.' . $userId . '.shareKey'; + $writePath = $basePath . '/' . self::fixPartialFilePath( $shareKeyPath ) . '.' . $userId . '.shareKey'; } else { @@ -366,12 +356,12 @@ class Keymanager $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $result = $view->file_put_contents($writePath, $shareKey); + $result = $view->file_put_contents( $writePath, $shareKey ); \OC_FileProxy::$enabled = $proxyStatus; if ( - is_int($result) + is_int( $result ) && $result > 0 ) { @@ -392,17 +382,16 @@ class Keymanager * @param array $shareKeys * @return bool */ - public static function setShareKeys(\OC_FilesystemView $view, $path, array $shareKeys) - { + public static function setShareKeys( \OC_FilesystemView $view, $path, array $shareKeys ) { // $shareKeys must be an array with the following format: // [userId] => [encrypted key] $result = true; - foreach ($shareKeys as $userId => $shareKey) { + foreach ( $shareKeys as $userId => $shareKey ) { - if (!self::setShareKey($view, $path, $userId, $shareKey)) { + if ( !self::setShareKey( $view, $path, $userId, $shareKey ) ) { // If any of the keys are not set, flag false $result = false; @@ -426,15 +415,14 @@ class Keymanager * @note The sharekey returned is encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getShareKey(\OC_FilesystemView $view, $userId, $filePath) - { + public static function getShareKey( \OC_FilesystemView $view, $userId, $filePath ) { // try reusing key file if part file - if (self::isPartialFilePath($filePath)) { + if ( self::isPartialFilePath( $filePath ) ) { - $result = self::getShareKey($view, $userId, self::fixPartialFilePath($filePath)); + $result = self::getShareKey( $view, $userId, self::fixPartialFilePath( $filePath ) ); - if ($result) { + if ( $result ) { return $result; @@ -446,14 +434,14 @@ class Keymanager \OC_FileProxy::$enabled = false; //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); + $util = new Util( $view, \OCP\User::getUser() ); - list($owner, $filename) = $util->getUidAndFilename($filePath); - $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey'); + list( $owner, $filename ) = $util->getUidAndFilename( $filePath ); + $shareKeyPath = \OC\Files\Filesystem::normalizePath( '/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey' ); - if ($view->file_exists($shareKeyPath)) { + if ( $view->file_exists( $shareKeyPath ) ) { - $result = $view->file_get_contents($shareKeyPath); + $result = $view->file_get_contents( $shareKeyPath ); } else { @@ -473,16 +461,18 @@ class Keymanager * @param string $userId owner of the file * @param string $filePath path to the file, relative to the owners file dir */ - public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) - { + public static function delAllShareKeys( \OC_FilesystemView $view, $userId, $filePath ) { - if ($view->is_dir($userId . '/files/' . $filePath)) { - $view->unlink($userId . '/files_encryption/share-keys/' . $filePath); + if ( $view->is_dir( $userId . '/files/' . $filePath ) ) { + $view->unlink( $userId . '/files_encryption/share-keys/' . $filePath ); } else { - $localKeyPath = $view->getLocalFile($userId . '/files_encryption/share-keys/' . $filePath); - $matches = glob(preg_quote($localKeyPath) . '*.shareKey'); - foreach ($matches as $ma) { - unlink($ma); + $localKeyPath = $view->getLocalFile( $userId . '/files_encryption/share-keys/' . $filePath ); + $matches = glob( preg_quote( $localKeyPath ) . '*.shareKey' ); + foreach ( $matches as $ma ) { + $result = unlink( $ma ); + if ( !$result ) { + \OC_Log::write( 'Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $filePath . '"', \OC_Log::ERROR ); + } } } } @@ -490,30 +480,29 @@ class Keymanager /** * @brief Delete a single user's shareKey for a single file */ - public static function delShareKey(\OC_FilesystemView $view, $userIds, $filePath) - { + public static function delShareKey( \OC_FilesystemView $view, $userIds, $filePath ) { $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; //here we need the currently logged in user, while userId can be a different user - $util = new Util($view, \OCP\User::getUser()); + $util = new Util( $view, \OCP\User::getUser() ); - list($owner, $filename) = $util->getUidAndFilename($filePath); + list( $owner, $filename ) = $util->getUidAndFilename( $filePath ); - $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename); + $shareKeyPath = \OC\Files\Filesystem::normalizePath( '/' . $owner . '/files_encryption/share-keys/' . $filename ); - if ($view->is_dir($shareKeyPath)) { + if ( $view->is_dir( $shareKeyPath ) ) { - $localPath = \OC\Files\Filesystem::normalizePath($view->getLocalFolder($shareKeyPath)); - self::recursiveDelShareKeys($localPath, $userIds); + $localPath = \OC\Files\Filesystem::normalizePath( $view->getLocalFolder( $shareKeyPath ) ); + self::recursiveDelShareKeys( $localPath, $userIds ); } else { - foreach ($userIds as $userId) { + foreach ( $userIds as $userId ) { - if (!$view->unlink($shareKeyPath . '.' . $userId . '.shareKey')) { - \OC_Log::write('Encryption library', 'Could not delete shareKey; does not exist: "' . $shareKeyPath . '.' . $userId . '.shareKey"', \OC_Log::ERROR); + if ( !$view->unlink( $shareKeyPath . '.' . $userId . '.shareKey' ) ) { + \OC_Log::write( 'Encryption library', 'Could not delete shareKey; does not exist: "' . $shareKeyPath . '.' . $userId . '.shareKey"', \OC_Log::ERROR ); } } @@ -528,45 +517,42 @@ class Keymanager * @param string $dir directory * @param array $userIds user ids for which the share keys should be deleted */ - private static function recursiveDelShareKeys($dir, $userIds) - { - foreach ($userIds as $userId) { - $completePath = $dir . '/.*' . '.' . $userId . '.shareKey'; - $matches = glob(preg_quote($dir) . '/*' . preg_quote('.' . $userId . '.shareKey')); + private static function recursiveDelShareKeys( $dir, $userIds ) { + foreach ( $userIds as $userId ) { + $matches = glob( preg_quote( $dir ) . '/*' . preg_quote( '.' . $userId . '.shareKey' ) ); } /** @var $matches array */ - foreach ($matches as $ma) { - if (!unlink($ma)) { - \OC_Log::write('Encryption library', 'Could not delete shareKey; does not exist: "' . $ma . '"', \OC_Log::ERROR); + foreach ( $matches as $ma ) { + if ( !unlink( $ma ) ) { + \OC_Log::write( 'Encryption library', 'Could not delete shareKey; does not exist: "' . $ma . '"', \OC_Log::ERROR ); } } - $subdirs = $directories = glob(preg_quote($dir) . '/*', GLOB_ONLYDIR); - foreach ($subdirs as $subdir) { - self::recursiveDelShareKeys($subdir, $userIds); + $subdirs = $directories = glob( preg_quote( $dir ) . '/*', GLOB_ONLYDIR ); + foreach ( $subdirs as $subdir ) { + self::recursiveDelShareKeys( $subdir, $userIds ); } } /** * @brief Make preparations to vars and filesystem for saving a keyfile */ - public static function keySetPreparation(\OC_FilesystemView $view, $path, $basePath, $userId) - { + public static function keySetPreparation( \OC_FilesystemView $view, $path, $basePath, $userId ) { - $targetPath = ltrim($path, '/'); + $targetPath = ltrim( $path, '/' ); - $path_parts = pathinfo($targetPath); + $path_parts = pathinfo( $targetPath ); // If the file resides within a subdirectory, create it if ( - isset($path_parts['dirname']) - && !$view->file_exists($basePath . '/' . $path_parts['dirname']) + isset( $path_parts['dirname'] ) + && !$view->file_exists( $basePath . '/' . $path_parts['dirname'] ) ) { - $sub_dirs = explode(DIRECTORY_SEPARATOR, $basePath . '/' . $path_parts['dirname']); + $sub_dirs = explode( DIRECTORY_SEPARATOR, $basePath . '/' . $path_parts['dirname'] ); $dir = ''; - foreach ($sub_dirs as $sub_dir) { + foreach ( $sub_dirs as $sub_dir ) { $dir .= '/' . $sub_dir; - if (!$view->is_dir($dir)) { - $view->mkdir($dir); + if ( !$view->is_dir( $dir ) ) { + $view->mkdir( $dir ); } } } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index cc9d239b256..eaaeae9b619 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -48,13 +48,12 @@ class Proxy extends \OC_FileProxy * * Tests if server side encryption is enabled, and file is allowed by blacklists */ - private static function shouldEncrypt($path) - { + private static function shouldEncrypt( $path ) { - if (is_null(self::$enableEncryption)) { + if ( is_null( self::$enableEncryption ) ) { if ( - \OCP\Config::getAppValue('files_encryption', 'enable_encryption', 'true') == 'true' + \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' && Crypt::mode() == 'server' ) { @@ -68,27 +67,27 @@ class Proxy extends \OC_FileProxy } - if (!self::$enableEncryption) { + if ( !self::$enableEncryption ) { return false; } - if (is_null(self::$blackList)) { + if ( is_null( self::$blackList ) ) { - self::$blackList = explode(',', \OCP\Config::getAppValue('files_encryption', 'type_blacklist', '')); + self::$blackList = explode( ',', \OCP\Config::getAppValue( 'files_encryption', 'type_blacklist', '' ) ); } - if (Crypt::isCatfileContent($path)) { + if ( Crypt::isCatfileContent( $path ) ) { return true; } - $extension = substr($path, strrpos($path, '.') + 1); + $extension = substr( $path, strrpos( $path, '.' ) + 1 ); - if (array_search($extension, self::$blackList) === false) { + if ( array_search( $extension, self::$blackList ) === false ) { return true; @@ -102,35 +101,34 @@ class Proxy extends \OC_FileProxy * @param $data * @return bool */ - public function preFile_put_contents($path, &$data) - { + public function preFile_put_contents( $path, &$data ) { - if (self::shouldEncrypt($path)) { + if ( self::shouldEncrypt( $path ) ) { // Stream put contents should have been converted to fopen - if (!is_resource($data)) { + if ( !is_resource( $data ) ) { $userId = \OCP\USER::getUser(); - $view = new \OC_FilesystemView('/'); - $util = new Util($view, $userId); - $session = new Session($view); + $view = new \OC_FilesystemView( '/' ); + $util = new Util( $view, $userId ); + $session = new Session( $view ); $privateKey = $session->getPrivateKey(); - $filePath = $util->stripUserFilesPath($path); + $filePath = $util->stripUserFilesPath( $path ); // Set the filesize for userland, before encrypting - $size = strlen($data); + $size = strlen( $data ); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Check if there is an existing key we can reuse - if ($encKeyfile = Keymanager::getFileKey($view, $userId, $filePath)) { + if ( $encKeyfile = Keymanager::getFileKey( $view, $userId, $filePath ) ) { // Fetch shareKey - $shareKey = Keymanager::getShareKey($view, $userId, $filePath); + $shareKey = Keymanager::getShareKey( $view, $userId, $filePath ); // Decrypt the keyfile - $plainKey = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); + $plainKey = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey ); } else { @@ -140,37 +138,37 @@ class Proxy extends \OC_FileProxy } // Encrypt data - $encData = Crypt::symmetricEncryptFileContent($data, $plainKey); + $encData = Crypt::symmetricEncryptFileContent( $data, $plainKey ); $sharingEnabled = \OCP\Share::isEnabled(); // if file exists try to get sharing users - if ($view->file_exists($path)) { - $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $filePath, $userId); + if ( $view->file_exists( $path ) ) { + $uniqueUserIds = $util->getSharingUsersArray( $sharingEnabled, $filePath, $userId ); } else { $uniqueUserIds[] = $userId; } // Fetch public keys for all users who will share the file - $publicKeys = Keymanager::getPublicKeys($view, $uniqueUserIds); + $publicKeys = Keymanager::getPublicKeys( $view, $uniqueUserIds ); // Encrypt plain keyfile to multiple sharefiles - $multiEncrypted = Crypt::multiKeyEncrypt($plainKey, $publicKeys); + $multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys ); // Save sharekeys to user folders - Keymanager::setShareKeys($view, $filePath, $multiEncrypted['keys']); + Keymanager::setShareKeys( $view, $filePath, $multiEncrypted['keys'] ); // Set encrypted keyfile as common varname $encKey = $multiEncrypted['data']; // Save keyfile for newly encrypted file in parallel directory tree - Keymanager::setFileKey($view, $filePath, $userId, $encKey); + Keymanager::setFileKey( $view, $filePath, $userId, $encKey ); // Replace plain content with encrypted content by reference $data = $encData; // Update the file cache with file info - \OC\Files\Filesystem::putFileInfo($filePath, array('encrypted' => true, 'size' => strlen($data), 'unencrypted_size' => $size), ''); + \OC\Files\Filesystem::putFileInfo( $filePath, array( 'encrypted' => true, 'size' => strlen( $data ), 'unencrypted_size' => $size ), '' ); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; @@ -186,52 +184,51 @@ class Proxy extends \OC_FileProxy * @param string $path Path of file from which has been read * @param string $data Data that has been read from file */ - public function postFile_get_contents($path, $data) - { + public function postFile_get_contents( $path, $data ) { $userId = \OCP\USER::getUser(); - $view = new \OC_FilesystemView('/'); - $util = new Util($view, $userId); + $view = new \OC_FilesystemView( '/' ); + $util = new Util( $view, $userId ); - $relPath = $util->stripUserFilesPath($path); + $relPath = $util->stripUserFilesPath( $path ); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // init session - $session = new Session($view); + $session = new Session( $view ); // If data is a catfile if ( Crypt::mode() == 'server' - && Crypt::isCatfileContent($data) + && Crypt::isCatfileContent( $data ) ) { - $privateKey = $session->getPrivateKey($userId); + $privateKey = $session->getPrivateKey( $userId ); // Get the encrypted keyfile - $encKeyfile = Keymanager::getFileKey($view, $userId, $relPath); + $encKeyfile = Keymanager::getFileKey( $view, $userId, $relPath ); // Attempt to fetch the user's shareKey - $shareKey = Keymanager::getShareKey($view, $userId, $relPath); + $shareKey = Keymanager::getShareKey( $view, $userId, $relPath ); // Decrypt keyfile with shareKey - $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); + $plainKeyfile = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey ); - $plainData = Crypt::symmetricDecryptFileContent($data, $plainKeyfile); + $plainData = Crypt::symmetricDecryptFileContent( $data, $plainKeyfile ); } elseif ( Crypt::mode() == 'server' - && isset($_SESSION['legacyenckey']) - && Crypt::isEncryptedMeta($path) + && isset( $_SESSION['legacyenckey'] ) + && Crypt::isEncryptedMeta( $path ) ) { - $plainData = Crypt::legacyDecrypt($data, $session->getLegacyKey()); + $plainData = Crypt::legacyDecrypt( $data, $session->getLegacyKey() ); } \OC_FileProxy::$enabled = $proxyStatus; - if (!isset($plainData)) { + if ( !isset( $plainData ) ) { $plainData = $data; @@ -244,11 +241,10 @@ class Proxy extends \OC_FileProxy /** * @brief When a file is deleted, remove its keyfile also */ - public function preUnlink($path) - { + public function preUnlink( $path ) { // let the trashbin handle this - if (\OCP\App::isEnabled('files_trashbin')) { + if ( \OCP\App::isEnabled( 'files_trashbin' ) ) { return true; } @@ -256,29 +252,24 @@ class Proxy extends \OC_FileProxy $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView('/'); + $view = new \OC_FilesystemView( '/' ); $userId = \OCP\USER::getUser(); - $util = new Util($view, $userId); + $util = new Util( $view, $userId ); // Format path to be relative to user files dir - $relPath = $util->stripUserFilesPath($path); + $relPath = $util->stripUserFilesPath( $path ); - list($owner, $ownerPath) = $util->getUidAndFilename($relPath); + list( $owner, $ownerPath ) = $util->getUidAndFilename( $relPath ); // Delete keyfile & shareKey so it isn't orphaned - if ( - !( - Keymanager::deleteFileKey($view, $owner, $ownerPath) - && Keymanager::delAllShareKeys($view, $owner, $ownerPath) - ) - ) { - - \OC_Log::write('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OC_Log::ERROR); - + if ( !Keymanager::deleteFileKey( $view, $owner, $ownerPath ) ) { + \OC_Log::write( 'Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $ownerPath . '"', \OC_Log::ERROR ); } + Keymanager::delAllShareKeys( $view, $owner, $ownerPath ); + \OC_FileProxy::$enabled = $proxyStatus; // If we don't return true then file delete will fail; better @@ -291,9 +282,8 @@ class Proxy extends \OC_FileProxy * @param $path * @return bool */ - public function postTouch($path) - { - $this->handleFile($path); + public function postTouch( $path ) { + $this->handleFile( $path ); return true; } @@ -303,21 +293,20 @@ class Proxy extends \OC_FileProxy * @param $result * @return resource */ - public function postFopen($path, &$result) - { + public function postFopen( $path, &$result ) { - if (!$result) { + if ( !$result ) { return $result; } // Reformat path for use with OC_FSV - $path_split = explode('/', $path); - $path_f = implode('/', array_slice($path_split, 3)); + $path_split = explode( '/', $path ); + $path_f = implode( '/', array_slice( $path_split, 3 ) ); // FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted - if ($path_split[2] == 'cache') { + if ( count($path_split) >= 2 && $path_split[2] == 'cache' ) { return $result; } @@ -325,31 +314,31 @@ class Proxy extends \OC_FileProxy $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $meta = stream_get_meta_data($result); + $meta = stream_get_meta_data( $result ); - $view = new \OC_FilesystemView(''); + $view = new \OC_FilesystemView( '' ); - $util = new Util($view, \OCP\USER::getUser()); + $util = new Util( $view, \OCP\USER::getUser() ); // If file is already encrypted, decrypt using crypto protocol if ( Crypt::mode() == 'server' - && $util->isEncryptedPath($path) + && $util->isEncryptedPath( $path ) ) { // Close the original encrypted file - fclose($result); + fclose( $result ); // Open the file using the crypto stream wrapper // protocol and let it do the decryption work instead - $result = fopen('crypt://' . $path_f, $meta['mode']); + $result = fopen( 'crypt://' . $path_f, $meta['mode'] ); } elseif ( - self::shouldEncrypt($path) + self::shouldEncrypt( $path ) and $meta ['mode'] != 'r' and $meta['mode'] != 'rb' ) { - $result = fopen('crypt://' . $path_f, $meta['mode']); + $result = fopen( 'crypt://' . $path_f, $meta['mode'] ); } // Re-enable the proxy @@ -364,18 +353,17 @@ class Proxy extends \OC_FileProxy * @param $data * @return array */ - public function postGetFileInfo($path, $data) - { + public function postGetFileInfo( $path, $data ) { // if path is a folder do nothing - if (is_array($data) && array_key_exists('size', $data)) { + if ( is_array( $data ) && array_key_exists( 'size', $data ) ) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // get file size - $data['size'] = self::postFileSize($path, $data['size']); + $data['size'] = self::postFileSize( $path, $data['size'] ); // Re-enable the proxy \OC_FileProxy::$enabled = $proxyStatus; @@ -389,52 +377,51 @@ class Proxy extends \OC_FileProxy * @param $size * @return bool */ - public function postFileSize($path, $size) - { + public function postFileSize( $path, $size ) { - $view = new \OC_FilesystemView('/'); + $view = new \OC_FilesystemView( '/' ); // if path is a folder do nothing - if ($view->is_dir($path)) { + if ( $view->is_dir( $path ) ) { return $size; } // Reformat path for use with OC_FSV - $path_split = explode('/', $path); - $path_f = implode('/', array_slice($path_split, 3)); + $path_split = explode( '/', $path ); + $path_f = implode( '/', array_slice( $path_split, 3 ) ); // if path is empty we cannot resolve anything - if (empty($path_f)) { + if ( empty( $path_f ) ) { return $size; } $fileInfo = false; // get file info from database/cache if not .part file - if(!Keymanager::isPartialFilePath($path)) { - $fileInfo = $view->getFileInfo($path); + if ( !Keymanager::isPartialFilePath( $path ) ) { + $fileInfo = $view->getFileInfo( $path ); } // if file is encrypted return real file size - if (is_array($fileInfo) && $fileInfo['encrypted'] === true) { + if ( is_array( $fileInfo ) && $fileInfo['encrypted'] === true ) { $size = $fileInfo['unencrypted_size']; } else { // self healing if file was removed from file cache - if (!is_array($fileInfo)) { + if ( !is_array( $fileInfo ) ) { $fileInfo = array(); } $userId = \OCP\User::getUser(); - $util = new Util($view, $userId); - $fixSize = $util->getFileSize($path); - if ($fixSize > 0) { + $util = new Util( $view, $userId ); + $fixSize = $util->getFileSize( $path ); + if ( $fixSize > 0 ) { $size = $fixSize; $fileInfo['encrypted'] = true; $fileInfo['unencrypted_size'] = $size; // put file info if not .part file - if(!Keymanager::isPartialFilePath($path_f)) { - $view->putFileInfo($path, $fileInfo); + if ( !Keymanager::isPartialFilePath( $path_f ) ) { + $view->putFileInfo( $path, $fileInfo ); } } @@ -445,33 +432,32 @@ class Proxy extends \OC_FileProxy /** * @param $path */ - public function handleFile($path) - { + public function handleFile( $path ) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $view = new \OC_FilesystemView('/'); - $session = new Session($view); + $view = new \OC_FilesystemView( '/' ); + $session = new Session( $view ); $userId = \OCP\User::getUser(); - $util = new Util($view, $userId); + $util = new Util( $view, $userId ); // Reformat path for use with OC_FSV - $path_split = explode('/', $path); - $path_f = implode('/', array_slice($path_split, 3)); + $path_split = explode( '/', $path ); + $path_f = implode( '/', array_slice( $path_split, 3 ) ); // only if file is on 'files' folder fix file size and sharing - if ($path_split[2] == 'files' && $util->fixFileSize($path)) { + if ( count($path_split) >= 2 && $path_split[2] == 'files' && $util->fixFileSize( $path ) ) { // get sharing app state $sharingEnabled = \OCP\Share::isEnabled(); // get users - $usersSharing = $util->getSharingUsersArray($sharingEnabled, $path_f); + $usersSharing = $util->getSharingUsersArray( $sharingEnabled, $path_f ); // update sharing-keys - $util->setSharedFileKeyfiles($session, $usersSharing, $path_f); + $util->setSharedFileKeyfiles( $session, $usersSharing, $path_f ); } \OC_FileProxy::$enabled = $proxyStatus; diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php index 86f56e56766..2ddad0a15da 100644 --- a/apps/files_encryption/lib/session.php +++ b/apps/files_encryption/lib/session.php @@ -37,27 +37,26 @@ class Session * * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled */ - public function __construct($view) - { + public function __construct( $view ) { $this->view = $view; - if (!$this->view->is_dir('owncloud_private_key')) { + if ( !$this->view->is_dir( 'owncloud_private_key' ) ) { - $this->view->mkdir('owncloud_private_key'); + $this->view->mkdir( 'owncloud_private_key' ); } - $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); + $publicShareKeyId = \OC_Appconfig::getValue( 'files_encryption', 'publicShareKeyId' ); - if ($publicShareKeyId === null) { - $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); - \OC_Appconfig::setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId); + if ( $publicShareKeyId === null ) { + $publicShareKeyId = 'pubShare_' . substr( md5( time() ), 0, 8 ); + \OC_Appconfig::setValue( 'files_encryption', 'publicShareKeyId', $publicShareKeyId ); } if ( - !$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") - || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key") + !$this->view->file_exists( "/public-keys/" . $publicShareKeyId . ".public.key" ) + || !$this->view->file_exists( "/owncloud_private_key/" . $publicShareKeyId . ".private.key" ) ) { $keypair = Crypt::createKeypair(); @@ -68,32 +67,33 @@ class Session // Save public key - if (!$view->is_dir('/public-keys')) { - $view->mkdir('/public-keys'); + if ( !$view->is_dir( '/public-keys' ) ) { + $view->mkdir( '/public-keys' ); } - $this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']); + $this->view->file_put_contents( '/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey'] ); - // Encrypt private key empthy passphrase - $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], ''); + // Encrypt private key empty passphrase + $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], '' ); // Save private key - $this->view->file_put_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key', $encryptedPrivateKey); + $this->view->file_put_contents( '/owncloud_private_key/' . $publicShareKeyId . '.private.key', $encryptedPrivateKey ); \OC_FileProxy::$enabled = $proxyStatus; } - if (\OCP\USER::getUser() === false || - (isset($_GET['service']) && $_GET['service'] == 'files' && - isset($_GET['t']))) { + if ( \OCP\USER::getUser() === false || + ( isset( $_GET['service'] ) && $_GET['service'] == 'files' && + isset( $_GET['t'] ) ) + ) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key'); - $privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, ''); - $this->setPrivateKey($privateKey); + $encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/' . $publicShareKeyId . '.private.key' ); + $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, '' ); + $this->setPrivateKey( $privateKey ); \OC_FileProxy::$enabled = $proxyStatus; } @@ -104,8 +104,7 @@ class Session * @param string $privateKey * @return bool */ - public function setPrivateKey($privateKey) - { + public function setPrivateKey( $privateKey ) { $_SESSION['privateKey'] = $privateKey; @@ -118,12 +117,11 @@ class Session * @returns string $privateKey The user's plaintext private key * */ - public function getPrivateKey() - { + public function getPrivateKey() { if ( - isset($_SESSION['privateKey']) - && !empty($_SESSION['privateKey']) + isset( $_SESSION['privateKey'] ) + && !empty( $_SESSION['privateKey'] ) ) { return $_SESSION['privateKey']; @@ -141,8 +139,7 @@ class Session * @param $legacyKey * @return bool */ - public function setLegacyKey($legacyKey) - { + public function setLegacyKey( $legacyKey ) { $_SESSION['legacyKey'] = $legacyKey; @@ -154,12 +151,11 @@ class Session * @returns string $legacyKey The user's plaintext legacy key * */ - public function getLegacyKey() - { + public function getLegacyKey() { if ( - isset($_SESSION['legacyKey']) - && !empty($_SESSION['legacyKey']) + isset( $_SESSION['legacyKey'] ) + && !empty( $_SESSION['legacyKey'] ) ) { return $_SESSION['legacyKey']; diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php index b143b62827f..fa9df02f085 100644 --- a/apps/files_encryption/lib/stream.php +++ b/apps/files_encryption/lib/stream.php @@ -77,19 +77,18 @@ class Stream * @param $opened_path * @return bool */ - public function stream_open($path, $mode, $options, &$opened_path) - { + public function stream_open( $path, $mode, $options, &$opened_path ) { - if (!isset($this->rootView)) { - $this->rootView = new \OC_FilesystemView('/'); + if ( !isset( $this->rootView ) ) { + $this->rootView = new \OC_FilesystemView( '/' ); } - $util = new Util($this->rootView, \OCP\USER::getUser()); + $util = new Util( $this->rootView, \OCP\USER::getUser() ); $this->userId = $util->getUserId(); // Strip identifier text from path, this gives us the path relative to data//files - $this->relPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path)); + $this->relPath = \OC\Files\Filesystem::normalizePath( str_replace( 'crypt://', '', $path ) ); // rawPath is relative to the data directory $this->rawPath = $util->getUserFilesDir() . $this->relPath; @@ -111,26 +110,25 @@ class Stream } else { - $this->size = $this->rootView->filesize($this->rawPath, $mode); + $this->size = $this->rootView->filesize( $this->rawPath, $mode ); } - $this->handle = $this->rootView->fopen($this->rawPath, $mode); + $this->handle = $this->rootView->fopen( $this->rawPath, $mode ); \OC_FileProxy::$enabled = $proxyStatus; - if (!is_resource($this->handle)) { + if ( !is_resource( $this->handle ) ) { - \OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR); + \OCP\Util::writeLog( 'files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR ); } else { - $this->meta = stream_get_meta_data($this->handle); + $this->meta = stream_get_meta_data( $this->handle ); } - - return is_resource($this->handle); + return is_resource( $this->handle ); } @@ -138,12 +136,11 @@ class Stream * @param $offset * @param int $whence */ - public function stream_seek($offset, $whence = SEEK_SET) - { + public function stream_seek( $offset, $whence = SEEK_SET ) { $this->flush(); - fseek($this->handle, $offset, $whence); + fseek( $this->handle, $offset, $whence ); } @@ -152,37 +149,36 @@ class Stream * @return bool|string * @throws \Exception */ - public function stream_read($count) - { + public function stream_read( $count ) { $this->writeCache = ''; - if ($count != 8192) { + if ( $count != 8192 ) { // $count will always be 8192 https://bugs.php.net/bug.php?id=21641 // This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed' - \OCP\Util::writeLog('files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL); + \OCP\Util::writeLog( 'files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL ); die(); } // Get the data from the file handle - $data = fread($this->handle, 8192); + $data = fread( $this->handle, 8192 ); $result = ''; - if (strlen($data)) { + if ( strlen( $data ) ) { - if (!$this->getKey()) { + if ( !$this->getKey() ) { // Error! We don't have a key to decrypt the file with - throw new \Exception('Encryption key not found for "' . $this->rawPath . '" during attempted read via stream'); + throw new \Exception( 'Encryption key not found for "' . $this->rawPath . '" during attempted read via stream' ); } // Decrypt data - $result = Crypt::symmetricDecryptFileContent($data, $this->plainKey); + $result = Crypt::symmetricDecryptFileContent( $data, $this->plainKey ); } @@ -196,11 +192,10 @@ class Stream * @param string $key key to use for encryption * @return string encrypted data on success, false on failure */ - public function preWriteEncrypt($plainData, $key) - { + public function preWriteEncrypt( $plainData, $key ) { // Encrypt data to 'catfile', which includes IV - if ($encrypted = Crypt::symmetricEncryptFileContent($plainData, $key)) { + if ( $encrypted = Crypt::symmetricEncryptFileContent( $plainData, $key ) ) { return $encrypted; @@ -217,11 +212,10 @@ class Stream * @internal param bool $generate if true, a new key will be generated if none can be found * @return bool true on key found and set, false on key not found and new key generated and set */ - public function getKey() - { + public function getKey() { // Check if key is already set - if (isset($this->plainKey) && isset($this->encKeyfile)) { + if ( isset( $this->plainKey ) && isset( $this->encKeyfile ) ) { return true; @@ -229,18 +223,18 @@ class Stream // Fetch and decrypt keyfile // Fetch existing keyfile - $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath); + $this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->relPath ); // If a keyfile already exists - if ($this->encKeyfile) { + if ( $this->encKeyfile ) { - $session = new Session($this->rootView); + $session = new Session( $this->rootView ); - $privateKey = $session->getPrivateKey($this->userId); + $privateKey = $session->getPrivateKey( $this->userId ); - $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath); + $shareKey = Keymanager::getShareKey( $this->rootView, $this->userId, $this->relPath ); - $this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $privateKey); + $this->plainKey = Crypt::multiKeyDecrypt( $this->encKeyfile, $shareKey, $privateKey ); return true; @@ -261,8 +255,7 @@ class Stream * @note Padding is added to each encrypted block to ensure that the resulting block is exactly 8192 bytes. This is removed during stream_read * @note PHP automatically updates the file pointer after writing data to reflect it's length. There is generally no need to update the poitner manually using fseek */ - public function stream_write($data) - { + public function stream_write( $data ) { // Disable the file proxies so that encryption is not // automatically attempted when the file is written to disk - @@ -272,16 +265,16 @@ class Stream \OC_FileProxy::$enabled = false; // Get the length of the unencrypted data that we are handling - $length = strlen($data); + $length = strlen( $data ); // Find out where we are up to in the writing of data to the // file - $pointer = ftell($this->handle); + $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 // one), save the newly generated keyfile - if (!$this->getKey()) { + if ( !$this->getKey() ) { $this->plainKey = Crypt::generateKey(); @@ -289,27 +282,27 @@ class Stream // If extra data is left over from the last round, make sure it // is integrated into the next 6126 / 8192 block - if ($this->writeCache) { + if ( $this->writeCache ) { // Concat writeCache to start of $data $data = $this->writeCache . $data; - // Clear the write cache, ready for resuse - it has been + // Clear the write cache, ready for reuse - it has been // flushed and its old contents processed $this->writeCache = ''; } - // While there still remains somed data to be processed & written - while (strlen($data) > 0) { + // While there still remains some data to be processed & written + while ( strlen( $data ) > 0 ) { - // Remaining length for this iteration, not of the + // Remaining length for this iteration, not of the // entire file (may be greater than 8192 bytes) - $remainingLength = strlen($data); + $remainingLength = strlen( $data ); - // If data remaining to be written is less than the + // If data remaining to be written is less than the // size of 1 6126 byte block - if ($remainingLength < 6126) { + if ( $remainingLength < 6126 ) { // Set writeCache to contents of $data // The writeCache will be carried over to the @@ -327,25 +320,25 @@ class Stream } else { // Read the chunk from the start of $data - $chunk = substr($data, 0, 6126); + $chunk = substr( $data, 0, 6126 ); - $encrypted = $this->preWriteEncrypt($chunk, $this->plainKey); + $encrypted = $this->preWriteEncrypt( $chunk, $this->plainKey ); // 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); + fwrite( $this->handle, $encrypted ); // Remove the chunk we just processed from // $data, leaving only unprocessed data in $data // var, for handling on the next round - $data = substr($data, 6126); + $data = substr( $data, 6126 ); } } - $this->size = max($this->size, $pointer + $length); + $this->size = max( $this->size, $pointer + $length ); $this->unencryptedSize += $length; \OC_FileProxy::$enabled = $proxyStatus; @@ -360,18 +353,17 @@ class Stream * @param $arg1 * @param $arg2 */ - public function stream_set_option($option, $arg1, $arg2) - { + public function stream_set_option( $option, $arg1, $arg2 ) { $return = false; - switch ($option) { + switch ( $option ) { case STREAM_OPTION_BLOCKING: - $return = stream_set_blocking($this->handle, $arg1); + $return = stream_set_blocking( $this->handle, $arg1 ); break; case STREAM_OPTION_READ_TIMEOUT: - $return = stream_set_timeout($this->handle, $arg1, $arg2); + $return = stream_set_timeout( $this->handle, $arg1, $arg2 ); break; case STREAM_OPTION_WRITE_BUFFER: - $return = stream_set_write_buffer($this->handle, $arg1); + $return = stream_set_write_buffer( $this->handle, $arg1 ); } return $return; @@ -380,26 +372,23 @@ class Stream /** * @return array */ - public function stream_stat() - { - return fstat($this->handle); + public function stream_stat() { + return fstat( $this->handle ); } /** * @param $mode */ - public function stream_lock($mode) - { - return flock($this->handle, $mode); + public function stream_lock( $mode ) { + return flock( $this->handle, $mode ); } /** * @return bool */ - public function stream_flush() - { + public function stream_flush() { - return fflush($this->handle); + return fflush( $this->handle ); // Not a typo: http://php.net/manual/en/function.fflush.php } @@ -407,22 +396,20 @@ class Stream /** * @return bool */ - public function stream_eof() - { - return feof($this->handle); + public function stream_eof() { + return feof( $this->handle ); } - private function flush() - { + private function flush() { - if ($this->writeCache) { + if ( $this->writeCache ) { // Set keyfile property for file in question $this->getKey(); - $encrypted = $this->preWriteEncrypt($this->writeCache, $this->plainKey); + $encrypted = $this->preWriteEncrypt( $this->writeCache, $this->plainKey ); - fwrite($this->handle, $encrypted); + fwrite( $this->handle, $encrypted ); $this->writeCache = ''; @@ -433,8 +420,7 @@ class Stream /** * @return bool */ - public function stream_close() - { + public function stream_close() { $this->flush(); @@ -448,33 +434,33 @@ class Stream \OC_FileProxy::$enabled = false; // Fetch user's public key - $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->userId); + $this->publicKey = Keymanager::getPublicKey( $this->rootView, $this->userId ); // Check if OC sharing api is enabled $sharingEnabled = \OCP\Share::isEnabled(); - $util = new Util($this->rootView, $this->userId); + $util = new Util( $this->rootView, $this->userId ); // Get all users sharing the file includes current user - $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId); + $uniqueUserIds = $util->getSharingUsersArray( $sharingEnabled, $this->relPath, $this->userId ); // Fetch public keys for all sharing users - $publicKeys = Keymanager::getPublicKeys($this->rootView, $uniqueUserIds); + $publicKeys = Keymanager::getPublicKeys( $this->rootView, $uniqueUserIds ); // Encrypt enc key for all sharing users - $this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys); + $this->encKeyfiles = Crypt::multiKeyEncrypt( $this->plainKey, $publicKeys ); - $view = new \OC_FilesystemView('/'); + $view = new \OC_FilesystemView( '/' ); // Save the new encrypted file key - Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']); + Keymanager::setFileKey( $this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data'] ); // Save the sharekeys - Keymanager::setShareKeys($view, $this->relPath, $this->encKeyfiles['keys']); + Keymanager::setShareKeys( $view, $this->relPath, $this->encKeyfiles['keys'] ); // get file info - $fileInfo = $view->getFileInfo($this->rawPath); - if (!is_array($fileInfo)) { + $fileInfo = $view->getFileInfo( $this->rawPath ); + if ( !is_array( $fileInfo ) ) { $fileInfo = array(); } @@ -487,10 +473,10 @@ class Stream $fileInfo['unencrypted_size'] = $this->unencryptedSize; // set fileinfo - $view->putFileInfo($this->rawPath, $fileInfo); + $view->putFileInfo( $this->rawPath, $fileInfo ); } - return fclose($this->handle); + return fclose( $this->handle ); } diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index d42fe9953b5..2980aa94e0c 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -117,25 +117,25 @@ class Util * @param $userId * @param bool $client */ - public function __construct(\OC_FilesystemView $view, $userId, $client = false) - { + public function __construct( \OC_FilesystemView $view, $userId, $client = false ) { $this->view = $view; $this->userId = $userId; $this->client = $client; $this->isPublic = false; - $this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId'); - $this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $this->publicShareKeyId = \OC_Appconfig::getValue( 'files_encryption', 'publicShareKeyId' ); + $this->recoveryKeyId = \OC_Appconfig::getValue( 'files_encryption', 'recoveryKeyId' ); // if we are anonymous/public - if ($this->userId === false || - (isset($_GET['service']) && $_GET['service'] == 'files' && - isset($_GET['t']))) { + if ( $this->userId === false || + ( isset( $_GET['service'] ) && $_GET['service'] == 'files' && + isset( $_GET['t'] ) ) + ) { $this->userId = $this->publicShareKeyId; // only handle for files_sharing app - if ($GLOBALS['app'] === 'files_sharing') { + if ( $GLOBALS['app'] === 'files_sharing' ) { $this->userDir = '/' . $GLOBALS['fileOwner']; $this->fileFolderName = 'files'; $this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable? @@ -164,15 +164,14 @@ class Util /** * @return bool */ - public function ready() - { + public function ready() { if ( - !$this->view->file_exists($this->encryptionDir) - or !$this->view->file_exists($this->keyfilesPath) - or !$this->view->file_exists($this->shareKeysPath) - or !$this->view->file_exists($this->publicKeyPath) - or !$this->view->file_exists($this->privateKeyPath) + !$this->view->file_exists( $this->encryptionDir ) + or !$this->view->file_exists( $this->keyfilesPath ) + or !$this->view->file_exists( $this->shareKeysPath ) + or !$this->view->file_exists( $this->publicKeyPath ) + or !$this->view->file_exists( $this->privateKeyPath ) ) { return false; @@ -189,8 +188,7 @@ class Util * @brief Sets up user folders and keys for serverside encryption * @param string $passphrase passphrase to encrypt server-stored private key with */ - public function setupServerSide($passphrase = null) - { + public function setupServerSide( $passphrase = null ) { // Set directories to check / create $setUpDirs = array( @@ -203,11 +201,11 @@ class Util ); // Check / create all necessary dirs - foreach ($setUpDirs as $dirPath) { + foreach ( $setUpDirs as $dirPath ) { - if (!$this->view->file_exists($dirPath)) { + if ( !$this->view->file_exists( $dirPath ) ) { - $this->view->mkdir($dirPath); + $this->view->mkdir( $dirPath ); } @@ -216,8 +214,8 @@ class Util // Create user keypair // we should never override a keyfile if ( - !$this->view->file_exists($this->publicKeyPath) - && !$this->view->file_exists($this->privateKeyPath) + !$this->view->file_exists( $this->publicKeyPath ) + && !$this->view->file_exists( $this->privateKeyPath ) ) { // Generate keypair @@ -226,35 +224,35 @@ class Util \OC_FileProxy::$enabled = false; // Save public key - $this->view->file_put_contents($this->publicKeyPath, $keypair['publicKey']); + $this->view->file_put_contents( $this->publicKeyPath, $keypair['publicKey'] ); // Encrypt private key with user pwd as passphrase - $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], $passphrase); + $encryptedPrivateKey = Crypt::symmetricEncryptFileContent( $keypair['privateKey'], $passphrase ); // Save private key - $this->view->file_put_contents($this->privateKeyPath, $encryptedPrivateKey); + $this->view->file_put_contents( $this->privateKeyPath, $encryptedPrivateKey ); \OC_FileProxy::$enabled = true; } else { // check if public-key exists but private-key is missing - if($this->view->file_exists($this->publicKeyPath) && !$this->view->file_exists($this->privateKeyPath)) { - \OC_Log::write('Encryption library', 'public key exists but private key is missing for "' . $this->userId . '"', \OC_Log::FATAL); + if ( $this->view->file_exists( $this->publicKeyPath ) && !$this->view->file_exists( $this->privateKeyPath ) ) { + \OC_Log::write( 'Encryption library', 'public key exists but private key is missing for "' . $this->userId . '"', \OC_Log::FATAL ); return false; - } else if(!$this->view->file_exists($this->publicKeyPath) && $this->view->file_exists($this->privateKeyPath)) { - \OC_Log::write('Encryption library', 'private key exists but public key is missing for "' . $this->userId . '"', \OC_Log::FATAL); + } else if ( !$this->view->file_exists( $this->publicKeyPath ) && $this->view->file_exists( $this->privateKeyPath ) ) { + \OC_Log::write( 'Encryption library', 'private key exists but public key is missing for "' . $this->userId . '"', \OC_Log::FATAL ); return false; } } // If there's no record for this user's encryption preferences - if (false === $this->recoveryEnabledForUser()) { + if ( false === $this->recoveryEnabledForUser() ) { // create database configuration $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)'; - $args = array($this->userId, 'server-side', 0); - $query = \OCP\DB::prepare($sql); - $query->execute($args); + $args = array( $this->userId, 'server-side', 0 ); + $query = \OCP\DB::prepare( $sql ); + $query->execute( $args ); } @@ -265,8 +263,7 @@ class Util /** * @return string */ - public function getPublicShareKeyId() - { + public function getPublicShareKeyId() { return $this->publicShareKeyId; } @@ -277,8 +274,7 @@ class Util * @note If records are not being returned, check for a hidden space * at the start of the uid in db */ - public function recoveryEnabledForUser() - { + public function recoveryEnabledForUser() { $sql = 'SELECT recovery_enabled @@ -287,22 +283,22 @@ class Util WHERE uid = ?'; - $args = array($this->userId); + $args = array( $this->userId ); - $query = \OCP\DB::prepare($sql); + $query = \OCP\DB::prepare( $sql ); - $result = $query->execute($args); + $result = $query->execute( $args ); $recoveryEnabled = array(); - while ($row = $result->fetchRow()) { + while ( $row = $result->fetchRow() ) { $recoveryEnabled[] = $row['recovery_enabled']; } // If no record is found - if (empty($recoveryEnabled)) { + if ( empty( $recoveryEnabled ) ) { return false; @@ -320,19 +316,18 @@ class Util * @param bool $enabled Whether to enable or disable recovery * @return bool */ - public function setRecoveryForUser($enabled) - { + public function setRecoveryForUser( $enabled ) { $recoveryStatus = $this->recoveryEnabledForUser(); // If a record for this user already exists, update it - if (false === $recoveryStatus) { + if ( false === $recoveryStatus ) { $sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)'; - $args = array($this->userId, 'server-side', $enabled); + $args = array( $this->userId, 'server-side', $enabled ); // Create a new record instead } else { @@ -344,13 +339,13 @@ class Util WHERE uid = ?'; - $args = array($enabled, $this->userId); + $args = array( $enabled, $this->userId ); } - $query = \OCP\DB::prepare($sql); + $query = \OCP\DB::prepare( $sql ); - if ($query->execute($args)) { + if ( $query->execute( $args ) ) { return true; @@ -369,47 +364,46 @@ class Util * @note $directory needs to be a path relative to OC data dir. e.g. * /admin/files NOT /backup OR /home/www/oc/data/admin/files */ - public function findEncFiles($directory, &$found = false) - { + public function findEncFiles( $directory, &$found = false ) { // Disable proxy - we don't want files to be decrypted before // we handle them \OC_FileProxy::$enabled = false; - if($found == false) { - $found = array('plain' => array(), 'encrypted' => array(), 'legacy' => array()); + if ( $found == false ) { + $found = array( 'plain' => array(), 'encrypted' => array(), 'legacy' => array() ); } if ( - $this->view->is_dir($directory) - && $handle = $this->view->opendir($directory) + $this->view->is_dir( $directory ) + && $handle = $this->view->opendir( $directory ) ) { - while (false !== ($file = readdir($handle))) { + while ( false !== ( $file = readdir( $handle ) ) ) { if ( $file != "." && $file != ".." ) { - $filePath = $directory . '/' . $this->view->getRelativePath('/' . $file); - $relPath = $this->stripUserFilesPath($filePath); + $filePath = $directory . '/' . $this->view->getRelativePath( '/' . $file ); + $relPath = $this->stripUserFilesPath( $filePath ); // If the path is a directory, search // its contents - if ($this->view->is_dir($filePath)) { + if ( $this->view->is_dir( $filePath ) ) { - $this->findEncFiles($filePath, $found); + $this->findEncFiles( $filePath, $found ); // If the path is a file, determine // its encryption status - } elseif ($this->view->is_file($filePath)) { + } elseif ( $this->view->is_file( $filePath ) ) { // Disable proxies again, some- // where they got re-enabled :/ \OC_FileProxy::$enabled = false; - $data = $this->view->file_get_contents($filePath); + $data = $this->view->file_get_contents( $filePath ); // If the file is encrypted // NOTE: If the userId is @@ -419,22 +413,22 @@ class Util // scanning every file like this // will eat server resources :( if ( - Keymanager::getFileKey($this->view, $this->userId, $relPath) - && Crypt::isCatfileContent($data) + Keymanager::getFileKey( $this->view, $this->userId, $relPath ) + && Crypt::isCatfileContent( $data ) ) { - $found['encrypted'][] = array('name' => $file, 'path' => $filePath); + $found['encrypted'][] = array( 'name' => $file, 'path' => $filePath ); // If the file uses old // encryption system - } elseif (Crypt::isLegacyEncryptedContent($this->tail($filePath, 3), $relPath)) { + } elseif ( Crypt::isLegacyEncryptedContent( $this->tail( $filePath, 3 ), $relPath ) ) { - $found['legacy'][] = array('name' => $file, 'path' => $filePath); + $found['legacy'][] = array( 'name' => $file, 'path' => $filePath ); // If the file is not encrypted } else { - $found['plain'][] = array('name' => $file, 'path' => $relPath); + $found['plain'][] = array( 'name' => $file, 'path' => $relPath ); } @@ -446,7 +440,7 @@ class Util \OC_FileProxy::$enabled = true; - if (empty($found)) { + if ( empty( $found ) ) { return false; @@ -469,39 +463,38 @@ class Util * @note Safe to use on large files; does not read entire file to memory * @note Derivative of http://tekkie.flashbit.net/php/tail-functionality-in-php */ - public function tail($filename, $numLines) - { + public function tail( $filename, $numLines ) { \OC_FileProxy::$enabled = false; $text = ''; $pos = -1; - $handle = $this->view->fopen($filename, 'r'); + $handle = $this->view->fopen( $filename, 'r' ); - while ($numLines > 0) { + while ( $numLines > 0 ) { --$pos; - if (fseek($handle, $pos, SEEK_END) !== 0) { + if ( fseek( $handle, $pos, SEEK_END ) !== 0 ) { - rewind($handle); + rewind( $handle ); $numLines = 0; - } elseif (fgetc($handle) === "\n") { + } elseif ( fgetc( $handle ) === "\n" ) { --$numLines; } - $block_size = (-$pos) % 8192; - if ($block_size === 0 || $numLines === 0) { + $block_size = ( -$pos ) % 8192; + if ( $block_size === 0 || $numLines === 0 ) { - $text = fread($handle, ($block_size === 0 ? 8192 : $block_size)) . $text; + $text = fread( $handle, ( $block_size === 0 ? 8192 : $block_size ) ) . $text; } } - fclose($handle); + fclose( $handle ); \OC_FileProxy::$enabled = true; @@ -513,8 +506,7 @@ class Util * @param $path * @return boolean */ - public function isEncryptedPath($path) - { + public function isEncryptedPath( $path ) { // Disable encryption proxy so data retrieved is in its // original form @@ -523,15 +515,15 @@ class Util // we only need 24 byte from the last chunk $data = ''; - $handle = $this->view->fopen($path, 'r'); - if (!fseek($handle, -24, SEEK_END)) { - $data = fgets($handle); + $handle = $this->view->fopen( $path, 'r' ); + if ( !fseek( $handle, -24, SEEK_END ) ) { + $data = fgets( $handle ); } // re-enable proxy \OC_FileProxy::$enabled = $proxyStatus; - return Crypt::isCatfileContent($data); + return Crypt::isCatfileContent( $data ); } @@ -540,8 +532,7 @@ class Util * @param string $path absolute path * @return bool */ - public function getFileSize($path) - { + public function getFileSize( $path ) { $result = 0; @@ -550,33 +541,33 @@ class Util \OC_FileProxy::$enabled = false; // Reformat path for use with OC_FSV - $pathSplit = explode('/', $path); - $pathRelative = implode('/', array_slice($pathSplit, 3)); + $pathSplit = explode( '/', $path ); + $pathRelative = implode( '/', array_slice( $pathSplit, 3 ) ); - if ($pathSplit[2] == 'files' && $this->view->file_exists($path) && $this->isEncryptedPath($path)) { + if ( $pathSplit[2] == 'files' && $this->view->file_exists( $path ) && $this->isEncryptedPath( $path ) ) { // get the size from filesystem - $fullPath = $this->view->getLocalFile($path); - $size = filesize($fullPath); + $fullPath = $this->view->getLocalFile( $path ); + $size = filesize( $fullPath ); // calculate last chunk nr - $lastChunckNr = floor($size / 8192); + $lastChunkNr = floor( $size / 8192 ); // open stream - $stream = fopen('crypt://' . $pathRelative, "r"); + $stream = fopen( 'crypt://' . $pathRelative, "r" ); - if (is_resource($stream)) { + if ( is_resource( $stream ) ) { // calculate last chunk position - $lastChunckPos = ($lastChunckNr * 8192); + $lastChunckPos = ( $lastChunkNr * 8192 ); // seek to end - fseek($stream, $lastChunckPos); + fseek( $stream, $lastChunckPos ); // get the content of the last chunk - $lastChunkContent = fread($stream, 8192); + $lastChunkContent = fread( $stream, 8192 ); // calc the real file size with the size of the last chunk - $realSize = (($lastChunckNr * 6126) + strlen($lastChunkContent)); + $realSize = ( ( $lastChunkNr * 6126 ) + strlen( $lastChunkContent ) ); // store file size $result = $realSize; @@ -593,8 +584,7 @@ class Util * @param $path absolute path * @return true / false if file is encrypted */ - public function fixFileSize($path) - { + public function fixFileSize( $path ) { $result = false; @@ -602,18 +592,18 @@ class Util $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $realSize = $this->getFileSize($path); + $realSize = $this->getFileSize( $path ); - if ($realSize > 0) { + if ( $realSize > 0 ) { - $cached = $this->view->getFileInfo($path); + $cached = $this->view->getFileInfo( $path ); $cached['encrypted'] = true; // set the size $cached['unencrypted_size'] = $realSize; // put file info - $this->view->putFileInfo($path, $cached); + $this->view->putFileInfo( $path, $cached ); $result = true; @@ -628,13 +618,12 @@ class Util * @brief Format a path to be relative to the /user/files/ directory * @note e.g. turns '/admin/files/test.txt' into 'test.txt' */ - public function stripUserFilesPath($path) - { + public function stripUserFilesPath( $path ) { - $trimmed = ltrim($path, '/'); - $split = explode('/', $trimmed); - $sliced = array_slice($split, 2); - $relPath = implode('/', $sliced); + $trimmed = ltrim( $path, '/' ); + $split = explode( '/', $trimmed ); + $sliced = array_slice( $split, 2 ); + $relPath = implode( '/', $sliced ); return $relPath; @@ -644,13 +633,12 @@ class Util * @param $path * @return bool */ - public function isSharedPath($path) - { + public function isSharedPath( $path ) { - $trimmed = ltrim($path, '/'); - $split = explode('/', $trimmed); + $trimmed = ltrim( $path, '/' ); + $split = explode( '/', $trimmed ); - if ($split[2] == "Shared") { + if ( $split[2] == "Shared" ) { return true; @@ -670,16 +658,15 @@ class Util * @return bool * @note Encryption is recursive */ - public function encryptAll($dirPath, $legacyPassphrase = null, $newPassphrase = null) - { + public function encryptAll( $dirPath, $legacyPassphrase = null, $newPassphrase = null ) { - if ($found = $this->findEncFiles($dirPath)) { + if ( $found = $this->findEncFiles( $dirPath ) ) { // Disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; // Encrypt unencrypted files - foreach ($found['plain'] as $plainFile) { + foreach ( $found['plain'] as $plainFile ) { //relative to data//file $relPath = $plainFile['path']; @@ -688,80 +675,80 @@ class Util $rawPath = $this->userId . '/files/' . $plainFile['path']; // Open plain file handle for binary reading - $plainHandle1 = $this->view->fopen($rawPath, 'rb'); + $plainHandle1 = $this->view->fopen( $rawPath, 'rb' ); // 2nd handle for moving plain file - view->rename() doesn't work, this is a workaround - $plainHandle2 = $this->view->fopen($rawPath . '.plaintmp', 'wb'); + $plainHandle2 = $this->view->fopen( $rawPath . '.plaintmp', 'wb' ); // Move plain file to a temporary location - stream_copy_to_stream($plainHandle1, $plainHandle2); + stream_copy_to_stream( $plainHandle1, $plainHandle2 ); // Close access to original file // $this->view->fclose( $plainHandle1 ); // not implemented in view{} // Delete original plain file so we can rename enc file later - $this->view->unlink($rawPath); + $this->view->unlink( $rawPath ); // Open enc file handle for binary writing, with same filename as original plain file - $encHandle = fopen('crypt://' . $relPath, 'wb'); + $encHandle = fopen( 'crypt://' . $relPath, 'wb' ); // Save data from plain stream to new encrypted file via enc stream // NOTE: Stream{} will be invoked for handling // the encryption, and should handle all keys // and their generation etc. automatically - stream_copy_to_stream($plainHandle2, $encHandle); + stream_copy_to_stream( $plainHandle2, $encHandle ); // get file size - $size = $this->view->filesize($rawPath . '.plaintmp'); + $size = $this->view->filesize( $rawPath . '.plaintmp' ); // Delete temporary plain copy of file - $this->view->unlink($rawPath . '.plaintmp'); + $this->view->unlink( $rawPath . '.plaintmp' ); // Add the file to the cache - \OC\Files\Filesystem::putFileInfo($plainFile['path'], array('encrypted' => true, 'size' => $size, 'unencrypted_size' => $size)); + \OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted' => true, 'size' => $size, 'unencrypted_size' => $size ) ); } // Encrypt legacy encrypted files if ( - !empty($legacyPassphrase) - && !empty($newPassphrase) + !empty( $legacyPassphrase ) + && !empty( $newPassphrase ) ) { - foreach ($found['legacy'] as $legacyFile) { + foreach ( $found['legacy'] as $legacyFile ) { // Fetch data from file - $legacyData = $this->view->file_get_contents($legacyFile['path']); + $legacyData = $this->view->file_get_contents( $legacyFile['path'] ); $sharingEnabled = \OCP\Share::isEnabled(); // if file exists try to get sharing users - if ($this->view->file_exists($legacyFile['path'])) { - $uniqueUserIds = $this->getSharingUsersArray($sharingEnabled, $legacyFile['path'], $this->userId); + if ( $this->view->file_exists( $legacyFile['path'] ) ) { + $uniqueUserIds = $this->getSharingUsersArray( $sharingEnabled, $legacyFile['path'], $this->userId ); } else { $uniqueUserIds[] = $this->userId; } // Fetch public keys for all users who will share the file - $publicKeys = Keymanager::getPublicKeys($this->view, $uniqueUserIds); + $publicKeys = Keymanager::getPublicKeys( $this->view, $uniqueUserIds ); // Recrypt data, generate catfile - $recrypted = Crypt::legacyKeyRecryptKeyfile($legacyData, $legacyPassphrase, $publicKeys, $newPassphrase, $legacyFile['path']); + $recrypted = Crypt::legacyKeyRecryptKeyfile( $legacyData, $legacyPassphrase, $publicKeys, $newPassphrase, $legacyFile['path'] ); $rawPath = $legacyFile['path']; - $relPath = $this->stripUserFilesPath($rawPath); + $relPath = $this->stripUserFilesPath( $rawPath ); // Save keyfile - Keymanager::setFileKey($this->view, $relPath, $this->userId, $recrypted['filekey']); + Keymanager::setFileKey( $this->view, $relPath, $this->userId, $recrypted['filekey'] ); // Save sharekeys to user folders - Keymanager::setShareKeys($this->view, $relPath, $recrypted['sharekeys']); + Keymanager::setShareKeys( $this->view, $relPath, $recrypted['sharekeys'] ); // Overwrite the existing file with the encrypted one - $this->view->file_put_contents($rawPath, $recrypted['data']); + $this->view->file_put_contents( $rawPath, $recrypted['data'] ); - $size = strlen($recrypted['data']); + $size = strlen( $recrypted['data'] ); // Add the file to the cache - \OC\Files\Filesystem::putFileInfo($rawPath, array('encrypted' => true, 'size' => $size), ''); + \OC\Files\Filesystem::putFileInfo( $rawPath, array( 'encrypted' => true, 'size' => $size ), '' ); } } @@ -781,10 +768,9 @@ class Util * @param string $pathName Name of the directory to return the path of * @return string path */ - public function getPath($pathName) - { + public function getPath( $pathName ) { - switch ($pathName) { + switch ( $pathName ) { case 'publicKeyDir': @@ -815,9 +801,10 @@ class Util return $this->privateKeyPath; break; - } + return false; + } /** @@ -825,18 +812,17 @@ class Util * @param int $fileId id of the file * @return string path of the file */ - public static function fileIdToPath($fileId) - { + public static function fileIdToPath( $fileId ) { - $query = \OC_DB::prepare('SELECT `path`' + $query = \OC_DB::prepare( 'SELECT `path`' . ' FROM `*PREFIX*filecache`' - . ' WHERE `fileid` = ?'); + . ' WHERE `fileid` = ?' ); - $result = $query->execute(array($fileId)); + $result = $query->execute( array( $fileId ) ); $row = $result->fetchRow(); - return substr($row['path'], 5); + return substr( $row['path'], 5 ); } @@ -845,16 +831,15 @@ class Util * @param array $unfilteredUsers users to be checked for sharing readiness * @return multi-dimensional array. keys: ready, unready */ - public function filterShareReadyUsers($unfilteredUsers) - { + public function filterShareReadyUsers( $unfilteredUsers ) { // This array will collect the filtered IDs $readyIds = $unreadyIds = array(); // Loop through users and create array of UIDs that need new keyfiles - foreach ($unfilteredUsers as $user) { + foreach ( $unfilteredUsers as $user ) { - $util = new Util($this->view, $user); + $util = new Util( $this->view, $user ); // Check that the user is encryption capable, or is the // public system user 'ownCloud' (for public shares) @@ -874,15 +859,15 @@ class Util // Log warning; we can't do necessary setup here // because we don't have the user passphrase - \OC_Log::write('Encryption library', '"' . $user . '" is not setup for encryption', \OC_Log::WARN); + \OC_Log::write( 'Encryption library', '"' . $user . '" is not setup for encryption', \OC_Log::WARN ); } } return array( - 'ready' => $readyIds - , 'unready' => $unreadyIds + 'ready' => $readyIds, + 'unready' => $unreadyIds ); } @@ -897,32 +882,31 @@ class Util * @note This was used when 2 types of encryption for keyfiles was used, * but now we've switched to exclusively using openssl_seal() */ - public function decryptUnknownKeyfile($filePath, $fileOwner, $privateKey) - { + public function decryptUnknownKeyfile( $filePath, $fileOwner, $privateKey ) { // Get the encrypted keyfile // NOTE: the keyfile format depends on how it was encrypted! At // this stage we don't know how it was encrypted - $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath); + $encKeyfile = Keymanager::getFileKey( $this->view, $this->userId, $filePath ); // We need to decrypt the keyfile // Has the file been shared yet? if ( $this->userId == $fileOwner - && !Keymanager::getShareKey($this->view, $this->userId, $filePath) // NOTE: we can't use isShared() here because it's a post share hook so it always returns true + && !Keymanager::getShareKey( $this->view, $this->userId, $filePath ) // NOTE: we can't use isShared() here because it's a post share hook so it always returns true ) { // The file has no shareKey, and its keyfile must be // decrypted conventionally - $plainKeyfile = Crypt::keyDecrypt($encKeyfile, $privateKey); + $plainKeyfile = Crypt::keyDecrypt( $encKeyfile, $privateKey ); } else { // The file has a shareKey and must use it for decryption - $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath); + $shareKey = Keymanager::getShareKey( $this->view, $this->userId, $filePath ); - $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); + $plainKeyfile = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey ); } @@ -937,23 +921,22 @@ class Util * @param string $filePath path of the file to be shared * @return bool */ - public function setSharedFileKeyfiles(Session $session, array $users, $filePath) - { + public function setSharedFileKeyfiles( Session $session, array $users, $filePath ) { // Make sure users are capable of sharing - $filteredUids = $this->filterShareReadyUsers($users); + $filteredUids = $this->filterShareReadyUsers( $users ); // If we're attempting to share to unready users - if (!empty($filteredUids['unready'])) { + if ( !empty( $filteredUids['unready'] ) ) { - \OC_Log::write('Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"' . print_r($filteredUids['unready'], 1), \OC_Log::WARN); + \OC_Log::write( 'Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"' . print_r( $filteredUids['unready'], 1 ), \OC_Log::WARN ); return false; } // Get public keys for each user, ready for generating sharekeys - $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']); + $userPubKeys = Keymanager::getPublicKeys( $this->view, $filteredUids['ready'] ); // Note proxy status then disable it $proxyStatus = \OC_FileProxy::$enabled; @@ -962,22 +945,22 @@ class Util // Get the current users's private key for decrypting existing keyfile $privateKey = $session->getPrivateKey(); - $fileOwner = \OC\Files\Filesystem::getOwner($filePath); + $fileOwner = \OC\Files\Filesystem::getOwner( $filePath ); // Decrypt keyfile - $plainKeyfile = $this->decryptUnknownKeyfile($filePath, $fileOwner, $privateKey); + $plainKeyfile = $this->decryptUnknownKeyfile( $filePath, $fileOwner, $privateKey ); // Re-enc keyfile to (additional) sharekeys - $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys); + $multiEncKey = Crypt::multiKeyEncrypt( $plainKeyfile, $userPubKeys ); // Save the recrypted key to it's owner's keyfiles directory // Save new sharekeys to all necessary user directory if ( - !Keymanager::setFileKey($this->view, $filePath, $fileOwner, $multiEncKey['data']) - || !Keymanager::setShareKeys($this->view, $filePath, $multiEncKey['keys']) + !Keymanager::setFileKey( $this->view, $filePath, $fileOwner, $multiEncKey['data'] ) + || !Keymanager::setShareKeys( $this->view, $filePath, $multiEncKey['keys'] ) ) { - \OC_Log::write('Encryption library', 'Keyfiles could not be saved for users sharing ' . $filePath, \OC_Log::ERROR); + \OC_Log::write( 'Encryption library', 'Keyfiles could not be saved for users sharing ' . $filePath, \OC_Log::ERROR ); return false; @@ -993,12 +976,11 @@ class Util * @brief Find, sanitise and format users sharing a file * @note This wraps other methods into a portable bundle */ - public function getSharingUsersArray($sharingEnabled, $filePath, $currentUserId = false) - { + public function getSharingUsersArray( $sharingEnabled, $filePath, $currentUserId = false ) { // Check if key recovery is enabled if ( - \OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled') + \OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' ) && $this->recoveryEnabledForUser() ) { @@ -1011,14 +993,15 @@ class Util } // 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) { + $userIds = array(); + if ( $sharingEnabled ) { // Find out who, if anyone, is sharing the file - $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner, true, true, true); + $result = \OCP\Share::getUsersSharingFile( $ownerPath, $owner, true, true, true ); $userIds = $result['users']; - if ($result['public']) { + if ( $result['public'] ) { $userIds[] = $this->publicShareKeyId; } @@ -1026,10 +1009,10 @@ class Util // If recovery is enabled, add the // Admin UID to list of users to share to - if ($recoveryEnabled) { + if ( $recoveryEnabled ) { // Find recoveryAdmin user ID - $recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId'); + $recoveryKeyId = \OC_Appconfig::getValue( 'files_encryption', 'recoveryKeyId' ); // Add recoveryAdmin to list of users sharing $userIds[] = $recoveryKeyId; @@ -1037,14 +1020,14 @@ class Util } // add current user if given - if ($currentUserId != false) { + if ( $currentUserId != false ) { $userIds[] = $currentUserId; } // Remove duplicate UIDs - $uniqueUserIds = array_unique($userIds); + $uniqueUserIds = array_unique( $userIds ); return $uniqueUserIds; @@ -1055,8 +1038,7 @@ class Util * @param $status * @return bool */ - public function setMigrationStatus($status) - { + public function setMigrationStatus( $status ) { $sql = 'UPDATE *PREFIX*encryption @@ -1065,11 +1047,11 @@ class Util WHERE uid = ?'; - $args = array($status, $this->userId); + $args = array( $status, $this->userId ); - $query = \OCP\DB::prepare($sql); + $query = \OCP\DB::prepare( $sql ); - if ($query->execute($args)) { + if ( $query->execute( $args ) ) { return true; @@ -1087,8 +1069,7 @@ class Util * @note If records are not being returned, check for a hidden space * at the start of the uid in db */ - public function getMigrationStatus() - { + public function getMigrationStatus() { $sql = 'SELECT migration_status @@ -1097,22 +1078,21 @@ class Util WHERE uid = ?'; - $args = array($this->userId); + $args = array( $this->userId ); - $query = \OCP\DB::prepare($sql); + $query = \OCP\DB::prepare( $sql ); - $result = $query->execute($args); + $result = $query->execute( $args ); $migrationStatus = array(); - while ($row = $result->fetchRow()) { - + $row = $result->fetchRow(); + if($row) { $migrationStatus[] = $row['migration_status']; - } // If no record is found - if (empty($migrationStatus)) { + if ( empty( $migrationStatus ) ) { return false; @@ -1132,83 +1112,74 @@ class Util * relative to /Shared are also acceptable * @return array */ - public function getUidAndFilename($path) - { + public function getUidAndFilename( $path ) { - $view = new \OC\Files\View($this->userFilesDir); - $fileOwnerUid = $view->getOwner($path); + $view = new \OC\Files\View( $this->userFilesDir ); + $fileOwnerUid = $view->getOwner( $path ); // handle public access - if ($this->isPublic) { + if ( $this->isPublic ) { $filename = $path; $fileOwnerUid = $GLOBALS['fileOwner']; - return array($fileOwnerUid, $filename); + return array( $fileOwnerUid, $filename ); } else { // Check that UID is valid - if (!\OCP\User::userExists($fileOwnerUid)) { - throw new \Exception('Could not find owner (UID = "' . var_export($fileOwnerUid, 1) . '") of file "' . $path . '"'); + if ( !\OCP\User::userExists( $fileOwnerUid ) ) { + throw new \Exception( 'Could not find owner (UID = "' . var_export( $fileOwnerUid, 1 ) . '") of file "' . $path . '"' ); } // NOTE: Bah, this dependency should be elsewhere - \OC\Files\Filesystem::initMountPoints($fileOwnerUid); + \OC\Files\Filesystem::initMountPoints( $fileOwnerUid ); // If the file owner is the currently logged in user - if ($fileOwnerUid == $this->userId) { + if ( $fileOwnerUid == $this->userId ) { // Assume the path supplied is correct $filename = $path; } else { - $info = $view->getFileInfo($path); - $ownerView = new \OC\Files\View('/' . $fileOwnerUid . '/files'); + $info = $view->getFileInfo( $path ); + $ownerView = new \OC\Files\View( '/' . $fileOwnerUid . '/files' ); // Fetch real file path from DB - $filename = $ownerView->getPath($info['fileid']); // TODO: Check that this returns a path without including the user data dir + $filename = $ownerView->getPath( $info['fileid'] ); // TODO: Check that this returns a path without including the user data dir } - return array($fileOwnerUid, $filename); + return array( $fileOwnerUid, $filename ); } } /** - * @brief geo recursively through a dir and collect all files and sub files. + * @brief go recursively through a dir and collect all files and sub files. * @param string $dir relative to the users files folder * @return array with list of files relative to the users files folder */ - public function getAllFiles($dir) - { + public function getAllFiles( $dir ) { $result = array(); - $content = $this->view->getDirectoryContent($this->userFilesDir . $dir); + $content = $this->view->getDirectoryContent( $this->userFilesDir . $dir ); // handling for re shared folders - $path_split = explode('/', $dir); - $shared = ''; - - if ($path_split[1] === 'Shared') { - - $shared = '/Shared'; + $path_split = explode( '/', $dir ); - } - - foreach ($content as $c) { + foreach ( $content as $c ) { - $sharedPart = $path_split[sizeof($path_split) - 1]; - $targetPathSplit = array_reverse(explode('/', $c['path'])); + $sharedPart = $path_split[sizeof( $path_split ) - 1]; + $targetPathSplit = array_reverse( explode( '/', $c['path'] ) ); $path = ''; // rebuild path - foreach ($targetPathSplit as $pathPart) { + foreach ( $targetPathSplit as $pathPart ) { - if ($pathPart !== $sharedPart) { + if ( $pathPart !== $sharedPart ) { $path = '/' . $pathPart . $path; @@ -1222,9 +1193,9 @@ class Util $path = $dir . $path; - if ($c['type'] === "dir") { + if ( $c['type'] === "dir" ) { - $result = array_merge($result, $this->getAllFiles($path)); + $result = array_merge( $result, $this->getAllFiles( $path ) ); } else { @@ -1242,14 +1213,13 @@ class Util * @param int $id of the current share * @return array of the parent */ - public static function getShareParent($id) - { + public static function getShareParent( $id ) { - $query = \OC_DB::prepare('SELECT `file_target`, `item_type`' + $query = \OC_DB::prepare( 'SELECT `file_target`, `item_type`' . ' FROM `*PREFIX*share`' - . ' WHERE `id` = ?'); + . ' WHERE `id` = ?' ); - $result = $query->execute(array($id)); + $result = $query->execute( array( $id ) ); $row = $result->fetchRow(); @@ -1262,14 +1232,13 @@ class Util * @param int $id of the current share * @return array of the parent */ - public static function getParentFromShare($id) - { + public static function getParentFromShare( $id ) { - $query = \OC_DB::prepare('SELECT `parent`' + $query = \OC_DB::prepare( 'SELECT `parent`' . ' FROM `*PREFIX*share`' - . ' WHERE `id` = ?'); + . ' WHERE `id` = ?' ); - $result = $query->execute(array($id)); + $result = $query->execute( array( $id ) ); $row = $result->fetchRow(); @@ -1283,22 +1252,23 @@ class Util * @internal param int $Id of a share * @return string owner */ - public function getOwnerFromSharedFile($id) - { + public function getOwnerFromSharedFile( $id ) { + + $query = \OC_DB::prepare( 'SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1 ); + $source = $query->execute( array( $id ) )->fetchRow(); - $query = \OC_DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1); - $source = $query->execute(array($id))->fetchRow(); + $fileOwner = false; - if (isset($source['parent'])) { + if ( isset( $source['parent'] ) ) { $parent = $source['parent']; - while (isset($parent)) { + while ( isset( $parent ) ) { - $query = \OC_DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1); - $item = $query->execute(array($parent))->fetchRow(); + $query = \OC_DB::prepare( 'SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1 ); + $item = $query->execute( array( $parent ) )->fetchRow(); - if (isset($item['parent'])) { + if ( isset( $item['parent'] ) ) { $parent = $item['parent']; @@ -1324,16 +1294,14 @@ class Util /** * @return string */ - public function getUserId() - { + public function getUserId() { return $this->userId; } /** * @return string */ - public function getUserFilesDir() - { + public function getUserFilesDir() { return $this->userFilesDir; } @@ -1341,8 +1309,7 @@ class Util * @param $password * @return bool */ - public function checkRecoveryPassword($password) - { + public function checkRecoveryPassword( $password ) { $pathKey = '/owncloud_private_key/' . $this->recoveryKeyId . ".private.key"; $pathControlData = '/control-file/controlfile.enc'; @@ -1350,16 +1317,16 @@ class Util $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $recoveryKey = $this->view->file_get_contents($pathKey); + $recoveryKey = $this->view->file_get_contents( $pathKey ); - $decryptedRecoveryKey = Crypt::symmetricDecryptFileContent($recoveryKey, $password); + $decryptedRecoveryKey = Crypt::symmetricDecryptFileContent( $recoveryKey, $password ); - $controlData = $this->view->file_get_contents($pathControlData); - $decryptedControlData = Crypt::keyDecrypt($controlData, $decryptedRecoveryKey); + $controlData = $this->view->file_get_contents( $pathControlData ); + $decryptedControlData = Crypt::keyDecrypt( $controlData, $decryptedRecoveryKey ); \OC_FileProxy::$enabled = $proxyStatus; - if ($decryptedControlData === 'ownCloud') { + if ( $decryptedControlData === 'ownCloud' ) { return true; } @@ -1369,27 +1336,26 @@ class Util /** * @return string */ - public function getRecoveryKeyId() - { + public function getRecoveryKeyId() { return $this->recoveryKeyId; } /** * @brief add recovery key to all encrypted files */ - public function addRecoveryKeys($path = '/') - { - $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); - foreach ($dirContent as $item) { - $filePath = substr($item['path'], 25); - if ($item['type'] == 'dir') { - $this->addRecoveryKeys($filePath . '/'); + public function addRecoveryKeys( $path = '/' ) { + $dirContent = $this->view->getDirectoryContent( $this->keyfilesPath . $path ); + foreach ( $dirContent as $item ) { + // get relative path from files_encryption/keyfiles/ + $filePath = substr( $item['path'], strlen('files_encryption/keyfiles') ); + if ( $item['type'] == 'dir' ) { + $this->addRecoveryKeys( $filePath . '/' ); } else { - $session = new Session(new \OC_FilesystemView('/')); + $session = new Session( new \OC_FilesystemView( '/' ) ); $sharingEnabled = \OCP\Share::isEnabled(); - $file = substr($filePath, 0, -4); - $usersSharing = $this->getSharingUsersArray($sharingEnabled, $file); - $this->setSharedFileKeyfiles($session, $usersSharing, $file); + $file = substr( $filePath, 0, -4 ); + $usersSharing = $this->getSharingUsersArray( $sharingEnabled, $file ); + $this->setSharedFileKeyfiles( $session, $usersSharing, $file ); } } } @@ -1397,16 +1363,16 @@ class Util /** * @brief remove recovery key to all encrypted files */ - public function removeRecoveryKeys($path = '/') - { - $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); - foreach ($dirContent as $item) { - $filePath = substr($item['path'], 25); - if ($item['type'] == 'dir') { - $this->removeRecoveryKeys($filePath . '/'); + public function removeRecoveryKeys( $path = '/' ) { + $dirContent = $this->view->getDirectoryContent( $this->keyfilesPath . $path ); + foreach ( $dirContent as $item ) { + // get relative path from files_encryption/keyfiles + $filePath = substr( $item['path'], strlen('files_encryption/keyfiles') ); + if ( $item['type'] == 'dir' ) { + $this->removeRecoveryKeys( $filePath . '/' ); } else { - $file = substr($filePath, 0, -4); - $this->view->unlink($this->shareKeysPath . '/' . $file . '.' . $this->recoveryKeyId . '.shareKey'); + $file = substr( $filePath, 0, -4 ); + $this->view->unlink( $this->shareKeysPath . '/' . $file . '.' . $this->recoveryKeyId . '.shareKey' ); } } } @@ -1416,40 +1382,39 @@ class Util * @param string $file * @param string $privateKey recovery key to decrypt the file */ - private function recoverFile($file, $privateKey) - { + private function recoverFile( $file, $privateKey ) { $sharingEnabled = \OCP\Share::isEnabled(); // Find out who, if anyone, is sharing the file - if ($sharingEnabled) { - $result = \OCP\Share::getUsersSharingFile($file, $this->userId, true, true, true); + if ( $sharingEnabled ) { + $result = \OCP\Share::getUsersSharingFile( $file, $this->userId, true, true, true ); $userIds = $result['users']; $userIds[] = $this->recoveryKeyId; - if ($result['public']) { + if ( $result['public'] ) { $userIds[] = $this->publicShareKeyId; } } else { - $userIds = array($this->userId, $this->recoveryKeyId); + $userIds = array( $this->userId, $this->recoveryKeyId ); } - $filteredUids = $this->filterShareReadyUsers($userIds); + $filteredUids = $this->filterShareReadyUsers( $userIds ); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; //decrypt file key - $encKeyfile = $this->view->file_get_contents($this->keyfilesPath . $file . ".key"); - $shareKey = $this->view->file_get_contents($this->shareKeysPath . $file . "." . $this->recoveryKeyId . ".shareKey"); - $plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey); + $encKeyfile = $this->view->file_get_contents( $this->keyfilesPath . $file . ".key" ); + $shareKey = $this->view->file_get_contents( $this->shareKeysPath . $file . "." . $this->recoveryKeyId . ".shareKey" ); + $plainKeyfile = Crypt::multiKeyDecrypt( $encKeyfile, $shareKey, $privateKey ); // encrypt file key again to all users, this time with the new public key for the recovered use - $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']); - $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys); + $userPubKeys = Keymanager::getPublicKeys( $this->view, $filteredUids['ready'] ); + $multiEncKey = Crypt::multiKeyEncrypt( $plainKeyfile, $userPubKeys ); // write new keys to filesystem TDOO! - $this->view->file_put_contents($this->keyfilesPath . $file . '.key', $multiEncKey['data']); - foreach ($multiEncKey['keys'] as $userId => $shareKey) { + $this->view->file_put_contents( $this->keyfilesPath . $file . '.key', $multiEncKey['data'] ); + foreach ( $multiEncKey['keys'] as $userId => $shareKey ) { $shareKeyPath = $this->shareKeysPath . $file . '.' . $userId . '.shareKey'; - $this->view->file_put_contents($shareKeyPath, $shareKey); + $this->view->file_put_contents( $shareKeyPath, $shareKey ); } // Return proxy to original status @@ -1461,16 +1426,15 @@ class Util * @param string $path to look for files keys * @param string $privateKey private recovery key which is used to decrypt the files */ - private function recoverAllFiles($path, $privateKey) - { - $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); - foreach ($dirContent as $item) { - $filePath = substr($item['path'], 25); - if ($item['type'] == 'dir') { - $this->recoverAllFiles($filePath . '/', $privateKey); + private function recoverAllFiles( $path, $privateKey ) { + $dirContent = $this->view->getDirectoryContent( $this->keyfilesPath . $path ); + foreach ( $dirContent as $item ) { + $filePath = substr( $item['path'], 25 ); + if ( $item['type'] == 'dir' ) { + $this->recoverAllFiles( $filePath . '/', $privateKey ); } else { - $file = substr($filePath, 0, -4); - $this->recoverFile($file, $privateKey); + $file = substr( $filePath, 0, -4 ); + $this->recoverFile( $file, $privateKey ); } } } @@ -1479,19 +1443,18 @@ class Util * @brief recover users files in case of password lost * @param string $recoveryPassword */ - public function recoverUsersFiles($recoveryPassword) - { + public function recoverUsersFiles( $recoveryPassword ) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; - $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $this->recoveryKeyId . '.private.key'); - $privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $recoveryPassword); + $encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/' . $this->recoveryKeyId . '.private.key' ); + $privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, $recoveryPassword ); \OC_FileProxy::$enabled = $proxyStatus; - $this->recoverAllFiles('/', $privateKey); + $this->recoverAllFiles( '/', $privateKey ); } } diff --git a/apps/files_encryption/settings-admin.php b/apps/files_encryption/settings-admin.php index 66efc584367..6cc5b997fdb 100644 --- a/apps/files_encryption/settings-admin.php +++ b/apps/files_encryption/settings-admin.php @@ -15,7 +15,6 @@ $view = new OC_FilesystemView( '' ); $recoveryAdminEnabled = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' ); -$tmpl->assign( 'encryption_mode', \OC_Appconfig::getValue( 'files_encryption', 'mode', 'none' ) ); $tmpl->assign( 'recoveryEnabled', $recoveryAdminEnabled ); \OCP\Util::addscript( 'files_encryption', 'settings-admin' ); diff --git a/apps/files_encryption/settings-personal.php b/apps/files_encryption/settings-personal.php index ada8ffbc318..57f7f584523 100644 --- a/apps/files_encryption/settings-personal.php +++ b/apps/files_encryption/settings-personal.php @@ -26,4 +26,3 @@ $tmpl->assign( 'recoveryEnabledForUser', $recoveryEnabledForUser ); return $tmpl->fetchPage(); -return null; diff --git a/apps/files_encryption/templates/settings-personal.php b/apps/files_encryption/templates/settings-personal.php index 14e8ce960a2..04d6e79179e 100644 --- a/apps/files_encryption/templates/settings-personal.php +++ b/apps/files_encryption/templates/settings-personal.php @@ -29,18 +29,5 @@


-