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 2026/01/19 16:18:25 UTC
(james-project) 11/17: fix(managesieve): Implement continuation as described in RFC-4616
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 a8950829cf959bee8f5f18c0572ac44a5610dc77
Author: Felix Auringer <fe...@protonmail.com>
AuthorDate: Mon Nov 17 11:02:56 2025 +0100
fix(managesieve): Implement continuation as described in RFC-4616
---
.../apache/james/managesieve/scripts/authenticate.test | 9 +++------
.../org/apache/james/managesieve/scripts/capability.test | 3 +--
.../apache/james/managesieve/scripts/checkscript.test | 3 +--
.../apache/james/managesieve/scripts/deletescript.test | 3 +--
.../org/apache/james/managesieve/scripts/getscript.test | 3 +--
.../org/apache/james/managesieve/scripts/havespace.test | 3 +--
.../apache/james/managesieve/scripts/listscripts.test | 3 +--
.../org/apache/james/managesieve/scripts/putscript.test | 3 +--
.../apache/james/managesieve/scripts/renamescript.test | 3 +--
.../org/apache/james/managesieve/scripts/setactive.test | 3 +--
.../org/apache/james/managesieve/scripts/starttls.test | 3 +--
.../apache/james/managesieve/scripts/unauthenticate.test | 3 +--
.../managesieve/core/OAUTHAuthenticationProcessor.java | 2 +-
.../managesieve/core/PlainAuthenticationProcessor.java | 2 +-
.../apache/james/managesieveserver/AuthenticateTest.java | 8 ++++----
.../james/managesieveserver/ManageSieveClient.java | 4 ++++
.../org/apache/james/managesieveserver/OIDCTest.java | 16 ++++++++--------
17 files changed, 32 insertions(+), 42 deletions(-)
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/authenticate.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/authenticate.test
index 9914f24f28..54c8a6140c 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/authenticate.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/authenticate.test
@@ -24,19 +24,16 @@ C: AUTHENTICATE "UNKNOWN"
S: NO "Unknown SASL mechanism UNKNOWN"
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: GETSCRIPT toto.sieve
S: NO "ManageSieve syntax is incorrect: quoted authentication data must be supplied"
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "tin password"
S: NO "Authentication failed with: Verification of credentials failed"
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/capability.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/capability.test
index 16e6a75e02..095c34db56 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/capability.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/capability.test
@@ -38,8 +38,7 @@ S: "VERSION" "1.0"
S: OK
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/checkscript.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/checkscript.test
index 33cc62e821..768909990c 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/checkscript.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/checkscript.test
@@ -34,8 +34,7 @@ C:
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/deletescript.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/deletescript.test
index 91658e2b55..be80044cac 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/deletescript.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/deletescript.test
@@ -24,8 +24,7 @@ C: DELETESCRIPT "foo"
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/getscript.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/getscript.test
index 8d1359100e..a04c277122 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/getscript.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/getscript.test
@@ -24,8 +24,7 @@ C: GETSCRIPT "foo"
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/havespace.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/havespace.test
index 653f60fe43..aaa2d3bfe9 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/havespace.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/havespace.test
@@ -27,8 +27,7 @@ C: HAVESPACE "scriptname" 49
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/listscripts.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/listscripts.test
index a59dd4a700..9f048b42f9 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/listscripts.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/listscripts.test
@@ -21,8 +21,7 @@ C: LISTSCRIPTS
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/putscript.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/putscript.test
index 2b9c72e33f..b8048ce22a 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/putscript.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/putscript.test
@@ -39,8 +39,7 @@ C:
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/renamescript.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/renamescript.test
index 1de65f25d0..7b5ff18344 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/renamescript.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/renamescript.test
@@ -27,8 +27,7 @@ C: RENAMESCRIPT "foo" "bar"
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/setactive.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/setactive.test
index 5a836693f6..c233498a47 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/setactive.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/setactive.test
@@ -24,8 +24,7 @@ C: SETACTIVE "foo"
S: NO
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/starttls.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/starttls.test
index 8220140f7e..39fdbf3f1d 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/starttls.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/starttls.test
@@ -24,8 +24,7 @@ C: STARTTLS
S: NO You can't enable two time SSL encryption
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/unauthenticate.test b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/unauthenticate.test
index 21ef39e49f..92576fdba8 100644
--- a/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/unauthenticate.test
+++ b/mpt/impl/managesieve/core/src/main/resources/org/apache/james/managesieve/scripts/unauthenticate.test
@@ -27,8 +27,7 @@ C: UNAUTHENTICATE
S: NO UNAUTHENTICATE command must be issued in authenticated state
C: AUTHENTICATE "PLAIN"
-S: ""
-S: OK
+S: \+ ""
C: "user password"
S: OK
diff --git a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/OAUTHAuthenticationProcessor.java b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/OAUTHAuthenticationProcessor.java
index e424d2759e..ba925141a8 100644
--- a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/OAUTHAuthenticationProcessor.java
+++ b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/OAUTHAuthenticationProcessor.java
@@ -45,7 +45,7 @@ public class OAUTHAuthenticationProcessor implements AuthenticationProcessor {
@Override
public String initialServerResponse(Session session) {
- return "\"\"\r\nOK";
+ return "+ \"\"";
}
@Override
diff --git a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/PlainAuthenticationProcessor.java b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/PlainAuthenticationProcessor.java
index 1a6164b5d8..1e9e659638 100644
--- a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/PlainAuthenticationProcessor.java
+++ b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/PlainAuthenticationProcessor.java
@@ -50,7 +50,7 @@ public class PlainAuthenticationProcessor implements AuthenticationProcessor {
@Override
public String initialServerResponse(Session session) {
- return "\"\"\r\nOK";
+ return "+ \"\"";
}
diff --git a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/AuthenticateTest.java b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/AuthenticateTest.java
index 91d99139c2..e9aea8302d 100644
--- a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/AuthenticateTest.java
+++ b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/AuthenticateTest.java
@@ -111,8 +111,8 @@ public class AuthenticateTest {
void plainLoginWithContinuationShouldSucceed() throws IOException {
this.client.sendCommand("AUTHENTICATE \"PLAIN\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
String initialClientResponse = "\0" + ManageSieveServerTestSystem.USERNAME.asString() + "\0" + ManageSieveServerTestSystem.PASSWORD;
this.client.sendCommand("\"" + Base64.getEncoder().encodeToString(initialClientResponse.getBytes(StandardCharsets.UTF_8)) + "\"");
@@ -124,8 +124,8 @@ public class AuthenticateTest {
void plainLoginWithContinuationCanBeAborted() throws IOException {
this.client.sendCommand("AUTHENTICATE \"PLAIN\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
this.client.sendCommand("\"*\"");
ManageSieveClient.ServerResponse authenticationResponse = this.client.readResponse();
diff --git a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/ManageSieveClient.java b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/ManageSieveClient.java
index e712489b70..c4f042b7ba 100644
--- a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/ManageSieveClient.java
+++ b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/ManageSieveClient.java
@@ -37,6 +37,7 @@ public class ManageSieveClient extends SocketClient {
enum ResponseType {
BYE,
+ CONTINUATION,
NO,
OK;
}
@@ -90,6 +91,9 @@ public class ManageSieveClient extends SocketClient {
}
response = new ServerResponse(responseType, responseCode, explanation, lines);
+ } else if (tokens[0].equals("+")) {
+ Optional explanation = Optional.of(tokens[1].substring(1, tokens[1].length() - 1));
+ response = new ServerResponse(ResponseType.CONTINUATION, Optional.empty(), explanation, new ArrayList());
} else {
lines.addLast(line);
}
diff --git a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/OIDCTest.java b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/OIDCTest.java
index b122d8ddf6..a07785e77d 100644
--- a/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/OIDCTest.java
+++ b/server/protocols/protocols-managesieve/src/test/java/org/apache/james/managesieveserver/OIDCTest.java
@@ -114,8 +114,8 @@ public class OIDCTest {
void oauthbearerLoginWithValidTokenAndContinuationShouldSucceed() throws Exception {
this.client.sendCommand("AUTHENTICATE \"OAUTHBEARER\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
this.client.sendCommand("\"" + VALID_OAUTHBEARER_INITIAL_CLIENT_RESPONSE + "\"");
ManageSieveClient.ServerResponse authenticationResponse = this.client.readResponse();
@@ -126,8 +126,8 @@ public class OIDCTest {
void oauthbearerLoginWithValidTokenAndContinuationCanBeAborted() throws Exception {
this.client.sendCommand("AUTHENTICATE \"OAUTHBEARER\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
this.client.sendCommand("\"*\"");
ManageSieveClient.ServerResponse authenticationResponse = this.client.readResponse();
@@ -153,8 +153,8 @@ public class OIDCTest {
void xoauth2LoginWithValidTokenAndContinuationShouldSucceed() throws Exception {
this.client.sendCommand("AUTHENTICATE \"XOAUTH2\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
this.client.sendCommand("\"" + VALID_XOAUTH2_INITIAL_CLIENT_RESPONSE + "\"");
ManageSieveClient.ServerResponse authenticationResponse = this.client.readResponse();
@@ -165,8 +165,8 @@ public class OIDCTest {
void xoauth2LoginWithValidTokenAndContinuationCanBeAborted() throws Exception {
this.client.sendCommand("AUTHENTICATE \"XOAUTH2\"");
ManageSieveClient.ServerResponse continuationResponse = this.client.readResponse();
- Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.OK);
- Assertions.assertThat(continuationResponse.responseLines()).containsExactly("\"\"");
+ Assertions.assertThat(continuationResponse.responseType()).isEqualTo(ManageSieveClient.ResponseType.CONTINUATION);
+ Assertions.assertThat(continuationResponse.explanation().get()).isEqualTo("");
this.client.sendCommand("\"*\"");
ManageSieveClient.ServerResponse authenticationResponse = this.client.readResponse();
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org