diff options
Diffstat (limited to 'core/Command/Encryption/MigrateKeyStorage.php')
-rw-r--r-- | core/Command/Encryption/MigrateKeyStorage.php | 174 |
1 files changed, 62 insertions, 112 deletions
diff --git a/core/Command/Encryption/MigrateKeyStorage.php b/core/Command/Encryption/MigrateKeyStorage.php index 98dea8fad5c..937b17cde5f 100644 --- a/core/Command/Encryption/MigrateKeyStorage.php +++ b/core/Command/Encryption/MigrateKeyStorage.php @@ -3,28 +3,9 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ - - namespace OC\Core\Command\Encryption; use OC\Encryption\Keys\Storage; @@ -35,41 +16,21 @@ use OCP\IUserManager; use OCP\Security\ICrypto; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class MigrateKeyStorage extends Command { - - /** @var View */ - protected $rootView; - - /** @var IUserManager */ - protected $userManager; - - /** @var IConfig */ - protected $config; - - /** @var Util */ - protected $util; - - /** @var QuestionHelper */ - protected $questionHelper; - /** - * @var ICrypto - */ - private $crypto; - - public function __construct(View $view, IUserManager $userManager, IConfig $config, Util $util, ICrypto $crypto) { + public function __construct( + protected View $rootView, + protected IUserManager $userManager, + protected IConfig $config, + protected Util $util, + private ICrypto $crypto, + ) { parent::__construct(); - $this->rootView = $view; - $this->userManager = $userManager; - $this->config = $config; - $this->util = $util; - $this->crypto = $crypto; } - protected function configure() { + protected function configure(): void { parent::configure(); $this ->setName('encryption:migrate-key-storage-format') @@ -79,94 +40,85 @@ class MigrateKeyStorage extends Command { protected function execute(InputInterface $input, OutputInterface $output): int { $root = $this->util->getKeyStorageRoot(); - $output->writeln("Updating key storage format"); + $output->writeln('Updating key storage format'); $this->updateKeys($root, $output); - $output->writeln("Key storage format successfully updated"); + $output->writeln('Key storage format successfully updated'); return 0; } /** - * move keys to new key storage root + * Move keys to new key storage root * - * @param string $root - * @param OutputInterface $output - * @return bool * @throws \Exception */ - protected function updateKeys(string $root, OutputInterface $output) { - $output->writeln("Start to update the keys:"); + protected function updateKeys(string $root, OutputInterface $output): bool { + $output->writeln('Start to update the keys:'); - $this->updateSystemKeys($root); + $this->updateSystemKeys($root, $output); $this->updateUsersKeys($root, $output); $this->config->deleteSystemValue('encryption.key_storage_migrated'); return true; } /** - * move system key folder - * - * @param string $root + * Move system key folder */ - protected function updateSystemKeys($root) { + protected function updateSystemKeys(string $root, OutputInterface $output): void { if (!$this->rootView->is_dir($root . '/files_encryption')) { return; } - $this->traverseKeys($root . '/files_encryption', null); + $this->traverseKeys($root . '/files_encryption', null, $output); } - private function traverseKeys(string $folder, ?string $uid) { + private function traverseKeys(string $folder, ?string $uid, OutputInterface $output): void { $listing = $this->rootView->getDirectoryContent($folder); foreach ($listing as $node) { if ($node['mimetype'] === 'httpd/unix-directory') { - //ignore - } else { - $endsWith = function ($haystack, $needle) { - $length = strlen($needle); - if ($length === 0) { - return true; - } + continue; + } - return (substr($haystack, -$length) === $needle); - }; + if ($node['name'] === 'fileKey' + || str_ends_with($node['name'], '.privateKey') + || str_ends_with($node['name'], '.publicKey') + || str_ends_with($node['name'], '.shareKey')) { + $path = $folder . '/' . $node['name']; - if ($node['name'] === 'fileKey' || - $endsWith($node['name'], '.privateKey') || - $endsWith($node['name'], '.publicKey') || - $endsWith($node['name'], '.shareKey')) { - $path = $folder . '/' . $node['name']; + $content = $this->rootView->file_get_contents($path); - $content = $this->rootView->file_get_contents($path); + if ($content === false) { + $output->writeln("<error>Failed to open path $path</error>"); + continue; + } - try { - $this->crypto->decrypt($content); - continue; - } catch (\Exception $e) { - // Ignore we now update the data. - } + try { + $this->crypto->decrypt($content); + continue; + } catch (\Exception $e) { + // Ignore we now update the data. + } - $data = [ - 'key' => base64_encode($content), - 'uid' => $uid, - ]; + $data = [ + 'key' => base64_encode($content), + 'uid' => $uid, + ]; - $enc = $this->crypto->encrypt(json_encode($data)); - $this->rootView->file_put_contents($path, $enc); - } + $enc = $this->crypto->encrypt(json_encode($data)); + $this->rootView->file_put_contents($path, $enc); } } } - private function traverseFileKeys(string $folder) { + private function traverseFileKeys(string $folder, OutputInterface $output): void { $listing = $this->rootView->getDirectoryContent($folder); foreach ($listing as $node) { if ($node['mimetype'] === 'httpd/unix-directory') { - $this->traverseFileKeys($folder . '/' . $node['name']); + $this->traverseFileKeys($folder . '/' . $node['name'], $output); } else { - $endsWith = function ($haystack, $needle) { + $endsWith = function (string $haystack, string $needle): bool { $length = strlen($needle); if ($length === 0) { return true; @@ -175,14 +127,19 @@ class MigrateKeyStorage extends Command { return (substr($haystack, -$length) === $needle); }; - if ($node['name'] === 'fileKey' || - $endsWith($node['name'], '.privateKey') || - $endsWith($node['name'], '.publicKey') || - $endsWith($node['name'], '.shareKey')) { + if ($node['name'] === 'fileKey' + || $endsWith($node['name'], '.privateKey') + || $endsWith($node['name'], '.publicKey') + || $endsWith($node['name'], '.shareKey')) { $path = $folder . '/' . $node['name']; $content = $this->rootView->file_get_contents($path); + if ($content === false) { + $output->writeln("<error>Failed to open path $path</error>"); + continue; + } + try { $this->crypto->decrypt($content); continue; @@ -204,10 +161,8 @@ class MigrateKeyStorage extends Command { /** * setup file system for the given user - * - * @param string $uid */ - protected function setupUserFS($uid) { + protected function setupUserFS(string $uid): void { \OC_Util::tearDownFS(); \OC_Util::setupFS($uid); } @@ -215,11 +170,8 @@ class MigrateKeyStorage extends Command { /** * iterate over each user and move the keys to the new storage - * - * @param string $root - * @param OutputInterface $output */ - protected function updateUsersKeys(string $root, OutputInterface $output) { + protected function updateUsersKeys(string $root, OutputInterface $output): void { $progress = new ProgressBar($output); $progress->start(); @@ -231,7 +183,7 @@ class MigrateKeyStorage extends Command { foreach ($users as $user) { $progress->advance(); $this->setupUserFS($user); - $this->updateUserKeys($root, $user); + $this->updateUserKeys($root, $user, $output); } $offset += $limit; } while (count($users) >= $limit); @@ -242,20 +194,18 @@ class MigrateKeyStorage extends Command { /** * move user encryption folder to new root folder * - * @param string $root - * @param string $user * @throws \Exception */ - protected function updateUserKeys(string $root, string $user) { + protected function updateUserKeys(string $root, string $user, OutputInterface $output): void { if ($this->userManager->userExists($user)) { $source = $root . '/' . $user . '/files_encryption/OC_DEFAULT_MODULE'; if ($this->rootView->is_dir($source)) { - $this->traverseKeys($source, $user); + $this->traverseKeys($source, $user, $output); } $source = $root . '/' . $user . '/files_encryption/keys'; if ($this->rootView->is_dir($source)) { - $this->traverseFileKeys($source); + $this->traverseFileKeys($source, $output); } } } |