You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2022/12/30 02:02:55 UTC

[james-project] 01/02: JAMES-3868 Cannot handle IMAP PLAIN login with password longer than 255 char

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

commit e72a891e853d8f3778a86387cbdee25de9adfd5b
Author: Tung Van TRAN <vt...@linagora.com>
AuthorDate: Tue Dec 13 11:06:36 2022 +0700

    JAMES-3868 Cannot handle IMAP PLAIN login with password longer than 255 char
---
 .../imap/processor/AuthenticateProcessor.java      | 22 +++++++++++-----------
 .../james/imapserver/netty/IMAPServerTest.java     | 15 +++++++++++++--
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
index 415f25b27e..cfab921d05 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AuthenticateProcessor.java
@@ -21,10 +21,11 @@ package org.apache.james.imap.processor;
 
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Base64;
 import java.util.List;
 import java.util.Optional;
-import java.util.StringTokenizer;
+import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 
@@ -48,6 +49,7 @@ import org.apache.james.util.MDCBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import reactor.core.publisher.Mono;
@@ -132,15 +134,13 @@ public class AuthenticateProcessor extends AbstractAuthProcessor<AuthenticateReq
     }
 
     private AuthenticationAttempt parseDelegationAttempt(String initialClientResponse) {
-        String token2;
         try {
             String userpass = new String(Base64.getDecoder().decode(initialClientResponse));
-            StringTokenizer authTokenizer = new StringTokenizer(userpass, "\0");
-            String token1 = authTokenizer.nextToken();  // Authorization Identity
-            token2 = authTokenizer.nextToken();                 // Authentication Identity
-            try {
-                return delegation(Username.of(token1), Username.of(token2), authTokenizer.nextToken());
-            } catch (java.util.NoSuchElementException ignored) {
+            List<String> tokens = Arrays.stream(userpass.split("\0"))
+                .filter(token -> !token.isBlank())
+                .collect(Collectors.toList());
+            Preconditions.checkArgument(tokens.size() == 2 || tokens.size() == 3);
+            if (tokens.size() == 2) {
                 // If we got here, this is what happened.  RFC 2595
                 // says that "the client may leave the authorization
                 // identity empty to indicate that it is the same as
@@ -156,9 +156,9 @@ public class AuthenticateProcessor extends AbstractAuthProcessor<AuthenticateReq
                 // elements, leading to the exception we just
                 // caught.  So we need to move the user to the
                 // password, and the authorize_id to the user.
-                return noDelegation(Username.of(token1), token2);
-            } finally {
-                authTokenizer = null;
+                return noDelegation(Username.of(tokens.get(0)), tokens.get(1));
+            } else {
+                return delegation(Username.of(tokens.get(0)), Username.of(tokens.get(1)), tokens.get(2));
             }
         } catch (Exception e) {
             // Ignored - this exception in parsing will be dealt
diff --git a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
index 3b4461e2cf..a0c0ace750 100644
--- a/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
+++ b/server/protocols/protocols-imap4/src/test/java/org/apache/james/imapserver/netty/IMAPServerTest.java
@@ -71,7 +71,6 @@ import org.apache.commons.net.imap.IMAPSClient;
 import org.apache.james.core.Username;
 import org.apache.james.imap.encode.main.DefaultImapEncoderFactory;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
-import org.apache.james.imap.processor.AppendProcessor;
 import org.apache.james.imap.processor.base.AbstractProcessor;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.jwt.OidcTokenFixture;
@@ -140,6 +139,7 @@ class IMAPServerTest {
     private static final String USER_PASS = "pass";
     public static final String SMALL_MESSAGE = "header: value\r\n\r\nBODY";
     private InMemoryIntegrationResources memoryIntegrationResources;
+    private FakeAuthenticator authenticator;
 
     @RegisterExtension
     public TestIMAPClient testIMAPClient = new TestIMAPClient();
@@ -179,7 +179,7 @@ class IMAPServerTest {
     }
 
     private IMAPServer createImapServer(HierarchicalConfiguration<ImmutableNode> config) throws Exception {
-        FakeAuthenticator authenticator = new FakeAuthenticator();
+        authenticator = new FakeAuthenticator();
         authenticator.addUser(USER, USER_PASS);
         authenticator.addUser(USER2, USER_PASS);
         authenticator.addUser(USER3, USER_PASS);
@@ -993,6 +993,17 @@ class IMAPServerTest {
                 .doesNotContain("LOGINDISABLED")
                 .contains("AUTH=PLAIN");
         }
+
+        @Test
+        void authenticatePlainShouldSucceedWhenPasswordHasMoreThan255Characters() {
+            Username user1 = Username.of("user1@domain.org");
+            String user1Password = "1".repeat(300);
+            authenticator.addUser(user1, user1Password);
+            assertThatCode(() ->
+                testIMAPClient.connect("127.0.0.1", port)
+                    .authenticatePlain(user1.asString(), user1Password))
+                .doesNotThrowAnyException();
+        }
     }
 
     @Nested


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org