feat: store EPP keys in files

This commit is contained in:
Maël Gangloff
2025-02-24 23:19:11 +01:00
parent 7b0c3f4c07
commit 9c56dec069
6 changed files with 50 additions and 56 deletions

View File

@@ -109,7 +109,7 @@ export default function EppConnectorForm() {
... ...
-----END PRIVATE KEY-----`}/> -----END PRIVATE KEY-----`}/>
</Form.Item> </Form.Item>
<Form.Item name={['authData', 'ssl', 'passphrase']}> <Form.Item name={['authData', 'auth', 'ssl', 'passphrase']}>
<Input placeholder={t`Private key passphrase (optional)`} autoComplete='off'/> <Input placeholder={t`Private key passphrase (optional)`} autoComplete='off'/>
</Form.Item> </Form.Item>
</Col> </Col>
@@ -122,7 +122,7 @@ export default function EppConnectorForm() {
<Form.Item <Form.Item
initialValue={true} initialValue={true}
help={t`Verify peer`} help={t`Verify peer`}
name={['authData', 'ssl', 'verify_peer']} name={['authData', 'auth', 'ssl', 'verify_peer']}
> >
<Switch/> <Switch/>
</Form.Item> </Form.Item>
@@ -131,7 +131,7 @@ export default function EppConnectorForm() {
<Form.Item <Form.Item
initialValue={true} initialValue={true}
help={t`Verify peer name`} help={t`Verify peer name`}
name={['authData', 'ssl', 'verify_peer_name']} name={['authData', 'auth', 'ssl', 'verify_peer_name']}
> >
<Switch/> <Switch/>
</Form.Item> </Form.Item>
@@ -140,7 +140,7 @@ export default function EppConnectorForm() {
<Form.Item <Form.Item
initialValue={false} initialValue={false}
help={t`Allow self-signed certificates`} help={t`Allow self-signed certificates`}
name={['authData', 'ssl', 'allow_self_signed']} name={['authData', 'auth', 'ssl', 'allow_self_signed']}
> >
<Switch/> <Switch/>
</Form.Item> </Form.Item>

View File

@@ -79,22 +79,47 @@ class ConnectorController extends AbstractController
throw new BadRequestHttpException('Provider not found'); throw new BadRequestHttpException('Provider not found');
} }
/** @var AbstractProvider $providerClient */ if (ConnectorProvider::EPP === $provider) {
$providerClient = $this->locator->get($provider->getConnectorProvider()); $filesystem = new Filesystem();
$authData = $providerClient->verifyAuthData($connector->getAuthData()); $directory = sprintf('%s/%s/', EppClientProvider::EPP_CERTIFICATES_PATH, $connector->getId());
$connector->setAuthData($authData); $authData = $connector->getAuthData();
$providerClient->authenticate($authData); unset($authData['file_certificate_pem'], $authData['file_certificate_key']); // Prevent alteration from user
if (isset($authData['certificate_pem'], $authData['certificate_key'])) {
$pemPath = $directory.'client.pem';
$keyPath = $directory.'client.key';
$filesystem->mkdir($directory, 0755);
$filesystem->dumpFile($pemPath, $authData['certificate_pem']);
$filesystem->dumpFile($keyPath, $authData['certificate_key']);
$connector->setAuthData([...$authData, 'file_certificate_pem' => $pemPath, 'file_certificate_key' => $keyPath]);
}
/** @var AbstractProvider $providerClient */
$providerClient = $this->locator->get($provider->getConnectorProvider());
$authData = $providerClient->verifyAuthData($connector->getAuthData());
$connector->setAuthData($authData);
try {
$providerClient->authenticate($authData);
} catch (\Throwable $exception) {
$filesystem->remove($directory);
throw $exception;
}
} else {
/** @var AbstractProvider $providerClient */
$providerClient = $this->locator->get($provider->getConnectorProvider());
$authData = $providerClient->verifyAuthData($connector->getAuthData());
$connector->setAuthData($authData);
$providerClient->authenticate($authData);
}
$this->logger->info('User {username} authentication data with the {provider} provider has been validated.', [ $this->logger->info('User {username} authentication data with the {provider} provider has been validated.', [
'username' => $user->getUserIdentifier(), 'username' => $user->getUserIdentifier(),
'provider' => $provider->value, 'provider' => $provider->value,
]); ]);
$this->logger->info('The new API connector requested by {username} has been successfully registered.', [
'username' => $user->getUserIdentifier(),
]);
$connector->setCreatedAt(new \DateTimeImmutable('now')); $connector->setCreatedAt(new \DateTimeImmutable('now'));
$this->em->persist($connector); $this->em->persist($connector);
$this->em->flush(); $this->em->flush();

View File

@@ -6,15 +6,15 @@ final class EppClientProviderAuthSSLDto
{ {
public ?string $peer_name = null; public ?string $peer_name = null;
public ?bool $verify_peer = null; public bool $verify_peer = true;
public ?bool $verify_peer_name = null; public bool $verify_peer_name = true;
public ?bool $allow_self_signed = null; public bool $allow_self_signed = false;
public ?int $verify_depth = null; public ?int $verify_depth = null;
public ?string $passphrase = null; public ?string $passphrase = null;
public ?bool $disable_compression = null; public bool $disable_compression = false;
} }

View File

@@ -44,9 +44,7 @@ final class EppClientProviderDto extends DefaultProviderDto
])] ])]
public array $objURI = []; public array $objURI = [];
public ?string $certificate_pem = null; public ?string $file_certificate_pem = null;
public ?string $certificate_key = null; public ?string $file_certificate_key = null;
public ?EppClientProviderFilesDto $files;
} }

