Merge pull request 'fix(ses): sign in to the SMTP relay with the password, not as an OAuth token' (#8) from fix/ses-smtp-password-auth into main

Reviewed-on: #8
This commit was merged in pull request #8.
This commit is contained in:
2026-10-25 11:57:20 +00:00
2 changed files with 7 additions and 1 deletions
@@ -57,6 +57,8 @@ public class SmtpRelay {
private static final Logger LOG = Logger.getLogger(SmtpRelay.class); private static final Logger LOG = Logger.getLogger(SmtpRelay.class);
private static final long RELAY_TIMEOUT_SECONDS = 30; private static final long RELAY_TIMEOUT_SECONDS = 30;
/** Every SASL method the mail client supports except XOAUTH2, which expects a token. */
static final String PASSWORD_AUTH_METHODS = "CRAM-SHA256 CRAM-SHA1 CRAM-MD5 DIGEST-MD5 LOGIN PLAIN";
/** SES control header naming the configuration set to apply to a raw send. */ /** SES control header naming the configuration set to apply to a raw send. */
public static final String HEADER_CONFIGURATION_SET = "X-SES-CONFIGURATION-SET"; public static final String HEADER_CONFIGURATION_SET = "X-SES-CONFIGURATION-SET";
@@ -118,6 +120,9 @@ public class SmtpRelay {
.filter(u -> !u.isBlank()) .filter(u -> !u.isBlank())
.ifPresent(u -> { .ifPresent(u -> {
mailConfig.setUsername(u); mailConfig.setUsername(u);
// smtp-pass is a password, never an OAuth token: without this the client prefers
// XOAUTH2 whenever the server offers it (Gmail does) and the login is refused.
mailConfig.setAuthMethods(PASSWORD_AUTH_METHODS);
config.services().ses().smtpPass() config.services().ses().smtpPass()
.filter(p -> !p.isBlank()) .filter(p -> !p.isBlank())
.ifPresent(mailConfig::setPassword); .ifPresent(mailConfig::setPassword);
@@ -287,7 +287,8 @@ class SmtpRelayServerTest {
String command = line.toUpperCase(Locale.ROOT); String command = line.toUpperCase(Locale.ROOT);
if (command.startsWith("EHLO")) { if (command.startsWith("EHLO")) {
reply(out, "250-floci-stub"); reply(out, "250-floci-stub");
reply(out, "250 AUTH PLAIN"); // Gmail also offers OAuth sign-in, which a password must never be sent as.
reply(out, "250 AUTH PLAIN XOAUTH2 OAUTHBEARER");
} else if (command.startsWith("HELO")) { } else if (command.startsWith("HELO")) {
reply(out, "250 floci-stub"); reply(out, "250 floci-stub");
} else if (command.startsWith("AUTH")) { } else if (command.startsWith("AUTH")) {