Skip to content

Commit

Permalink
Merge pull request #40990 from cescoffier/mailer-tls-registry
Browse files Browse the repository at this point in the history
Add support for the TLS registry to the mailer extension
  • Loading branch information
geoand authored Jun 10, 2024
2 parents af3b663 + 134296a commit 250eb95
Show file tree
Hide file tree
Showing 34 changed files with 1,001 additions and 297 deletions.
112 changes: 93 additions & 19 deletions docs/src/main/asciidoc/mailer-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -362,28 +362,100 @@ More details about this extension and its configuration can be found in the http
[TIP]
For more information about the Mailer configuration please refer to the <<configuration-reference,Configuration Reference>>.

== Configuring a trust store
== Configuring TLS

If your SMTP requires a trust store, you can configure the trust store as follows:
SMTP provides various way to use TLS:

- StartTLS: The client connects to the server using a plain connection and then upgrades to a secure connection.
- SSL/TLS: The client connects to the server using a secure connection from the start.

=== Configuring STARTTLS

To use `STARTTLS`, you need to configure the `start-tls` property to `REQUIRED` or `OPTIONAL` and set `tls` to `false`:

[source, properties]
----
quarkus.mailer.tls=false
quarkus.mailer.start-tls=REQUIRED
----

Setting `tls` to `false` ensure we connect using a plain connection and then upgrade to a secure connection using `STARTTLS`.

To configure the trust store, you can use a _named_ TLS configuration stored in the xref:./tls-registry-reference.adoc[TLS registry]:

[source, properties]
----
quarkus.mailer.tls=false
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.tls-configuration-name=my-mailer # Reference the named configuration
quarkus.tls.my-mailer.trust-store.pem.certs=server-cert.pem # Configure the trust store
----

While not recommended, you can trust all certificates by setting `quarkus.tls.trust-all` to `true`:

[source, properties]
----
quarkus.mailer.tls=false
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.tls-configuration-name=my-mailer # Reference the named configuration
quarkus.tls.my-mailer.trust-all=true
----

Alternatively, you can use the _deprecated_ `quarkus.mailer.trust-store.paths` and `quarkus.mailer.trust-all` properties:

[source, properties]
----
quarkus.mailer.tls=false
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.truststore.paths=target/certs/mailpit-ca.crt
----

[source, properties]
----
quarkus.mailer.host=...
quarkus.mailer.port=...
quarkus.mailer.ssl=true
quarkus.mailer.trust-store.paths=truststore.jks # the path to your trust store
quarkus.mailer.trust-store.password=secret # the trust store password if any
quarkus.mailer.trust-store.type=JKS # the type of trust store if it can't be deduced from the file extension
quarkus.mailer.tls=false
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.trust-all=true
----

Quarkus mailer supports JKS, PKCS#12 and PEM trust stores.
For PEM, you can configure multiple files.
For JKS and PKCS#12, you can configure the password if any.
=== Configuring SSL/TLS

`quarkus.mailer.trust-store.type` is optional and allows configuring the type of trust store (among `JKS`, `PEM` and `PKCS`).
When not set, Quarkus tries to deduce the type from the file name.
To establish a TLS connection, you need to configure a _named_ configuration using the xref:./tls-registry-reference.adoc[TLS registry]:

NOTE: You can also configure `quarkus.mailer.trust-all=true` to bypass the verification.
[source, properties]
----
quarkus.tls.my-mailer.trust-store.p12.path=server-truststore.p12
quarkus.tls.my-mailer.trust-store.p12.password=secret
quarkus.mailer.tls-configuration-name=my-mailer # Reference the named configuration
----

WARNING: When using the mailer, using a _named_ configuration is required to avoid conflicts with other TLS configurations.
The mailer will not use the default TLS configuration.

When you configure a _named_ TLS configuration, TLS is enabled by default.
If your SMTP server uses a valid (trusted) certificate, and thus do not require a specific TLS configuration, you need to enable TLS explicitly (as you do not have to configure a trust store):

[source, properties]
----
quarkus.mailer.tls=true
----



[IMPORTANT]
====
When `quarkus.tls.trust-all` is set to `true`, the trust store configuration is ignored. This is not recommended for production.
Also, we recommend avoiding using `quarkus.tls.trust-all`, and use a named configuration instead if `trust-all` is required:
[source, properties]
----
quarkus.tls.my-mailer.trust-all=true
quarkus.mailer.tls-configuration-name=my-mailer # Reference the named configuration
----
You can also use the deprecated `quarkus.mailer.trust-all=true` property.
====

== Multiple mailer configurations

Expand Down Expand Up @@ -476,7 +548,7 @@ You need to switch on 2-Step Verification at https://myaccount.google.com/securi

When done, you can configure your Quarkus application by adding the following properties to your `application.properties`:

With TLS:
With `STARTTLS`:

[source,properties]
----
Expand All @@ -491,15 +563,15 @@ quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD
quarkus.mailer.mock=false # In dev mode, prevent from using the mock SMTP server
----

Or with SSL:
Or with TLS/SSL:

