Skip to content
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
2 changes: 0 additions & 2 deletions lib/Controller/PageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ public function index(): TemplateResponse {
$response = new TemplateResponse(Application::APP_ID, 'main');

$policy = new ContentSecurityPolicy();
$policy->allowEvalScript(true);
$policy->addAllowedFrameDomain('\'self\'');
$policy->addAllowedWorkerSrcDomain("'self'");
$response->setContentSecurityPolicy($policy);
Expand Down Expand Up @@ -387,7 +386,6 @@ public function sign(string $uuid): TemplateResponse {
$response = new TemplateResponse(Application::APP_ID, 'external', [], TemplateResponse::RENDER_AS_BASE);

$policy = new ContentSecurityPolicy();
$policy->allowEvalScript(true);
$policy->addAllowedWorkerSrcDomain("'self'");
$response->setContentSecurityPolicy($policy);

Expand Down
3 changes: 1 addition & 2 deletions lib/Handler/CertificateEngine/OpenSslHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,7 @@ private function buildCaCertificateConfig(): array {
],
'v3_ca' => [
'basicConstraints' => 'critical, CA:TRUE, pathlen:1',
'keyUsage' => 'critical, digitalSignature, keyCertSign',
'extendedKeyUsage' => 'clientAuth, emailProtection',
'keyUsage' => 'critical, digitalSignature, keyCertSign, cRLSign',
'subjectAltName' => $this->getSubjectAltNames(),
'authorityKeyIdentifier' => 'keyid',
'subjectKeyIdentifier' => 'hash',
Expand Down
1 change: 0 additions & 1 deletion lib/Middleware/InjectionMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ public function afterException($controller, $methodName, \Exception $exception):
);

$policy = new ContentSecurityPolicy();
$policy->allowEvalScript(true);
$policy->addAllowedFrameDomain('\'self\'');
$response->setContentSecurityPolicy($policy);
return $response;
Expand Down
8 changes: 7 additions & 1 deletion lib/Service/Crl/CrlRevocationChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,13 @@ private function generateLocalCrl(string $crlUrl): ?string {
$this->logger->debug('CRL URL does not match expected pattern', ['url' => $crlUrl, 'pattern' => $pattern]);
return null;
} catch (\Exception $e) {
$this->logger->warning('Failed to generate local CRL: ' . $e->getMessage());
if ($e instanceof \RuntimeException && str_starts_with($e->getMessage(), 'Config path does not exist for instanceId:')) {
$this->logger->debug('Skipping local CRL generation because source PKI config path is missing', [
'reason' => $e->getMessage(),
]);
} else {
$this->logger->warning('Failed to generate local CRL: ' . $e->getMessage());
}
return null;
}
}
Expand Down
15 changes: 12 additions & 3 deletions lib/Service/Crl/CrlService.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,18 @@ public function generateCrlDer(string $instanceId, int $generation, string $engi

return $engine->generateCrlDer($revokedCertificates, $instanceId, $generation, $crlNumber);
} catch (\Throwable $e) {
$this->logger->error('Failed to generate CRL', [
'exception' => $e,
]);
if ($e instanceof \RuntimeException && str_starts_with($e->getMessage(), 'Config path does not exist for instanceId:')) {
$this->logger->debug('Skipping local CRL generation because source PKI config path is missing', [
'instanceId' => $instanceId,
'generation' => $generation,
'engineType' => $engineType,
'reason' => $e->getMessage(),
]);
} else {
$this->logger->error('Failed to generate CRL', [
'exception' => $e,
]);
}
throw $e;
}
}
Expand Down
7 changes: 6 additions & 1 deletion lib/Service/Crl/Ldap/LdapCrlDownloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ public function __construct(
}

