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