diff --git a/changelog.d/17849.feature b/changelog.d/17849.feature new file mode 100644 index 0000000000..4de580f9ed --- /dev/null +++ b/changelog.d/17849.feature @@ -0,0 +1 @@ +Added the `email.tlsname` config option. This allows specifying the domain name used to validate the SMTP server's TLS certificate separately from the `email.smtp_host` to connect to. diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md index 47e3ef1287..2059525841 100644 --- a/docs/usage/configuration/config_documentation.md +++ b/docs/usage/configuration/config_documentation.md @@ -673,8 +673,9 @@ This setting has the following sub-options: TLS via STARTTLS *if the SMTP server supports it*. If this option is set, Synapse will refuse to connect unless the server supports STARTTLS. * `enable_tls`: By default, if the server supports TLS, it will be used, and the server - must present a certificate that is valid for 'smtp_host'. If this option + must present a certificate that is valid for `tlsname`. If this option is set to false, TLS will not be used. +* `tlsname`: The domain name the SMTP server's TLS certificate must be valid for, defaulting to `smtp_host`. * `notif_from`: defines the "From" address to use when sending emails. It must be set if email sending is enabled. The placeholder '%(app)s' will be replaced by the application name, which is normally set in `app_name`, but may be overridden by the @@ -741,6 +742,7 @@ email: force_tls: true require_transport_security: true enable_tls: false + tlsname: mail.server.example.com notif_from: "Your Friendly %(app)s homeserver " app_name: my_branded_matrix_server enable_notifs: true diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py index 8033fa2e52..c3a3e05a82 100644 --- a/synapse/config/emailconfig.py +++ b/synapse/config/emailconfig.py @@ -110,6 +110,7 @@ class EmailConfig(Config): raise ConfigError( "email.require_transport_security requires email.enable_tls to be true" ) + self.email_tlsname = email_config.get("tlsname", None) if "app_name" in email_config: self.email_app_name = email_config["app_name"] diff --git a/synapse/handlers/send_email.py b/synapse/handlers/send_email.py index 70cdb0721c..bfb882daa7 100644 --- a/synapse/handlers/send_email.py +++ b/synapse/handlers/send_email.py @@ -71,6 +71,7 @@ async def _sendmail( require_tls: bool = False, enable_tls: bool = True, force_tls: bool = False, + tlsname: Optional[str] = None, ) -> None: """A simple wrapper around ESMTPSenderFactory, to allow substitution in tests @@ -88,9 +89,13 @@ async def _sendmail( enable_tls: True to enable STARTTLS. If this is False and require_tls is True, the request will fail. force_tls: True to enable Implicit TLS. + tlsname: the domain name expected as the TLS certificate's commonname, + defaults to smtphost. """ msg = BytesIO(msg_bytes) d: "Deferred[object]" = Deferred() + if tlsname is None: + tlsname = smtphost def build_sender_factory(**kwargs: Any) -> ESMTPSenderFactory: return ESMTPSenderFactory( @@ -117,10 +122,10 @@ async def _sendmail( else: # for twisted 21.2 and later, there is a 'hostname' parameter which we should # set to enable TLS. - factory = build_sender_factory(hostname=smtphost if enable_tls else None) + factory = build_sender_factory(hostname=tlsname if enable_tls else None) if force_tls: - factory = TLSMemoryBIOFactory(optionsForClientTLS(smtphost), True, factory) + factory = TLSMemoryBIOFactory(optionsForClientTLS(tlsname), True, factory) endpoint = HostnameEndpoint( reactor, smtphost, smtpport, timeout=30, bindAddress=None @@ -148,6 +153,7 @@ class SendEmailHandler: self._require_transport_security = hs.config.email.require_transport_security self._enable_tls = hs.config.email.enable_smtp_tls self._force_tls = hs.config.email.force_tls + self._tlsname = hs.config.email.email_tlsname self._sendmail = _sendmail @@ -227,4 +233,5 @@ class SendEmailHandler: require_tls=self._require_transport_security, enable_tls=self._enable_tls, force_tls=self._force_tls, + tlsname=self._tlsname, )