This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push: new 2df3332e89 [FIX] Handle XOAUTH2 for SMTP without initial response (#2428) 2df3332e89 is described below commit 2df3332e89820080840e3b213e7fd0af492a5632 Author: Benoit TELLIER <btell...@linagora.com> AuthorDate: Tue Oct 1 18:23:15 2024 +0400 [FIX] Handle XOAUTH2 for SMTP without initial response (#2428) --- .../protocols/smtp/core/esmtp/AuthCmdHandler.java | 79 ++++++++++++++-------- .../org/apache/james/smtpserver/SMTPSaslTest.java | 22 ++++++ 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java index 6b75b976fc..0fd4a66644 100644 --- a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java +++ b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/AuthCmdHandler.java @@ -168,43 +168,62 @@ public class AuthCmdHandler } String authType = argument.toUpperCase(Locale.US); if (authType.equals(AUTH_TYPE_PLAIN) && session.getConfiguration().isPlainAuthEnabled()) { - String userpass; - if (initialResponse == null) { - session.pushLineHandler(new AbstractSMTPLineHandler() { - @Override - protected Response onCommand(SMTPSession session, String l) { - return doPlainAuth(session, l); - } - }); - return AUTH_READY_PLAIN; - } else { - userpass = initialResponse.trim(); - return doPlainAuth(session, userpass); - } + return handlePlainContinuation(session, initialResponse); } else if (authType.equals(AUTH_TYPE_LOGIN) && session.getConfiguration().isPlainAuthEnabled()) { - - if (initialResponse == null) { - session.pushLineHandler(new AbstractSMTPLineHandler() { - @Override - protected Response onCommand(SMTPSession session, String l) { - return doLoginAuthPass(session, l); - } - }); - return AUTH_READY_USERNAME_LOGIN; - } else { - String user = initialResponse.trim(); - return doLoginAuthPass(session, user); - } - } else if ((authType.equals(AUTH_TYPE_OAUTHBEARER) || authType.equals(AUTH_TYPE_XOAUTH2)) - && session.supportsOAuth()) { - return doSASLAuthentication(session, initialResponse); + return handleLoginAuthContinuation(session, initialResponse); + } else if ((authType.equals(AUTH_TYPE_OAUTHBEARER) || authType.equals(AUTH_TYPE_XOAUTH2)) && session.supportsOAuth()) { + return handleOauth2Continuation(session, initialResponse); } else { return doUnknownAuth(authType); } } } - private Response doSASLAuthentication(SMTPSession session, String initialResponseString) { + private Response handlePlainContinuation(SMTPSession session, String initialResponse) { + return Optional.ofNullable(initialResponse) + .map(String::trim) + .map(userpass -> doPlainAuth(session, userpass)) + .orElseGet(() -> { + session.pushLineHandler(new AbstractSMTPLineHandler() { + @Override + protected Response onCommand(SMTPSession session, String l) { + return doPlainAuth(session, l); + } + }); + return AUTH_READY_USERNAME_LOGIN; + }); + } + + private Response handleLoginAuthContinuation(SMTPSession session, String initialResponse) { + return Optional.ofNullable(initialResponse) + .map(String::trim) + .map(user -> doLoginAuthPass(session, user)) + .orElseGet(() -> { + session.pushLineHandler(new AbstractSMTPLineHandler() { + @Override + protected Response onCommand(SMTPSession session, String l) { + return doLoginAuthPass(session, l); + } + }); + return AUTH_READY_USERNAME_LOGIN; + }); + } + + private Response handleOauth2Continuation(SMTPSession session, String initialResponse) { + return Optional.ofNullable(initialResponse) + .map(token -> doOauth2Authentication(session, token)) + .orElseGet(() -> { + session.pushLineHandler(new AbstractSMTPLineHandler() { + @Override + protected Response onCommand(SMTPSession session, String l) { + return doOauth2Authentication(session, l); + } + }); + return new SMTPResponse(SMTPRetCode.AUTH_READY, ""); + }); + } + + private Response doOauth2Authentication(SMTPSession session, String initialResponseString) { return session.getConfiguration().saslConfiguration() .map(oidcSASLConfiguration -> hooks.stream() .flatMap(hook -> Optional.ofNullable(executeHook(session, hook, diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java index a25f1d36e0..e6325e8fb8 100644 --- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java +++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPSaslTest.java @@ -120,6 +120,28 @@ class SMTPSaslTest { assertThat(client.getReplyString()).contains("235 Authentication successful."); } + @Test + void oauthShouldSuccessWhenValidTokenAndContinuation() throws Exception { + SMTPSClient client = initSMTPSClient(); + + client.sendCommand("AUTH OAUTHBEARER"); + assertThat(client.getReplyString()).contains("334"); + client.sendCommand(VALID_TOKEN); + + assertThat(client.getReplyString()).contains("235 Authentication successful."); + } + + @Test + void oauthShouldSuccessWhenValidTokenAndContinuationAndXOauth2() throws Exception { + SMTPSClient client = initSMTPSClient(); + + client.sendCommand("AUTH XOAUTH2"); + assertThat(client.getReplyString()).contains("334"); + client.sendCommand(VALID_TOKEN); + + assertThat(client.getReplyString()).contains("235 Authentication successful."); + } + @Test void oauthShouldSupportXOAUTH2Type() throws Exception { SMTPSClient client = initSMTPSClient(); --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org