Skip to content

Commit

Permalink
Merge pull request #3361 from LibreSign/backport/3358/stable28
Browse files Browse the repository at this point in the history
[stable28] fix: Java setup
  • Loading branch information
vitormattos authored Jul 12, 2024
2 parents c56a627 + 716f668 commit 00a0ed9
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 63 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ appstore:
if [ -f $(cert_dir)/$(app_name).key ]; then \
curl -o $(cert_dir)/$(app_name).crt \
"https://raw.githubusercontent.com/nextcloud/app-certificate-requests/master/$(app_name)/$(app_name).crt"; \
$(occ) libresign:install --all --architecture aarch64; \
$(occ) libresign:install --all --architecture x86_64; \
$(occ) libresign:install --all --all-distros --architecture=aarch64; \
$(occ) libresign:install --all --all-distros --architecture=x86_64; \
echo "Signing setup files…"; \
$(occ) config:system:set debug --value true --type boolean; \
$(occ) libresign:developer:sign-setup \
Expand Down
22 changes: 21 additions & 1 deletion lib/Command/Developer/SignSetup.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->signSetupService->setPrivateKey($rsa);
foreach ($this->signSetupService->getArchitectures() as $architecture) {
foreach ($this->installService->getAvailableResources() as $resource) {
$this->signSetupService->writeAppSignature($architecture, $resource);
if ($resource === 'java') {
foreach (['linux', 'alpine-linux'] as $distro) {
$this->installService->setDistro($distro);
$this->writeAppSignature($architecture, $resource);
}
continue;
}
$this->writeAppSignature($architecture, $resource);
}
}
$output->writeln('Successfully signed');
Expand All @@ -88,4 +95,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
return 0;
}