View File

@@ -1,14 +0,0 @@
<?php
namespace App\Dto\Connector;
use Symfony\Component\Validator\Constraints as Assert;
final class EppClientProviderFilesDto
{
#[Assert\NotBlank]
public string $pem;
#[Assert\NotBlank]
public string $key;
}

View File

@@ -15,7 +15,6 @@ use Metaregistrar\EPP\eppHelloRequest;
use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface; use Psr\Cache\CacheItemPoolInterface;
use Psr\Cache\InvalidArgumentException; use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -25,10 +24,7 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
public const EPP_CERTIFICATES_PATH = '../var/epp-certificates/'; public const EPP_CERTIFICATES_PATH = '../var/epp-certificates/';
protected string $dtoClass = EppClientProviderDto::class; protected string $dtoClass = EppClientProviderDto::class;
private eppConnection $eppClient; private ?eppConnection $eppClient = null;
private readonly Filesystem $filesystem;
private ?string $file_certificate_pem = null;
private ?string $file_certificate_key = null;
public function __construct( public function __construct(
CacheItemPoolInterface $cacheItemPool, CacheItemPoolInterface $cacheItemPool,
@@ -36,7 +32,6 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
ValidatorInterface $validator, ValidatorInterface $validator,
) { ) {
parent::__construct($cacheItemPool, $serializer, $validator); parent::__construct($cacheItemPool, $serializer, $validator);
$this->filesystem = new Filesystem();
} }
protected function assertAuthentication(): void protected function assertAuthentication(): void
@@ -136,7 +131,7 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
*/ */
private function connect(): void private function connect(): void
{ {
if ($this->eppClient->isConnected()) { if ($this->eppClient && $this->eppClient->isConnected()) {
return; return;
} }
@@ -149,20 +144,14 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
$conn->setUsername($this->authData['auth']['username']); $conn->setUsername($this->authData['auth']['username']);
$conn->setPassword($this->authData['auth']['password']); $conn->setPassword($this->authData['auth']['password']);
if (isset($this->authData['certificate_pem'], $this->authData['certificate_key'])) { if (isset($this->authData['file_certificate_pem'], $this->authData['file_certificate_key'])) {
$this->file_certificate_pem = $this->filesystem->tempnam(sys_get_temp_dir(), 'epp_client_', '.pem');
$this->filesystem->dumpFile($this->file_certificate_pem, urldecode($this->authData['certificate_pem']));
$this->file_certificate_key = $this->filesystem->tempnam(sys_get_temp_dir(), 'epp_client_', '.key');
$this->filesystem->dumpFile($this->file_certificate_key, urldecode($this->authData['certificate_key']));
$conn->setSslContext(stream_context_create(['ssl' => [ $conn->setSslContext(stream_context_create(['ssl' => [
...$this->authData['auth']['ssl'], ...$this->authData['auth']['ssl'],
'local_cert' => $this->file_certificate_pem, 'local_cert' => $this->authData['file_certificate_pem'],
'local_pk' => $this->file_certificate_key, 'local_pk' => $this->authData['file_certificate_key'],
]])); ]]));
} else { } else {
unset($this->authData['auth']['ssl']['local_cert'], $this->authData['auth']['ssl']['local_pk']); unset($this->authData['file_certificate_pem'], $this->authData['file_certificate_key']);
$conn->setSslContext(stream_context_create(['ssl' => $this->authData['auth']['ssl']])); $conn->setSslContext(stream_context_create(['ssl' => $this->authData['auth']['ssl']]));
} }
@@ -176,10 +165,6 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
private function disconnect(): void private function disconnect(): void
{ {
if (isset($this->authData['certificate_pem'], $this->authData['certificate_key'])) {
$this->filesystem->remove($this->file_certificate_pem);
$this->filesystem->remove($this->file_certificate_key);
}
$this->eppClient->disconnect(); $this->eppClient->disconnect();
} }