[source,properties]
----
quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN
[email protected]
quarkus.mailer.host=smtp.gmail.com
quarkus.mailer.port=465
quarkus.mailer.ssl=true
quarkus.mailer.tls=true
[email protected]
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD
Expand Down Expand Up @@ -532,6 +604,7 @@ ses.from=an email address from the verified domain
quarkus.mailer.host=${ses.smtp}
quarkus.mailer.port=587
quarkus.mailer.tls=false
quarkus.mailer.username=${ses.user}
quarkus.mailer.password=${ses.password}
quarkus.mailer.start-tls=REQUIRED
Expand Down Expand Up @@ -565,7 +638,7 @@ quarkus.mailer.port=465
quarkus.mailer.username=${mailjet.api-key}
quarkus.mailer.password=${mailjet.secret-key}
quarkus.mailer.start-tls=OPTIONAL
quarkus.mailer.ssl=true
quarkus.mailer.tls=true
quarkus.mailer.login=REQUIRED
quarkus.mailer.from=${mailjet.from}
Expand All @@ -591,13 +664,14 @@ quarkus.mailer.port=465
quarkus.mailer.username=${sendgrid.username}
quarkus.mailer.password=${sendgrid.key}
quarkus.mailer.start-tls=OPTIONAL
quarkus.mailer.ssl=true
quarkus.mailer.login=REQUIRED
quarkus.mailer.from=...
quarkus.mailer.tls=true
quarkus.mailer.mock=false # In dev mode, prevent from using the mock SMTP server
----


[[configuration-reference]]
== Mailer Configuration Reference

Expand Down
5 changes: 5 additions & 0 deletions extensions/mailer/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>me.escoffier.certs</groupId>
<artifactId>certificate-generator-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class MailerRuntimeConfig {
* SMTP relaying is the transmission of email from email server to email server.
* The port 587 is the default port when {@link #ssl} is enabled.
* It ensures that email is submitted securely.
*
* <p>
* Note that the port 465 may be used by SMTP servers, however, IANA has reassigned a new service to this port,
* and it should no longer be used for SMTP communications.
*/
Expand All @@ -70,17 +70,51 @@ public class MailerRuntimeConfig {
@ConfigItem
public Optional<String> password = Optional.empty();

/**
* The name of the TLS configuration to use.
* <p>
* If a name is configured, it uses the configuration from {@code quarkus.tls.<name>.*}
* If a name is configured, but no TLS configuration is found with that name then an error will be thrown.
* <p>
* If no TLS configuration name is set then, the specific TLS configuration (from {@code quarkus.mailer.*}) will be used.
* <p>
* The default TLS configuration is <strong>not</strong> used by default.
*/
@ConfigItem
public Optional<String> tlsConfigurationName = Optional.empty();

/**
* Enables or disables the TLS/SSL.
*
* @deprecated Use {{@link #tls}}
*/
@Deprecated
@ConfigItem(defaultValue = "false")
public boolean ssl;

/**
* Whether the connection should be secured using TLS.
* <p>
* SMTP allows establishing connection with or without TLS.
* When establishing a connection with TLS, the connection is secured and encrypted.
* When establishing a connection without TLS, it can be secured and encrypted later using the STARTTLS command.
* In this case, the connection is initially unsecured and unencrypted.
* To configure this case, set this property to {@code false} and {@link #startTLS} to {@code REQUIRED}
*
* Note that if a TLS configuration is set, TLS is enabled automatically. So, setting this property to {@code false} is
* required to not establish a connection with TLS.
*/
@ConfigItem
public Optional<Boolean> tls;

/**
* Set whether all server certificates should be trusted.
* This option is only used when {@link #ssl} is enabled.
*
* @deprecated Use the TLS registry instead.
*/
@ConfigItem
@Deprecated
public Optional<Boolean> trustAll = Optional.empty();

/**
Expand All @@ -104,7 +138,7 @@ public class MailerRuntimeConfig {

/**
* Disable ESMTP.
*
* <p>
* The RFC-1869 states that clients should always attempt {@code EHLO} as first command to determine if ESMTP
* is supported, if this returns an error code, {@code HELO} is tried to use the <em>regular</em> SMTP command.
*/
Expand Down Expand Up @@ -142,7 +176,7 @@ public class MailerRuntimeConfig {
* Sets the allowed authentication methods.
* These methods will be used only if the server supports them.
* If not set, all supported methods may be used.
*
* <p>
* The list is given as a space separated list, such as {@code DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN}.
*/
@ConfigItem
Expand All @@ -151,7 +185,7 @@ public class MailerRuntimeConfig {
/**
* Set the trust store.
*
* @deprecated Use {{@link #truststore} instead.
* @deprecated Use the TLS registry instead.
*/
@Deprecated
@ConfigItem
Expand All @@ -160,16 +194,19 @@ public class MailerRuntimeConfig {
/**
* Sets the trust store password if any.
*
* @deprecated Use {{@link #truststore} instead.
* @deprecated Use the TLS registry instead.
*/
@ConfigItem
@Deprecated
public Optional<String> keyStorePassword = Optional.empty();

/**
* Configures the trust store.
*
* @deprecated Use the TLS registry instead.
*/
@ConfigItem
@Deprecated
public TrustStoreConfig truststore = new TrustStoreConfig();

/**
Expand Down
Loading

0 comments on commit 250eb95

Please sign in to comment.