diff options
author | Bjoern Schiessle <schiessle@owncloud.com> | 2014-11-10 12:40:24 +0100 |
---|---|---|
committer | Bjoern Schiessle <schiessle@owncloud.com> | 2014-11-26 10:57:47 +0100 |
commit | fd86d76f98f58ef232de58cc55401d85de262d0a (patch) | |
tree | e70c5c202d6de38a8bd9c7d43df8e024704ef4da /apps/files_encryption/lib | |
parent | c5fa8f1bdc08b07d03fcc9f9c84033960ec4e20f (diff) | |
download | nextcloud-server-fd86d76f98f58ef232de58cc55401d85de262d0a.tar.gz nextcloud-server-fd86d76f98f58ef232de58cc55401d85de262d0a.zip |
new folder structure for keys
all keys are now in files_encryption/key/path_to_file/filename/
share keys are named: user.shareKey
file key is named: fileKey
Diffstat (limited to 'apps/files_encryption/lib')
-rw-r--r-- | apps/files_encryption/lib/helper.php | 45 | ||||
-rw-r--r-- | apps/files_encryption/lib/keymanager.php | 372 | ||||
-rw-r--r-- | apps/files_encryption/lib/proxy.php | 2 | ||||
-rw-r--r-- | apps/files_encryption/lib/util.php | 74 |
4 files changed, 132 insertions, 361 deletions
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php index 7a50ade82f3..c512185522d 100644 --- a/apps/files_encryption/lib/helper.php +++ b/apps/files_encryption/lib/helper.php @@ -68,9 +68,9 @@ class Helper { \OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Encryption\Hooks', 'postRenameOrCopy'); \OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete'); \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete'); - \OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount'); - \OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUmount'); \OCP\Util::connectHook('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', 'OCA\Encryption\Hooks', 'postPasswordReset'); + \OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUnmount'); + \OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUnmount'); } /** @@ -433,47 +433,6 @@ class Helper { } /** - * find all share keys for a given file - * - * @param string $filePath path to the file name relative to the user's files dir - * for example "subdir/filename.txt" - * @param string $shareKeyPath share key prefix path relative to the user's data dir - * for example "user1/files_encryption/share-keys/subdir/filename.txt" - * @param \OC\Files\View $rootView root view, relative to data/ - * @return array list of share key files, path relative to data/$user - */ - public static function findShareKeys($filePath, $shareKeyPath, \OC\Files\View $rootView) { - $result = array(); - - $user = \OCP\User::getUser(); - $util = new Util($rootView, $user); - // get current sharing state - $sharingEnabled = \OCP\Share::isEnabled(); - - // get users sharing this file - $usersSharing = $util->getSharingUsersArray($sharingEnabled, $filePath); - - $pathinfo = pathinfo($shareKeyPath); - - $baseDir = $pathinfo['dirname'] . '/'; - $fileName = $pathinfo['basename']; - foreach ($usersSharing as $user) { - $keyName = $fileName . '.' . $user . '.shareKey'; - if ($rootView->file_exists($baseDir . $keyName)) { - $result[] = $baseDir . $keyName; - } else { - \OC_Log::write( - 'Encryption library', - 'No share key found for user "' . $user . '" for file "' . $fileName . '"', - \OC_Log::WARN - ); - } - } - - return $result; - } - - /** * remember from which file the tmp file (getLocalFile() call) was created * @param string $tmpFile path of tmp file * @param string $originalFile path of the original file relative to data/ diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php index 9560126ef33..53aaf435da8 100644 --- a/apps/files_encryption/lib/keymanager.php +++ b/apps/files_encryption/lib/keymanager.php @@ -29,6 +29,9 @@ namespace OCA\Encryption; */ class Keymanager { + // base dir where all the file related keys are stored + const KEYS_BASE_DIR = '/files_encryption/keys/'; + /** * retrieve the ENCRYPTED private key from a user * @@ -42,15 +45,10 @@ class Keymanager { $path = '/' . $user . '/' . 'files_encryption' . '/' . $user . '.private.key'; $key = false; - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - if ($view->file_exists($path)) { $key = $view->file_get_contents($path); } - \OC_FileProxy::$enabled = $proxyStatus; - return $key; } @@ -62,13 +60,8 @@ class Keymanager { */ public static function getPublicKey(\OC\Files\View $view, $userId) { - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - $result = $view->file_get_contents('/public-keys/' . $userId . '.public.key'); - \OC_FileProxy::$enabled = $proxyStatus; - return $result; } @@ -99,9 +92,7 @@ class Keymanager { $keys = array(); foreach ($userIds as $userId) { - $keys[$userId] = self::getPublicKey($view, $userId); - } return $keys; @@ -121,130 +112,121 @@ class Keymanager { */ public static function setFileKey(\OC\Files\View $view, $util, $path, $catfile) { - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - list($owner, $filename) = $util->getUidAndFilename($path); - - // in case of system wide mount points the keys are stored directly in the data directory - if ($util->isSystemWideMountPoint($filename)) { - $basePath = '/files_encryption/keyfiles'; - } else { - $basePath = '/' . $owner . '/files_encryption/keyfiles'; - } + $basePath = self::getKeyPath($view, $util, $path); - $targetPath = self::keySetPreparation($view, $filename, $basePath); + self::keySetPreparation($view, $basePath); - // try reusing key file if part file - if (Helper::isPartialFilePath($targetPath)) { - - $result = $view->file_put_contents( - $basePath . '/' . Helper::stripPartialFileExtension($targetPath) . '.key', $catfile); - - } else { - - $result = $view->file_put_contents($basePath . '/' . $targetPath . '.key', $catfile); - - } - - \OC_FileProxy::$enabled = $proxyStatus; + $result = $view->file_put_contents( + $basePath . '/fileKey', $catfile); return $result; } /** - * retrieve keyfile for an encrypted file - * @param \OC\Files\View $view + * get path to key folder for a given file + * + * @param \OC\Files\View $view relative to data directory * @param \OCA\Encryption\Util $util - * @param string|false $filePath - * @internal param \OCA\Encryption\file $string name - * @return string file key or false - * @note The keyfile returned is asymmetrically encrypted. Decryption - * of the keyfile must be performed by client code + * @param string $path path to the file, relative to the users file directory + * @return string */ - public static function getFileKey($view, $util, $filePath) { + public static function getKeyPath($view, $util, $path) { + if ($view->is_dir('/' . \OCP\User::getUser() . '/' . $path)) { + throw new Exception\EncryptionException('file was expected but directoy was given', Exception\EncryptionException::GENERIC); + } - list($owner, $filename) = $util->getUidAndFilename($filePath); + list($owner, $filename) = $util->getUidAndFilename($path); $filename = Helper::stripPartialFileExtension($filename); $filePath_f = ltrim($filename, '/'); // in case of system wide mount points the keys are stored directly in the data directory if ($util->isSystemWideMountPoint($filename)) { - $keyfilePath = '/files_encryption/keyfiles/' . $filePath_f . '.key'; + $keyPath = self::KEYS_BASE_DIR . $filePath_f . '/'; } else { - $keyfilePath = '/' . $owner . '/files_encryption/keyfiles/' . $filePath_f . '.key'; + $keyPath = '/' . $owner . self::KEYS_BASE_DIR . $filePath_f . '/'; } - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - if ($view->file_exists($keyfilePath)) { - - $result = $view->file_get_contents($keyfilePath); - - } else { + return $keyPath; + } - $result = false; + /** + * get path to file key for a given file + * + * @param \OC\Files\View $view relative to data directory + * @param \OCA\Encryption\Util $util + * @param string $path path to the file, relative to the users file directory + * @return string + */ + public static function getFileKeyPath($view, $util, $path) { + if ($view->is_dir('/' . \OCP\User::getUser() . '/' . $path)) { + throw new Exception\EncryptionException('file was expected but directoy was given', Exception\EncryptionException::GENERIC); } - \OC_FileProxy::$enabled = $proxyStatus; + list($owner, $filename) = $util->getUidAndFilename($path); + $filename = Helper::stripPartialFileExtension($filename); + $filePath_f = ltrim($filename, '/'); - return $result; + // in case of system wide mount points the keys are stored directly in the data directory + if ($util->isSystemWideMountPoint($filename)) { + $keyfilePath = self::KEYS_BASE_DIR . $filePath_f . '/fileKey'; + } else { + $keyfilePath = '/' . $owner . self::KEYS_BASE_DIR . $filePath_f . '/fileKey'; + } + return $keyfilePath; } /** - * Delete a keyfile + * get path to share key for a given user * - * @param \OC\Files\View $view - * @param string $path path of the file the key belongs to - * @param string $userId the user to whom the file belongs - * @return bool Outcome of unlink operation - * @note $path must be relative to data/user/files. e.g. mydoc.txt NOT - * /data/admin/files/mydoc.txt + * @param \OC\Files\View $view relateive to data directory + * @param \OCA\Encryption\Util $util + * @param string $path path to file relative to the users files directoy + * @param string $uid user for whom we want the share-key path + * @retrun string */ - public static function deleteFileKey($view, $path, $userId=null) { - - $trimmed = ltrim($path, '/'); + public static function getShareKeyPath($view, $util, $path, $uid) { - if ($trimmed === '') { - \OCP\Util::writeLog('Encryption library', - 'Can\'t delete file-key empty path given!', \OCP\Util::ERROR); - return false; + if ($view->is_dir('/' . \OCP\User::getUser() . '/' . $path)) { + throw new Exception\EncryptionException('file was expected but directoy was given', Exception\EncryptionException::GENERIC); } - if ($userId === null) { - $userId = Helper::getUser($path); - } - $util = new Util($view, $userId); + list($owner, $filename) = $util->getUidAndFilename($path); + $filename = Helper::stripPartialFileExtension($filename); - if($util->isSystemWideMountPoint($path)) { - $keyPath = '/files_encryption/keyfiles/' . $trimmed; + // in case of system wide mount points the keys are stored directly in the data directory + if ($util->isSystemWideMountPoint($filename)) { + $shareKeyPath = self::KEYS_BASE_DIR . $filename . '/'. $uid . '.shareKey'; } else { - $keyPath = '/' . $userId . '/files_encryption/keyfiles/' . $trimmed; + $shareKeyPath = '/' . $owner . self::KEYS_BASE_DIR . $filename . '/' . $uid . '.shareKey'; } - $result = false; - $fileExists = $view->file_exists('/' . $userId . '/files/' . $trimmed); + return $shareKeyPath; + } - if ($view->is_dir($keyPath) && !$fileExists) { - \OCP\Util::writeLog('files_encryption', 'deleteFileKey: delete file key: ' . $keyPath, \OCP\Util::DEBUG); - $result = $view->unlink($keyPath); - } elseif ($view->file_exists($keyPath . '.key') && !$fileExists) { - \OCP\Util::writeLog('files_encryption', 'deleteFileKey: delete file key: ' . $keyPath, \OCP\Util::DEBUG); - $result = $view->unlink($keyPath . '.key'); - } - if ($fileExists) { - \OCP\Util::writeLog('Encryption library', - 'Did not delete the file key, file still exists: ' . '/' . $userId . '/files/' . $trimmed, \OCP\Util::ERROR); - } elseif (!$result) { - \OCP\Util::writeLog('Encryption library', - 'Could not delete keyfile; does not exist: "' . $keyPath, \OCP\Util::ERROR); + /** + * retrieve keyfile for an encrypted file + * @param \OC\Files\View $view + * @param \OCA\Encryption\Util $util + * @param string|false $filePath + * @internal param \OCA\Encryption\file $string name + * @return string file key or false + * @note The keyfile returned is asymmetrically encrypted. Decryption + * of the keyfile must be performed by client code + */ + public static function getFileKey($view, $util, $filePath) { + + $keyfilePath = self::getFileKeyPath($view, $util, $filePath); + + if ($view->file_exists($keyfilePath)) { + $result = $view->file_get_contents($keyfilePath); + } else { + $result = false; } return $result; @@ -344,32 +326,18 @@ class Keymanager { * @param array $shareKeys * @return bool */ - public static function setShareKeys(\OC\Files\View $view, $util, $path, array $shareKeys) { - - // $shareKeys must be an array with the following format: - // [userId] => [encrypted key] - - list($owner, $filename) = $util->getUidAndFilename($path); + public static function setShareKeys($view, $util, $path, array $shareKeys) { // in case of system wide mount points the keys are stored directly in the data directory - if ($util->isSystemWideMountPoint($filename)) { - $basePath = '/files_encryption/share-keys'; - } else { - $basePath = '/' . $owner . '/files_encryption/share-keys'; - } + $basePath = Keymanager::getKeyPath($view, $util, $path); - $shareKeyPath = self::keySetPreparation($view, $filename, $basePath); + self::keySetPreparation($view, $basePath); $result = true; foreach ($shareKeys as $userId => $shareKey) { - // try reusing key file if part file - if (Helper::isPartialFilePath($shareKeyPath)) { - $writePath = $basePath . '/' . Helper::stripPartialFileExtension($shareKeyPath) . '.' . $userId . '.shareKey'; - } else { - $writePath = $basePath . '/' . $shareKeyPath . '.' . $userId . '.shareKey'; - } + $writePath = $basePath . '/' . $userId . '.shareKey'; if (!self::setShareKey($view, $writePath, $shareKey)) { @@ -392,89 +360,17 @@ class Keymanager { * @note The sharekey returned is encrypted. Decryption * of the keyfile must be performed by client code */ - public static function getShareKey(\OC\Files\View $view, $userId, $util, $filePath) { + public static function getShareKey($view, $userId, $util, $filePath) { - // try reusing key file if part file - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - list($owner, $filename) = $util->getUidAndFilename($filePath); - $filename = Helper::stripPartialFileExtension($filename); - // in case of system wide mount points the keys are stored directly in the data directory - if ($util->isSystemWideMountPoint($filename)) { - $shareKeyPath = '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey'; - } else { - $shareKeyPath = '/' . $owner . '/files_encryption/share-keys/' . $filename . '.' . $userId . '.shareKey'; - } + $shareKeyPath = self::getShareKeyPath($view, $util, $filePath, $userId); if ($view->file_exists($shareKeyPath)) { - $result = $view->file_get_contents($shareKeyPath); - } else { - $result = false; - } - \OC_FileProxy::$enabled = $proxyStatus; - return $result; - - } - - /** - * delete all share keys of a given file - * @param \OC\Files\View $view - * @param string $userId owner of the file - * @param string $filePath path to the file, relative to the owners file dir - */ - public static function delAllShareKeys($view, $userId, $filePath) { - - $filePath = ltrim($filePath, '/'); - - if ($view->file_exists('/' . $userId . '/files/' . $filePath)) { - \OCP\Util::writeLog('Encryption library', - 'File still exists, stop deleting share keys!', \OCP\Util::ERROR); - return false; - } - - if ($filePath === '') { - \OCP\Util::writeLog('Encryption library', - 'Can\'t delete share-keys empty path given!', \OCP\Util::ERROR); - return false; - } - - $util = new util($view, $userId); - - if ($util->isSystemWideMountPoint($filePath)) { - $baseDir = '/files_encryption/share-keys/'; - } else { - $baseDir = $userId . '/files_encryption/share-keys/'; - } - - $result = true; - - if ($view->is_dir($baseDir . $filePath)) { - \OCP\Util::writeLog('files_encryption', 'delAllShareKeys: delete share keys: ' . $baseDir . $filePath, \OCP\Util::DEBUG); - $result = $view->unlink($baseDir . $filePath); - } else { - $sharingEnabled = \OCP\Share::isEnabled(); - $users = $util->getSharingUsersArray($sharingEnabled, $filePath); - foreach($users as $user) { - $keyName = $baseDir . $filePath . '.' . $user . '.shareKey'; - if ($view->file_exists($keyName)) { - \OCP\Util::writeLog( - 'files_encryption', - 'dellAllShareKeys: delete share keys: "' . $keyName . '"', - \OCP\Util::DEBUG - ); - $result &= $view->unlink($keyName); - } - } - } - - return (bool)$result; } /** @@ -482,45 +378,19 @@ class Keymanager { * * @param \OC\Files\View $view relative to data/ * @param array $userIds list of users we want to remove - * @param string $filename the owners name of the file for which we want to remove the users relative to data/user/files - * @param string $owner owner of the file + * @param string $keyPath + * @param string $owner the owner of the file + * @param string $ownerPath the owners name of the file for which we want to remove the users relative to data/user/files */ - public static function delShareKey($view, $userIds, $filename, $owner) { + public static function delShareKey($view, $userIds, $keysPath, $owner, $ownerPath) { - $proxyStatus = \OC_FileProxy::$enabled; - \OC_FileProxy::$enabled = false; - - $util = new Util($view, $owner); - - if ($util->isSystemWideMountPoint($filename)) { - $shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename); - } else { - $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename); + $key = array_search($owner, $userIds, true); + if ($key !== false && $view->file_exists('/' . $owner . '/files/' . $ownerPath)) { + unset($userIds[$key]); } - if ($view->is_dir($shareKeyPath)) { - - self::recursiveDelShareKeys($shareKeyPath, $userIds, $owner, $view); - - } else { - - foreach ($userIds as $userId) { - - if ($userId === $owner && $view->file_exists('/' . $owner . '/files/' . $filename)) { - \OCP\Util::writeLog('files_encryption', 'Tried to delete owner key, but the file still exists!', \OCP\Util::FATAL); - continue; - } - $result = $view->unlink($shareKeyPath . '.' . $userId . '.shareKey'); - \OCP\Util::writeLog('files_encryption', 'delShareKey: delete share key: ' . $shareKeyPath . '.' . $userId . '.shareKey' , \OCP\Util::DEBUG); - if (!$result) { - \OCP\Util::writeLog('Encryption library', - 'Could not delete shareKey; does not exist: "' . $shareKeyPath . '.' . $userId - . '.shareKey"', \OCP\Util::ERROR); - } - } - } + self::recursiveDelShareKeys($keysPath, $userIds, $view); - \OC_FileProxy::$enabled = $proxyStatus; } /** @@ -528,35 +398,23 @@ class Keymanager { * * @param string $dir directory * @param array $userIds user ids for which the share keys should be deleted - * @param string $owner owner of the file * @param \OC\Files\View $view view relative to data/ */ - private static function recursiveDelShareKeys($dir, $userIds, $owner, $view) { + private static function recursiveDelShareKeys($dir, $userIds, $view) { $dirContent = $view->opendir($dir); - $dirSlices = explode('/', ltrim($dir, '/')); - $realFileDir = '/' . $owner . '/files/' . implode('/', array_slice($dirSlices, 3)) . '/'; if (is_resource($dirContent)) { while (($file = readdir($dirContent)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($file)) { if ($view->is_dir($dir . '/' . $file)) { - self::recursiveDelShareKeys($dir . '/' . $file, $userIds, $owner, $view); + self::recursiveDelShareKeys($dir . '/' . $file, $userIds, $view); } else { foreach ($userIds as $userId) { - $fileNameFromShareKey = self::getFilenameFromShareKey($file, $userId); - if (!$fileNameFromShareKey) { - continue; - } - $realFile = $realFileDir . $fileNameFromShareKey; - - if ($userId === $owner && - $view->file_exists($realFile)) { - \OCP\Util::writeLog('files_encryption', 'original file still exists, keep owners share key!', \OCP\Util::ERROR); - continue; + if ($userId . '.shareKey' === $file) { + \OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG); + $view->unlink($dir . '/' . $file); } - \OCP\Util::writeLog('files_encryption', 'recursiveDelShareKey: delete share key: ' . $file, \OCP\Util::DEBUG); - $view->unlink($dir . '/' . $file); } } } @@ -567,21 +425,16 @@ class Keymanager { /** * Make preparations to vars and filesystem for saving a keyfile - * @param string|boolean $path + * + * @param \OC\Files\View $view + * @param string $path relatvie to the views root * @param string $basePath */ - protected static function keySetPreparation(\OC\Files\View $view, $path, $basePath) { - - $targetPath = ltrim($path, '/'); - - $path_parts = pathinfo($targetPath); + protected static function keySetPreparation($view, $path) { // If the file resides within a subdirectory, create it - if ( - isset($path_parts['dirname']) - && !$view->file_exists($basePath . '/' . $path_parts['dirname']) - ) { - $sub_dirs = explode('/', $basePath . '/' . $path_parts['dirname']); + if (!$view->file_exists($path)) { + $sub_dirs = explode('/', $path); $dir = ''; foreach ($sub_dirs as $sub_dir) { $dir .= '/' . $sub_dir; @@ -590,27 +443,6 @@ class Keymanager { } } } - - return $targetPath; - } - /** - * extract filename from share key name - * @param string $shareKey (filename.userid.sharekey) - * @param string $userId - * @return string|false filename or false - */ - protected static function getFilenameFromShareKey($shareKey, $userId) { - $expectedSuffix = '.' . $userId . '.' . 'shareKey'; - $suffixLen = strlen($expectedSuffix); - - $suffix = substr($shareKey, -$suffixLen); - - if ($suffix !== $expectedSuffix) { - return false; - } - - return substr($shareKey, 0, -$suffixLen); - } } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index a358a46a6e7..8c8ffd61207 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -204,11 +204,11 @@ class Proxy extends \OC_FileProxy { public function postFile_get_contents($path, $data) { $plainData = null; - $view = new \OC\Files\View('/'); // If data is a catfile if ( Crypt::mode() === 'server' + && $this->shouldEncrypt($path) && Crypt::isCatfileContent($data) ) { diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php index d214d13de69..a1baecfb2f3 100644 --- a/apps/files_encryption/lib/util.php +++ b/apps/files_encryption/lib/util.php @@ -44,10 +44,10 @@ class Util { private $client; // Client side encryption mode flag private $publicKeyDir; // Dir containing all public user keys private $encryptionDir; // Dir containing user's files_encryption - private $keyfilesPath; // Dir containing user's keyfiles - private $shareKeysPath; // Dir containing env keys for shared files + private $keysPath; // Dir containing all file related encryption keys private $publicKeyPath; // Path to user's public key private $privateKeyPath; // Path to user's private key + private $userFilesDir; private $publicShareKeyId; private $recoveryKeyId; private $isPublic; @@ -74,8 +74,7 @@ class Util { '/' . $userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable? $this->publicKeyDir = '/' . 'public-keys'; $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption'; - $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles'; - $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys'; + $this->keysPath = $this->encryptionDir . '/' . 'keys'; $this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key $this->privateKeyPath = @@ -99,8 +98,7 @@ class Util { 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->keysPath) or !$this->view->file_exists($this->publicKeyPath) or !$this->view->file_exists($this->privateKeyPath) ) { @@ -149,8 +147,7 @@ class Util { $this->userDir, $this->publicKeyDir, $this->encryptionDir, - $this->keyfilesPath, - $this->shareKeysPath + $this->keysPath ); // Check / create all necessary dirs @@ -727,8 +724,8 @@ class Util { } if ($successful) { - $this->view->rename($this->keyfilesPath, $this->keyfilesPath . '.backup'); - $this->view->rename($this->shareKeysPath, $this->shareKeysPath . '.backup'); + $this->backupAllKeys('decryptAll'); + $this->view->deleteAll($this->keysPath); } \OC_FileProxy::$enabled = true; @@ -845,9 +842,9 @@ class Util { break; - case 'keyfilesPath': + case 'keysPath': - return $this->keyfilesPath; + return $this->keysPath; break; @@ -1395,19 +1392,17 @@ class Util { * add recovery key to all encrypted files */ public function addRecoveryKeys($path = '/') { - $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); + $dirContent = $this->view->getDirectoryContent($this->keysPath . '/' . $path); foreach ($dirContent as $item) { // get relative path from files_encryption/keyfiles/ - $filePath = substr($item['path'], strlen('files_encryption/keyfiles')); - if ($item['type'] === 'dir') { + $filePath = substr($item['path'], strlen('files_encryption/keys')); + if ($this->view->is_dir($this->userFilesDir . '/' . $filePath)) { $this->addRecoveryKeys($filePath . '/'); } else { $session = new \OCA\Encryption\Session(new \OC\Files\View('/')); $sharingEnabled = \OCP\Share::isEnabled(); - // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt' - $file = substr($filePath, 0, -4); - $usersSharing = $this->getSharingUsersArray($sharingEnabled, $file); - $this->setSharedFileKeyfiles($session, $usersSharing, $file); + $usersSharing = $this->getSharingUsersArray($sharingEnabled, $filePath); + $this->setSharedFileKeyfiles($session, $usersSharing, $filePath); } } } @@ -1416,16 +1411,14 @@ class Util { * remove recovery key to all encrypted files */ public function removeRecoveryKeys($path = '/') { - $dirContent = $this->view->getDirectoryContent($this->keyfilesPath . $path); + $dirContent = $this->view->getDirectoryContent($this->keysPath . '/' . $path); foreach ($dirContent as $item) { // get relative path from files_encryption/keyfiles - $filePath = substr($item['path'], strlen('files_encryption/keyfiles')); - if ($item['type'] === 'dir') { + $filePath = substr($item['path'], strlen('files_encryption/keys')); + if ($this->view->is_dir($this->userFilesDir . '/' . $filePath)) { $this->removeRecoveryKeys($filePath . '/'); } else { - // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt' - $file = substr($filePath, 0, -4); - $this->view->unlink($this->shareKeysPath . '/' . $file . '.' . $this->recoveryKeyId . '.shareKey'); + $this->view->unlink($this->keysPath . '/' . $filePath . '/' . $this->recoveryKeyId . '.shareKey'); } } } @@ -1455,27 +1448,17 @@ class Util { } $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"); + $encKeyfile = Keymanager::getFileKey($this->view, $this, $file); + $shareKey = Keymanager::getShareKey($this->view, $this->recoveryKeyId, $this, $file); $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); - // write new keys to filesystem TDOO! - $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); - } + Keymanager::setFileKey($this->view, $this, $file, $multiEncKey['data']); + Keymanager::setShareKeys($this->view, $this, $file, $multiEncKey['keys']); - // Return proxy to original status - \OC_FileProxy::$enabled = $proxyStatus; } /** @@ -1484,16 +1467,14 @@ class Util { * @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); + $dirContent = $this->view->getDirectoryContent($this->keysPath . '/' . $path); foreach ($dirContent as $item) { // get relative path from files_encryption/keyfiles - $filePath = substr($item['path'], strlen('files_encryption/keyfiles')); - if ($item['type'] === 'dir') { + $filePath = substr($item['path'], strlen('files_encryption/keys')); + if ($this->view->is_dir($this->userFilesDir . '/' . $filePath)) { $this->recoverAllFiles($filePath . '/', $privateKey); } else { - // remove '.key' extension from path e.g. 'file.txt.key' to 'file.txt' - $file = substr($filePath, 0, -4); - $this->recoverFile($file, $privateKey); + $this->recoverFile($filePath, $privateKey); } } } @@ -1527,8 +1508,7 @@ class Util { $backupDir = $this->encryptionDir . '/backup.'; $backupDir .= ($purpose === '') ? date("Y-m-d_H-i-s") . '/' : $purpose . '.' . date("Y-m-d_H-i-s") . '/'; $this->view->mkdir($backupDir); - $this->view->copy($this->shareKeysPath, $backupDir . 'share-keys/'); - $this->view->copy($this->keyfilesPath, $backupDir . 'keyfiles/'); + $this->view->copy($this->keysPath, $backupDir . 'keys/'); $this->view->copy($this->privateKeyPath, $backupDir . $this->userId . '.private.key'); $this->view->copy($this->publicKeyPath, $backupDir . $this->userId . '.public.key'); } |