refactor: use temp file for client certificate

This commit is contained in:
Maël Gangloff 2025-02-24 10:31:46 +01:00
parent 7615c81d6b
commit 77e7d6cdf8
No known key found for this signature in database
GPG Key ID: 11FDC81C24A7F629
3 changed files with 57 additions and 61 deletions

View File

@ -79,45 +79,12 @@ class ConnectorController extends AbstractController
throw new BadRequestHttpException('Provider not found'); throw new BadRequestHttpException('Provider not found');
} }
if (ConnectorProvider::EPP === $provider) { /** @var AbstractProvider $providerClient */
$directory = sprintf('../var/epp-certificates/%s/', $connector->getId()); $providerClient = $this->locator->get($provider->getConnectorProvider());
$authData = $providerClient->verifyAuthData($connector->getAuthData());
$connector->setAuthData($authData);
$filesystem = new Filesystem(); $providerClient->authenticate($authData);
$filesystem->mkdir($directory, 0755);
$authData = $connector->getAuthData();
if (!isset($authData['certificate_pem'], $authData['certificate_key'])) {
throw new BadRequestHttpException('EPP certificates are required');
}
$pemPath = $directory.'client.pem';
$keyPath = $directory.'client.key';
$filesystem->dumpFile($pemPath, urldecode($authData['certificate_pem']));
$filesystem->dumpFile($keyPath, urldecode($authData['certificate_key']));
$connector->setAuthData([...$authData, 'files' => ['pem' => $pemPath, '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(),

View File

@ -44,11 +44,9 @@ final class EppClientProviderDto extends DefaultProviderDto
])] ])]
public array $objURI = []; public array $objURI = [];
#[Assert\NotBlank] public ?string $certificate_pem = null;
public string $certificate_pem;
#[Assert\NotBlank] public ?string $certificate_key = null;
public string $certificate_key;
public ?EppClientProviderFilesDto $files; public ?EppClientProviderFilesDto $files;
} }

View File

@ -15,6 +15,7 @@ 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,6 +26,9 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
protected string $dtoClass = EppClientProviderDto::class; protected string $dtoClass = EppClientProviderDto::class;
private eppConnection $eppClient; private eppConnection $eppClient;
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,
@ -32,11 +36,12 @@ 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
{ {
$this->connect($this->authData); $this->connect();
$this->eppClient->login(); $this->eppClient->login();
$this->eppClient->request(new eppHelloRequest()); $this->eppClient->request(new eppHelloRequest());
@ -50,7 +55,7 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
*/ */
public function orderDomain(Domain $domain, bool $dryRun): void public function orderDomain(Domain $domain, bool $dryRun): void
{ {
$this->connect($this->authData); $this->connect();
$d = new eppDomain($domain->getLdhName()); $d = new eppDomain($domain->getLdhName());
$d->setRegistrant($this->authData['domain']['registrant']); $d->setRegistrant($this->authData['domain']['registrant']);
@ -67,7 +72,7 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
} }
$this->eppClient->logout(); $this->eppClient->logout();
$this->eppClient->disconnect(); $this->disconnect();
} }
/** /**
@ -106,7 +111,7 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
*/ */
public function checkDomains(string ...$domains): array public function checkDomains(string ...$domains): array
{ {
$this->connect($this->authData); $this->connect();
$this->eppClient->login(); $this->eppClient->login();
$check = new eppCheckDomainRequest($domains); $check = new eppCheckDomainRequest($domains);
@ -129,27 +134,53 @@ class EppClientProvider extends AbstractProvider implements CheckDomainProviderI
/** /**
* @throws eppException * @throws eppException
*/ */
private function connect(array $authData): void private function connect(): void
{ {
$conn = new eppConnection(false, null); $conn = new eppConnection(false, null);
$conn->setHostname($authData['hostname']); $conn->setHostname($this->authData['hostname']);
$conn->setVersion($authData['version']); $conn->setVersion($this->authData['version']);
$conn->setLanguage($authData['language']); $conn->setLanguage($this->authData['language']);
$conn->setPort($authData['port']); $conn->setPort($this->authData['port']);
$conn->setUsername($authData['auth']['username']); $conn->setUsername($this->authData['auth']['username']);
$conn->setPassword($authData['auth']['password']); $conn->setPassword($this->authData['auth']['password']);
$conn->setSslContext(stream_context_create(['ssl' => [
...$authData['auth']['ssl'],
'local_cert' => $authData['files']['pem'],
'local_pk' => $authData['files']['key'],
]]));
$conn->setXpathExtensions($authData['xPathURI']); if (isset($this->authData['certificate_pem'], $this->authData['certificate_key'])) {
$conn->setExtensions($authData['extURI']); $this->file_certificate_pem = $this->filesystem->tempnam(sys_get_temp_dir(), 'epp_client_', '.pem');
$conn->setServices($authData['objURI']); $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' => [
...$this->authData['auth']['ssl'],
'local_cert' => $this->file_certificate_pem,
'local_pk' => $this->file_certificate_key,
]]));
} else {
unset($this->authData['auth']['ssl']['local_cert'], $this->authData['auth']['ssl']['local_pk']);
$conn->setSslContext(stream_context_create(['ssl' => $this->authData['auth']['ssl']]));
}
$conn->setXpathExtensions($this->authData['xPathURI']);
$conn->setExtensions($this->authData['extURI']);
$conn->setServices($this->authData['objURI']);
$conn->connect(); $conn->connect();
$this->eppClient = $conn; $this->eppClient = $conn;
} }
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();
}
public function __destruct()
{
$this->disconnect();
}
} }