private function writeAppSignature(string $architecture, string $resource): void {
$this->installService
->setArchitecture($architecture)
->setResource($resource);
$this->signSetupService->setInstallPath(
$this->installService->getInstallPath()
);
$this->signSetupService->setSignatureFileName(
$this->installService->getSignatureFileName()
);
$this->signSetupService->writeAppSignature($architecture, $resource);
}
}
16 changes: 14 additions & 2 deletions lib/Command/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ protected function configure(): void {
shortcut: null,
mode: InputOption::VALUE_REQUIRED,
description: 'x86_64 or aarch64'
)
->addOption(
name: 'all-distros',
shortcut: null,
mode: InputOption::VALUE_NONE,
description: 'Will download java to all available distros'
);
if ($this->config->getSystemValue('debug', false) === true) {
$this->addOption(
Expand All @@ -106,8 +112,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
$all = $input->getOption('all');
if ($input->getOption('java') || $all) {
if ($all) {
foreach (['linux', 'alpine-linux'] as $distro) {
if ($input->getOption('all-distros')) {
$currentDistro = $this->installService->getLinuxDistributionToDownloadJava();
if ($currentDistro === 'linux') {
$distros = ['alpine-linux', 'linux'];
} else {
$distros = ['linux', 'alpine-linux'];
}
foreach ($distros as $distro) {
$this->installService->setDistro($distro);
$this->installService->installJava();
}
Expand Down
76 changes: 61 additions & 15 deletions lib/Service/Install/InstallService.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class InstallService {
'java',
'jsignpdf',
'pdftk',
'cfssl'
'cfssl',
];
private string $distro = '';
private string $architecture;
Expand All @@ -100,8 +100,9 @@ public function setOutput(OutputInterface $output): void {
$this->output = $output;
}

public function setArchitecture(string $architecture): void {
public function setArchitecture(string $architecture): self {
$this->architecture = $architecture;
return $this;
}

private function getFolder(string $path = '', ?ISimpleFolder $folder = null, $needToBeEmpty = false): ISimpleFolder {
Expand Down Expand Up @@ -378,6 +379,13 @@ private function writeAppSignature(): void {
if (!$this->willUseLocalCert) {
return;
}

$this->signSetupService->setSignatureFileName(
$this->getSignatureFileName()
);
$this->signSetupService->setInstallPath(
$this->getInstallPath()
);
$this->signSetupService->writeAppSignature($this->architecture, $this->resource);
}

Expand All @@ -393,9 +401,8 @@ public function installJava(?bool $async = false): void {
$linuxDistribution = $this->getLinuxDistributionToDownloadJava();
$extractDir = $this->getFullPath() . '/' . $linuxDistribution . '/' . $this->resource;

if ($this->isDownloadedFilesOk()) {
$folder = $this->getFolder($this->resource);
} else {
$downloadOk = $this->isDownloadedFilesOk();
if (!$downloadOk) {
$folder = $this->getEmptyFolder($this->resource);
/**
* Steps to update:
Expand Down Expand Up @@ -428,21 +435,51 @@ public function installJava(?bool $async = false): void {
$extractor = new $class($comporessedInternalFileName);
$extractor->extract($extractDir);
unlink($comporessedInternalFileName);
$this->writeAppSignature();
$downloadOk = true;
}

$this->appConfig->setAppValue('java_path', $extractDir . '/jdk-' . self::JAVA_URL_PATH_NAME . '-jre/bin/java');
if ($downloadOk) {
$this->writeAppSignature();
}
$this->removeDownloadProgress();
}

public function setDistro(string $distro): void {
$this->distro = $distro;
}

public function getInstallPath(): string {
switch ($this->resource) {
case 'java':
$path = $this->appConfig->getAppValue('java_path');
return substr($path, 0, -strlen('/bin/java'));
case 'jsignpdf':
$path = $this->appConfig->getAppValue('jsignpdf_jar_path');
return substr($path, 0, -strlen('/JSignPdf.jar'));
case 'pdftk':
$path = $this->appConfig->getAppValue('pdftk_path');
return substr($path, 0, -strlen('/pdftk.jar'));
case 'cfssl':
$path = $this->appConfig->getAppValue('cfssl_bin');
return substr($path, 0, -strlen('/cfssl'));
}
return '';
}

public function getSignatureFileName(): string {
$path[] = 'install-' . $this->architecture;
if ($this->resource === 'java') {
$path[] = $this->getLinuxDistributionToDownloadJava();
}
$path[] = $this->resource . '.json';
return implode('-', $path);
}

/**
* Return linux or alpine-linux
*/
private function getLinuxDistributionToDownloadJava(): string {
public function getLinuxDistributionToDownloadJava(): string {
if ($this->distro) {
return $this->distro;
}
Expand Down Expand Up @@ -479,9 +516,8 @@ public function installJSignPdf(?bool $async = false): void {
}
$extractDir = $this->getFullPath() . '/' . $this->resource;

if ($this->isDownloadedFilesOk()) {
$folder = $this->getFolder($this->resource);
} else {
$downloadOk = $this->isDownloadedFilesOk();
if (!$downloadOk) {
$folder = $this->getEmptyFolder($this->resource);
$compressedFileName = 'jsignpdf-' . JSignPdfHandler::VERSION . '.zip';
try {
Expand All @@ -499,11 +535,14 @@ public function installJSignPdf(?bool $async = false): void {
$zip = new ZIP($extractDir . '/' . $compressedFileName);
$zip->extract($extractDir);
unlink($extractDir . '/' . $compressedFileName);
$this->writeAppSignature();
$downloadOk = true;
}

$fullPath = $extractDir . '/jsignpdf-' . JSignPdfHandler::VERSION . '/JSignPdf.jar';
$this->appConfig->setAppValue('jsignpdf_jar_path', $fullPath);
if ($downloadOk) {
$this->writeAppSignature();
}
$this->removeDownloadProgress();
}

Expand All @@ -528,7 +567,8 @@ public function installPdftk(?bool $async = false): void {
return;
}

if ($this->isDownloadedFilesOk()) {
$downloadOk = $this->isDownloadedFilesOk();
if ($downloadOk) {
$folder = $this->getFolder($this->resource);
$file = $folder->getFile('pdftk.jar');
$fullPath = $this->getDataDir() . '/' . $this->getInternalPathOfFile($file);
Expand All @@ -545,10 +585,12 @@ public function installPdftk(?bool $async = false): void {
$hash = '59a28bed53b428595d165d52988bf4cf';

$this->download($url, 'pdftk', $fullPath, $hash);
$this->writeAppSignature();
}

$this->appConfig->setAppValue('pdftk_path', $fullPath);
if ($downloadOk) {
$this->writeAppSignature();
}
$this->removeDownloadProgress();
}

Expand Down Expand Up @@ -586,7 +628,8 @@ public function installCfssl(?bool $async = false): void {
}

private function installCfsslByArchitecture(string $architecture): void {
if ($this->isDownloadedFilesOk()) {
$downloadOk = $this->isDownloadedFilesOk();
if ($downloadOk) {
$folder = $this->getFolder($this->resource);
} else {
$folder = $this->getEmptyFolder($this->resource);
Expand All @@ -613,12 +656,15 @@ private function installCfsslByArchitecture(string $architecture): void {

chmod($fullPath, 0700);
}
$this->writeAppSignature();
$downloadOk = true;
}

$cfsslBinPath = $this->getDataDir() . '/' .
$this->getInternalPathOfFolder($folder) . '/cfssl';
$this->appConfig->setAppValue('cfssl_bin', $cfsslBinPath);
if ($downloadOk) {
$this->writeAppSignature();
}
}

public function uninstallCfssl(): void {
Expand Down
59 changes: 24 additions & 35 deletions lib/Service/Install/SignSetupService.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
use phpseclib\Crypt\RSA;
use phpseclib\File\X509;
Expand All @@ -34,6 +33,8 @@ class SignSetupService {
private string $resource;
private array $signatureData = [];
private bool $willUseLocalCert = false;
private string $signatureFileName = '';
private string $installPath = '';
private ?X509 $x509 = null;
private ?RSA $rsa = null;
public function __construct(
Expand Down Expand Up @@ -107,30 +108,45 @@ public function writeAppSignature(
) {
$this->architecture = $architecture;
$this->resource = $resource;
$appInfoDir = $this->getAppInfoDirectory();
try {
$iterator = $this->getFolderIterator($this->getInstallPath());
$iterator = $this->getFolderIterator($this->installPath);
$hashes = $this->generateHashes($iterator);
$signature = $this->createSignatureData($hashes);
$this->fileAccessHelper->file_put_contents(
$appInfoDir . '/install-' . $this->architecture . '-' . $this->resource . '.json',
$this->getFileName(),
json_encode($signature, JSON_PRETTY_PRINT)
);
} catch (NotFoundException $e) {
throw new \Exception(sprintf(
"Folder %s not found.\nIs necessary to run this command first: occ libresign:install --%s --architecture %s",
"Folder %s not found.\nIs necessary to run this command first: occ libresign:install --%s --architecture=%s",
$e->getMessage(),
$this->resource,
$this->architecture,
));
} catch (\Exception $e) {
$appInfoDir = $this->getAppInfoDirectory();
if (!$this->fileAccessHelper->is_writable($appInfoDir)) {
throw new \Exception($appInfoDir . ' is not writable. Original error: ' . $e->getMessage());
}
throw $e;
}
}

public function setInstallPath(string $installPath): self {
$this->installPath = $installPath;
return $this;
}

public function setSignatureFileName(string $signatureFileName): self {
$this->signatureFileName = $signatureFileName;
return $this;
}

private function getFileName(): string {
$appInfoDir = $this->getAppInfoDirectory();
return $appInfoDir . '/' . $this->signatureFileName;
}

protected function getAppInfoDirectory(): string {
$appInfoDir = realpath(__DIR__ . '/../../../appinfo');
$this->fileAccessHelper->assertDirectoryExists($appInfoDir);
Expand All @@ -153,9 +169,7 @@ private function getSignatureData(): array {
if (!empty($this->signatureData)) {
return $this->signatureData;
}
$appInfoDir = $this->getAppInfoDirectory();
$signaturePath = $appInfoDir . '/install-' . $this->architecture . '-' . $this->resource . '.json';
$content = $this->fileAccessHelper->file_get_contents($signaturePath);
$content = $this->fileAccessHelper->file_get_contents($this->getFileName());
$signatureData = null;

if (\is_string($content)) {
Expand Down Expand Up @@ -235,8 +249,7 @@ public function verify(string $architecture, $resource): array {
try {
$expectedHashes = $this->getHashesOfResource();
// Compare the list of files which are not identical
$installPath = $this->getInstallPath();
$currentInstanceHashes = $this->generateHashes($this->getFolderIterator($installPath), $installPath);
$currentInstanceHashes = $this->generateHashes($this->getFolderIterator($this->installPath), $this->installPath);
} catch (EmptySignatureDataException $th) {
return [
'EMPTY_SIGNATURE_DATA' => $th->getMessage(),
Expand Down Expand Up @@ -284,30 +297,6 @@ public function verify(string $architecture, $resource): array {
return $differenceArray;
}

private function getDataDir(): string {
$dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
return $dataDir;
}

/**
* @todo check a best solution to don't use reflection
*/
protected function getInternalPathOfFolder(ISimpleFolder $node): string {
$reflection = new \ReflectionClass($node);
$reflectionProperty = $reflection->getProperty('folder');
$reflectionProperty->setAccessible(true);
$folder = $reflectionProperty->getValue($node);
$path = $folder->getInternalPath();
return $path;
}

private function getInstallPath(): string {
$folder = $this->getDataDir() . '/' .
$this->getInternalPathOfFolder($this->appData->getFolder($this->architecture . '/' . $this->resource));
return $folder;
}


/**
* Enumerates all files belonging to the folder. Sensible defaults are excluded.
*
Expand Down Expand Up @@ -342,7 +331,7 @@ private function getFolderIterator(string $folderToIterate): \RecursiveIteratorI
private function generateHashes(\RecursiveIteratorIterator $iterator): array {
$hashes = [];

$baseDirectoryLength = \strlen($this->getInstallPath());
$baseDirectoryLength = \strlen($this->installPath);
foreach ($iterator as $filename => $data) {
/** @var \DirectoryIterator $data */
if ($data->isDir()) {
Expand Down
Loading

0 comments on commit 00a0ed9

Please sign in to comment.