Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix encryption:fix-encrypted-version command when encrypted is set to 0 #33433

Merged
merged 3 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions apps/encryption/lib/Command/FixEncryptedVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ protected function configure(): void {
);
}

/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$skipSignatureCheck = $this->config->getSystemValue('encryption_skip_signature_check', false);
$this->supportLegacy = $this->config->getSystemValueBool('encryption.legacy_format_support', false);
Expand All @@ -121,7 +116,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$pathToWalk = "$pathToWalk/$pathOption";
}

if ($user === null) {
if ($user === '') {
$output->writeln("<error>No user id provided.</error>\n");
return 1;
}
Expand All @@ -134,12 +129,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

/**
* @param string $user
* @param string $path
* @param OutputInterface $output
* @return int 0 for success, 1 for error
*/
private function walkPathOfUser($user, $path, OutputInterface $output): int {
private function walkPathOfUser(string $user, string $path, OutputInterface $output): int {
$this->setupUserFs($user);
if (!$this->view->file_exists($path)) {
$output->writeln("<error>Path \"$path\" does not exist. Please provide a valid path.</error>");
Expand Down Expand Up @@ -169,11 +161,9 @@ private function walkPathOfUser($user, $path, OutputInterface $output): int {
}

/**
* @param string $path
* @param OutputInterface $output
* @param bool $ignoreCorrectEncVersionCall, setting this variable to false avoids recursion
*/
private function verifyFileContent($path, OutputInterface $output, $ignoreCorrectEncVersionCall = true): bool {
private function verifyFileContent(string $path, OutputInterface $output, bool $ignoreCorrectEncVersionCall = true): bool {
try {
/**
* In encryption, the files are read in a block size of 8192 bytes
Expand All @@ -185,6 +175,22 @@ private function verifyFileContent($path, OutputInterface $output, $ignoreCorrec
$handle = $this->view->fopen($path, 'rb');

if (\fread($handle, 9001) !== false) {
$fileInfo = $this->view->getFileInfo($path);
if (!$fileInfo) {
$output->writeln("<warning>File info not found for file: \"$path\"</warning>");
come-nc marked this conversation as resolved.
Show resolved Hide resolved
return true;
}
$encryptedVersion = $fileInfo->getEncryptedVersion();
$stat = $this->view->stat($path);
if (($encryptedVersion == 0) && isset($stat['hasHeader']) && ($stat['hasHeader'] == true)) {
PVince81 marked this conversation as resolved.
Show resolved Hide resolved
// The file has encrypted to false but has an encryption header
if ($ignoreCorrectEncVersionCall === true) {
// Lets rectify the file by correcting encrypted version
$output->writeln("<info>Attempting to fix the path: \"$path\"</info>");
return $this->correctEncryptedVersion($path, $output);
}
return false;
}
$output->writeln("<info>The file \"$path\" is: OK</info>");
}

Expand All @@ -201,9 +207,9 @@ private function verifyFileContent($path, OutputInterface $output, $ignoreCorrec
return false;
} catch (HintException $e) {
$this->logger->warning("Issue: " . $e->getMessage());
//If allowOnce is set to false, this becomes recursive.
// If allowOnce is set to false, this becomes recursive.
if ($ignoreCorrectEncVersionCall === true) {
//Lets rectify the file by correcting encrypted version
// Lets rectify the file by correcting encrypted version
$output->writeln("<info>Attempting to fix the path: \"$path\"</info>");
return $this->correctEncryptedVersion($path, $output);
}
Expand All @@ -212,18 +218,19 @@ private function verifyFileContent($path, OutputInterface $output, $ignoreCorrec
}

/**
* @param string $path
* @param OutputInterface $output
* @param bool $includeZero whether to try zero version for unencrypted file
* @return bool
*/
private function correctEncryptedVersion($path, OutputInterface $output, bool $includeZero = false): bool {
private function correctEncryptedVersion(string $path, OutputInterface $output, bool $includeZero = false): bool {
$fileInfo = $this->view->getFileInfo($path);
if (!$fileInfo) {
$output->writeln("<warning>File info not found for file: \"$path\"</warning>");
return true;
}
$fileId = $fileInfo->getId();
if ($fileId === null) {
$output->writeln("<warning>File info contains no id for file: \"$path\"</warning>");
come-nc marked this conversation as resolved.
Show resolved Hide resolved
return true;
}
$encryptedVersion = $fileInfo->getEncryptedVersion();
$wrongEncryptedVersion = $encryptedVersion;

Expand Down Expand Up @@ -255,7 +262,7 @@ private function correctEncryptedVersion($path, OutputInterface $output, bool $i
}
}

//test by decrementing the value till 1 and if nothing works try incrementing
// Test by decrementing the value till 1 and if nothing works try incrementing
$encryptedVersion--;
while ($encryptedVersion > 0) {
$cacheInfo = ['encryptedVersion' => $encryptedVersion, 'encrypted' => $encryptedVersion];
Expand All @@ -268,7 +275,7 @@ private function correctEncryptedVersion($path, OutputInterface $output, bool $i
$encryptedVersion--;
}

//So decrementing did not work. Now lets increment. Max increment is till 5
// So decrementing did not work. Now lets increment. Max increment is till 5
$increment = 1;
while ($increment <= 5) {
/**
Expand Down Expand Up @@ -301,9 +308,8 @@ private function correctEncryptedVersion($path, OutputInterface $output, bool $i

/**
* Setup user file system
* @param string $uid
*/
private function setupUserFs($uid): void {
private function setupUserFs(string $uid): void {
\OC_Util::tearDownFS();
\OC_Util::setupFS($uid);
}
Expand Down
17 changes: 14 additions & 3 deletions apps/encryption/tests/Command/FixEncryptedVersionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ public function testExecuteWithDirectoryPathOption() {
$this->assertStringNotContainsString('world.txt', $output);
}

/**
* Test commands with a directory path
*/
public function testExecuteWithNoUser() {
$this->util->expects($this->once())->method('isMasterKeyEnabled')
->willReturn(true);
Expand All @@ -347,6 +344,20 @@ public function testExecuteWithNoUser() {

$output = $this->commandTester->getDisplay();

$this->assertStringContainsString('No user id provided', $output);
}

public function testExecuteWithBadUser() {
$this->util->expects($this->once())->method('isMasterKeyEnabled')
->willReturn(true);

$this->commandTester->execute([
'user' => 'nonexisting',
'--path' => "/"
]);

$output = $this->commandTester->getDisplay();

$this->assertStringContainsString('does not exist', $output);
}

Expand Down