Skip to content

Commit 48a426f

Browse files
committed
refactor(cfssl): manage process lifecycle via process manager
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 514a958 commit 48a426f

1 file changed

Lines changed: 45 additions & 21 deletions

File tree

lib/Handler/CertificateEngine/CfsslHandler.php

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use OCA\Libresign\Service\CertificatePolicyService;
2323
use OCA\Libresign\Service\Crl\CrlRevocationChecker;
2424
use OCA\Libresign\Service\Install\InstallService;
25+
use OCA\Libresign\Service\Process\ProcessManager;
26+
use OCA\Libresign\Vendor\Symfony\Component\Process\Process;
2527
use OCP\Files\AppData\IAppDataFactory;
2628
use OCP\IAppConfig;
2729
use OCP\IConfig;
@@ -39,6 +41,7 @@
3941
*/
4042
class CfsslHandler extends AEngineHandler implements IEngineHandler {
4143
public const CFSSL_URI = 'http://127.0.0.1:8888/api/v1/cfssl/';
44+
private const PROCESS_SOURCE = 'cfssl';
4245

4346
/** @var Client */
4447
protected $client;
@@ -58,6 +61,7 @@ public function __construct(
5861
protected CrlMapper $crlMapper,
5962
protected LoggerInterface $logger,
6063
CrlRevocationChecker $crlRevocationChecker,
64+
private ProcessManager $processManager,
6165
) {
6266
parent::__construct(
6367
$config,
@@ -245,10 +249,11 @@ private function gencert(): void {
245249
$configPath = $this->getCurrentConfigPath();
246250
$csrFile = $configPath . '/csr_server.json';
247251

248-
$cmd = escapeshellcmd($binary) . ' gencert -initca ' . escapeshellarg($csrFile);
249-
$output = shell_exec($cmd);
252+
$process = $this->createProcess([$binary, 'gencert', '-initca', $csrFile]);
253+
$process->run();
254+
$output = $process->getOutput();
250255

251-
if (!$output) {
256+
if (!$process->isSuccessful() || $output === '') {
252257
throw new \RuntimeException('cfssl without output.');
253258
}
254259

@@ -320,11 +325,26 @@ private function wakeUp(): void {
320325
throw new LibresignException('CFSSL not configured.');
321326
}
322327
$this->cfsslServerHandler->updateExpirity($this->getCaExpiryInDays());
323-
$cmd = 'nohup ' . $binary . ' serve -address=127.0.0.1 '
324-
. '-ca-key ' . $configPath . DIRECTORY_SEPARATOR . 'ca-key.pem '
325-
. '-ca ' . $configPath . DIRECTORY_SEPARATOR . 'ca.pem '
326-
. '-config ' . $configPath . DIRECTORY_SEPARATOR . 'config_server.json > /dev/null 2>&1 & echo $!';
327-
shell_exec($cmd);
328+
$process = $this->createProcess([
329+
$binary,
330+
'serve',
331+
'-address=127.0.0.1',
332+
'-ca-key', $configPath . DIRECTORY_SEPARATOR . 'ca-key.pem',
333+
'-ca', $configPath . DIRECTORY_SEPARATOR . 'ca.pem',
334+
'-config', $configPath . DIRECTORY_SEPARATOR . 'config_server.json',
335+
]);
336+
$process->setOptions(['create_new_console' => true]);
337+
$process->setTimeout(null);
338+
$process->disableOutput();
339+
$process->start();
340+
341+
$pid = (int)($process->getPid() ?? 0);
342+
if ($pid > 0) {
343+
$this->processManager->register(self::PROCESS_SOURCE, $pid, [
344+
'uri' => $this->getCfsslUri(),
345+
]);
346+
}
347+
328348
$loops = 0;
329349
while (!$this->portOpen() && $loops <= 4) {
330350
sleep(1);
@@ -349,17 +369,11 @@ private function portOpen(): bool {
349369
}
350370

351371
private function getServerPid(): int {
352-
$cmd = 'ps -eo pid,command|';
353-
$cmd .= 'grep "cfssl.*serve.*-address"|'
354-
. 'grep -v grep|'
355-
. 'grep -v defunct|'
356-
. 'sed -e "s/^[[:space:]]*//"|cut -d" " -f1';
357-
$output = shell_exec($cmd);
358-
if (!is_string($output)) {
359-
return 0;
360-
}
361-
$pid = trim($output);
362-
return (int)$pid;
372+
$uri = $this->getCfsslUri();
373+
return $this->processManager->findRunningPid(
374+
self::PROCESS_SOURCE,
375+
fn (array $entry): bool => ($entry['context']['uri'] ?? '') === $uri,
376+
);
363377
}
364378

365379
/**
@@ -381,6 +395,7 @@ private function stopIfRunning(): void {
381395
$pid = $this->getServerPid();
382396
if ($pid > 0) {
383397
exec($this->parseCommand('kill -9 ' . $pid));
398+
$this->processManager->unregister(self::PROCESS_SOURCE, $pid);
384399
}
385400
}
386401

@@ -452,8 +467,10 @@ private function checkBinaries(): array {
452467
->setTip('Run occ libresign:install --cfssl'),
453468
];
454469
}
455-
$version = shell_exec("$binary version");
456-
if (!is_string($version) || empty($version)) {
470+
$process = $this->createProcess([$binary, 'version']);
471+
$process->run();
472+
$version = $process->getOutput();
473+
if (!$process->isSuccessful() || empty($version)) {
457474
return [
458475
(new ConfigureCheckHelper())
459476
->setErrorMessage(sprintf(
@@ -502,6 +519,13 @@ private function checkBinaries(): array {
502519
return $return;
503520
}
504521

522+
/**
523+
* @param string[] $command
524+
*/
525+
protected function createProcess(array $command): Process {
526+
return new Process($command);
527+
}
528+
505529
/**
506530
* Get Authority Key Identifier from certificate (needed for CFSSL revocation)
507531
*

0 commit comments

Comments
 (0)