public function isLdapUrl(string $url): bool {
$scheme = strtolower(parse_url($url, PHP_URL_SCHEME) ?? '');
$scheme = parse_url($url, PHP_URL_SCHEME);
if (!is_string($scheme)) {
return preg_match('/^ldaps?:\/\//i', trim($url)) === 1;
}

$scheme = strtolower($scheme);
return in_array($scheme, ['ldap', 'ldaps'], true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ public function testLoadFileUuidWithEmptyUuid(): void {
*/
public function testLoadFileUuidWhenFileNotFound(): void {
$user = $this->createAccount('username', 'password');
$user->setEMailAddress('person@test.coop');
$file = $this->requestSignFile([
'file' => ['base64' => base64_encode(file_get_contents(__DIR__ . '/../../fixtures/pdfs/small_valid.pdf'))],
'name' => 'test',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ public function testGenerateCrlDerWithRevokedCertificates(array $certificates):
$verifyResult = implode("\n", $verifyOutput);

$this->assertEquals(0, $verifyExitCode, 'CRL signature verification should succeed. Output: ' . $verifyResult);
$this->assertStringContainsString('verify OK', $verifyResult, 'CRL signature should be valid');
$this->assertStringNotContainsString('unable to get issuer certificate', strtolower($verifyResult), 'CRL verification should use the provided CA certificate');

} finally {
if (file_exists($tempCrlFile)) {
Expand Down
1 change: 1 addition & 0 deletions tests/php/Unit/Service/Crl/Ldap/LdapCrlDownloaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static function dataProviderIsLdapUrl(): array {
'ldap lowercase' => ['ldap://ldap.example.com/cn=CRL,o=Org', true],
'ldaps lowercase' => ['ldaps://ldap.example.com/cn=CRL,o=Org', true],
'LDAP uppercase' => ['LDAP://ldap.example.com/cn=CRL,o=Org', true],
'ldap hostless URL from AD CDP' => ['ldap:///CN=Example%20Issuing%20CA1,CN=CDP,CN=Public%20Key%20Services,DC=example,DC=local?certificateRevocationList?base?objectClass=cRLDistributionPoint', true],
'http not ldap' => ['http://crl.example.com/crl.crl', false],
'https not ldap' => ['https://crl.example.com/crl.crl', false],
'empty string' => ['', false],
Expand Down
48 changes: 48 additions & 0 deletions tests/php/Unit/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,48 @@ public static function setUpBeforeClass(): void {

public function setUp(): void {
static::getMockAppConfig();
$this->suppressMailDelivery();
$this->mockConfig([
'dav' => [
'enableDefaultContact' => 'false',
],
]);
$this->ensureDavDefaultContactFixture();
$this->getBinariesFromCache();
if ($this->iDependOnOthers() || !$this->IsDatabaseAccessAllowed()) {
return;
}
$this->cleanDatabase();
}

private function suppressMailDelivery(): void {
$mailService = $this->createMock(\OCA\Libresign\Service\MailService::class);
$mailService->method('notifyUnsignedUser')->willReturnCallback(static function (): void {
});
$mailService->method('notifySignDataUpdated')->willReturnCallback(static function (): void {
});
$mailService->method('notifySignedUser')->willReturnCallback(static function (): void {
});
$mailService->method('notifyCanceledRequest')->willReturnCallback(static function (): void {
});
$mailService->method('sendCodeToSign')->willReturnCallback(static function (): void {
});
$this->overwriteService(\OCA\Libresign\Service\MailService::class, $mailService);
}

private function ensureDavDefaultContactFixture(): void {
$instanceId = \OC_Util::getInstanceId();
$dir = '../../data/appdata_' . $instanceId . '/dav/defaultContact';
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}

$file = $dir . '/defaultContact.vcf';
if (!file_exists($file)) {
file_put_contents($file, "BEGIN:VCARD\nVERSION:3.0\nFN:Default Contact\nEND:VCARD\n");
}
}

public function tearDown(): void {
$this->backupBinaries();
if ($this->haveDependents() || !$this->IsDatabaseAccessAllowed()) {
Expand Down Expand Up @@ -311,6 +346,19 @@ public function requestSignFile($data): File {
$appConfig->setValueString(Application::APP_ID, 'organizationalUnit', 'organizationalUnit');
$appConfig->setValueString(Application::APP_ID, 'cfsslUri', self::$server->getServerRoot() . '/api/v1/cfssl/');

$mailService = $this->createMock(\OCA\Libresign\Service\MailService::class);
$mailService->method('notifyUnsignedUser')->willReturnCallback(static function (): void {
});
$mailService->method('notifySignDataUpdated')->willReturnCallback(static function (): void {
});
$mailService->method('notifySignedUser')->willReturnCallback(static function (): void {
});
$mailService->method('notifyCanceledRequest')->willReturnCallback(static function (): void {
});
$mailService->method('sendCodeToSign')->willReturnCallback(static function (): void {
});
$this->overwriteService(\OCA\Libresign\Service\MailService::class, $mailService);

if (!isset($data['settings'])) {
$data['settings']['separator'] = '_';
$data['settings']['folderPatterns'][] = [
Expand Down
Loading