From 73093c1dd80b0767943f4596dbabc4d0d3e45c38 Mon Sep 17 00:00:00 2001 From: Adam Shepherd <665-AdamPS@users.noreply.drupalcode.org> Date: Sat, 6 May 2023 15:14:28 +0100 Subject: [PATCH] Issue #3351129 by AdamPS: Safeguard transport DSN --- src/Plugin/MailerTransport/DsnTransport.php | 2 +- src/ReplacementSendmailTransportFactory.php | 37 +++++++++++++++++++++ src/TransportFactoryManager.php | 7 ++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/ReplacementSendmailTransportFactory.php diff --git a/src/Plugin/MailerTransport/DsnTransport.php b/src/Plugin/MailerTransport/DsnTransport.php index 872665d3..b1de99ce 100644 --- a/src/Plugin/MailerTransport/DsnTransport.php +++ b/src/Plugin/MailerTransport/DsnTransport.php @@ -57,7 +57,7 @@ class DsnTransport extends TransportBase { Transport::fromDsn($dsn); } catch (\Exception $e) { - $form_state->setErrorByName('dsn', $this->t('Invalid DSN.')); + $form_state->setErrorByName('dsn', $this->t('Invalid DSN: @message', ['@message' => $e->getMessage()])); } } diff --git a/src/ReplacementSendmailTransportFactory.php b/src/ReplacementSendmailTransportFactory.php new file mode 100644 index 00000000..b256dacc --- /dev/null +++ b/src/ReplacementSendmailTransportFactory.php @@ -0,0 +1,37 @@ +<?php + +namespace Drupal\symfony_mailer; + +use Drupal\Core\Site\Settings; +use Symfony\Component\Mailer\Transport\AbstractTransportFactory; +use Symfony\Component\Mailer\Transport\Dsn; +use Symfony\Component\Mailer\Transport\SendmailTransportFactory; +use Symfony\Component\Mailer\Transport\TransportInterface; + +/** + * Provides a replacement sendmail transport factory that checks the command. + */ +final class ReplacementSendmailTransportFactory extends AbstractTransportFactory { + + /** + * {@inheritdoc} + */ + public function create(Dsn $dsn): TransportInterface { + if ($command = $dsn->getOption('command')) { + $commands = Settings::get('mailer_sendmail_commands', []); + if (!in_array($command, $commands)) { + throw new \RuntimeException("Unsafe sendmail command {$command}"); + } + } + + return (new SendmailTransportFactory())->create($dsn); + } + + /** + * {@inheritdoc} + */ + protected function getSupportedSchemes(): array { + return ['sendmail', 'sendmail+smtp']; + } + +} diff --git a/src/TransportFactoryManager.php b/src/TransportFactoryManager.php index 7602e489..0cb3268b 100644 --- a/src/TransportFactoryManager.php +++ b/src/TransportFactoryManager.php @@ -3,6 +3,7 @@ namespace Drupal\symfony_mailer; use Symfony\Component\Mailer\Transport; +use Symfony\Component\Mailer\Transport\SendmailTransportFactory; use Symfony\Component\Mailer\Transport\TransportFactoryInterface; /** @@ -22,6 +23,12 @@ class TransportFactoryManager implements TransportFactoryManagerInterface { */ public function __construct() { $this->factories = iterator_to_array(Transport::getDefaultFactories()); + + // Replace the sendmail transport factory with our own implementation. + $this->factories = array_filter($this->factories, function ($factory) { + return !($factory instanceof SendmailTransportFactory); + }); + $this->addFactory(new ReplacementSendmailTransportFactory()); } /** -- GitLab