Skip to content

Commit 4d7ec53

Browse files
authored
Merge pull request #6980 from LibreSign/hotfix/6977-fix-ca-config-loss
hotfix: 6977 fix ca config loss
2 parents 716f9fe + 5cec074 commit 4d7ec53

File tree

3 files changed

+377
-34
lines changed

3 files changed

+377
-34
lines changed

lib/Migration/DeleteOldBinaries.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class DeleteOldBinaries implements IRepairStep {
4545
'jsignpdf',
4646
'pdftk',
4747
],
48+
'pki',
4849
'openssl_config',
4950
'cfssl_config',
5051
'unauthenticated',

lib/Migration/Version13000Date20251031165700.php

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
namespace OCA\Libresign\Migration;
1111

1212
use Closure;
13+
use OC\DB\Exceptions\DbalException;
1314
use OCA\Libresign\AppInfo\Application;
1415
use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory;
1516
use OCA\Libresign\Service\CaIdentifierService;
16-
use OCA\Libresign\Service\Install\InstallService;
1717
use OCP\DB\ISchemaWrapper;
1818
use OCP\DB\QueryBuilder\IQueryBuilder;
1919
use OCP\DB\Types;
@@ -35,7 +35,6 @@ public function __construct(
3535
private IAppConfig $appConfig,
3636
private CertificateEngineFactory $certificateEngineFactory,
3737
private CaIdentifierService $caIdentifierService,
38-
private InstallService $installService,
3938
private IDBConnection $connection,
4039
private IAppDataFactory $appDataFactory,
4140
private LoggerInterface $logger,
@@ -53,7 +52,6 @@ public function __construct(
5352
#[Override]
5453
public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
5554
$this->convertRootCertOuStringToArray();
56-
$this->addConfigPathToOpenSsl();
5755
$this->backupCrlDataToDisk();
5856
}
5957

@@ -130,18 +128,6 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array
130128
$this->populateCrlInstanceAndGeneration();
131129
}
132130

133-
private function addConfigPathToOpenSsl(): void {
134-
$engineName = $this->appConfig->getValueString(Application::APP_ID, 'certificate_engine', '');
135-
if ($engineName !== 'openssl') {
136-
return;
137-
}
138-
$engine = $this->certificateEngineFactory->getEngine();
139-
$configPath = $this->appConfig->getValueString(Application::APP_ID, 'config_path', '');
140-
if (empty($configPath)) {
141-
$engine->setConfigPath($engine->getCurrentConfigPath());
142-
}
143-
}
144-
145131
private function migrateToNewestConfigFormat(): void {
146132
$dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
147133
$rootPath = $dataDir . '/appdata_' . $this->config->getSystemValue('instanceid') . '/libresign/';
@@ -156,7 +142,6 @@ private function migrateToNewestConfigFormat(): void {
156142
$originalCaId = $this->caIdentifierService->generateCaId($engineName);
157143
}
158144
}
159-
$generatedNewCaId = false;
160145

161146
$engines = ['o' => 'openssl', 'c' => 'cfssl'];
162147
foreach ($engines as $engineType => $engineName) {
@@ -166,38 +151,59 @@ private function migrateToNewestConfigFormat(): void {
166151

167152
$engine = $this->certificateEngineFactory->getEngine($engineName);
168153

169-
if (empty($originalCaId) || !str_ends_with($originalCaId, '-e:' . $engineType)) {
170-
$generatedNewCaId = true;
154+
// Generate ca_id if needed, but don't increment counter unnecessarily
155+
if (empty($originalCaId) || !str_ends_with($originalCaId, '_e:' . $engineType)) {
171156
$this->caIdentifierService->generateCaId($engineName);
172157
}
173158

174159
$this->appConfig->deleteKey(Application::APP_ID, 'config_path');
175160
$configPath = $engine->getCurrentConfigPath();
176161
$configFiles = glob($rootPath . $engineName . '_config/*');
177162

178-
if (!empty($configFiles) && empty(glob($configPath . '/*'))) {
179-
foreach ($configFiles as $file) {
180-
if (is_file($file)) {
181-
copy($file, $configPath . '/' . basename($file));
163+
// Copy files only if destination doesn't have essential CA files
164+
if (!empty($configFiles)) {
165+
$destHasCaPem = file_exists($configPath . '/ca.pem');
166+
$destHasCaKey = file_exists($configPath . '/ca-key.pem');
167+
168+
if (!$destHasCaPem || !$destHasCaKey) {
169+
foreach ($configFiles as $file) {
170+
if (is_file($file)) {
171+
$destFile = $configPath . '/' . basename($file);
172+
if (!file_exists($destFile)) {
173+
copy($file, $destFile);
174+
}
175+
}
182176
}
183177
}
184178
}
185179

186-
if (!empty($configFiles)) {
187-
foreach ($configFiles as $file) {
188-
if (is_file($file)) {
189-
unlink($file);
180+
// Only delete source directory if destination has both essential CA files
181+
$destHasCaPem = file_exists($configPath . '/ca.pem');
182+
$destHasCaKey = file_exists($configPath . '/ca-key.pem');
183+
184+
if ($destHasCaPem && $destHasCaKey) {
185+
if (!empty($configFiles)) {
186+
foreach ($configFiles as $file) {
187+
if (is_file($file)) {
188+
@unlink($file);
189+
}
190190
}
191191
}
192-
}
193-
if (is_dir($rootPath . $engineName . '_config')) {
194-
rmdir($rootPath . $engineName . '_config');
192+
if (is_dir($rootPath . $engineName . '_config')) {
193+
@rmdir($rootPath . $engineName . '_config');
194+
}
195+
} else {
196+
// Log warning if we couldn't migrate successfully
197+
$this->logger->warning(
198+
'Migration could not verify CA files in destination directory. Old directory preserved.',
199+
[
200+
'engine' => $engineName,
201+
'source' => $rootPath . $engineName . '_config',
202+
'destination' => $configPath,
203+
]
204+
);
195205
}
196206
}
197-
198-
if ($generatedNewCaId && $originalCaId) {
199-
$this->appConfig->setValueString(Application::APP_ID, 'ca_id', $originalCaId);
200-
}
201207
}
202208

203209
private function convertRootCertOuStringToArray(): void {
@@ -374,7 +380,10 @@ private function restoreCrlDataFromDisk(): void {
374380

375381
fclose($handle);
376382

377-
$file->delete();
383+
try {
384+
$file->delete();
385+
} catch (DbalException $e) {
386+
}
378387

379388
} catch (\Exception $e) {
380389
$this->logger->error('Error restoring CRL data from disk during migration: ' . $e->getMessage(), ['exception' => $e]);

0 commit comments

Comments
 (0)