Merge pull request #5881 from k9mail/fix_pop3_get_capabilities

Stop using AUTH without arguments (POP3)
This commit is contained in:
cketti 2022-01-25 19:12:35 +01:00 committed by GitHub
commit f60dd4b0df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 158 deletions

View file

@ -175,40 +175,6 @@ class Pop3Connection {
private Pop3Capabilities getCapabilities() throws IOException {
Pop3Capabilities capabilities = new Pop3Capabilities();
try {
/*
* Try sending an AUTH command with no arguments.
*
* The server may respond with a list of supported SASL
* authentication mechanisms.
*
* Ref.: http://tools.ietf.org/html/draft-myers-sasl-pop3-05
*
* While this never became a standard, there are servers that
* support it, and Thunderbird includes this check.
*/
executeSimpleCommand(AUTH_COMMAND);
String response;
while ((response = readLine()) != null) {
if (response.equals(".")) {
break;
}
response = response.toUpperCase(Locale.US);
switch (response) {
case AUTH_PLAIN_CAPABILITY:
capabilities.authPlain = true;
break;
case AUTH_CRAM_MD5_CAPABILITY:
capabilities.cramMD5 = true;
break;
case AUTH_EXTERNAL_CAPABILITY:
capabilities.external = true;
break;
}
}
} catch (MessagingException ignored) {
// Assume AUTH command with no arguments is not supported.
}
try {
executeSimpleCommand(CAPA_COMMAND);
String response;
@ -231,6 +197,9 @@ class Pop3Connection {
if (saslAuthMechanisms.contains(AUTH_CRAM_MD5_CAPABILITY)) {
capabilities.cramMD5 = true;
}
if (saslAuthMechanisms.contains(AUTH_EXTERNAL_CAPABILITY)) {
capabilities.external = true;
}
}
}

View file

@ -42,29 +42,19 @@ public class Pop3ConnectionTest {
private static String username = "user";
private static String password = "password";
private static final String INITIAL_RESPONSE = "+OK POP3 server greeting\r\n";
private static final String AUTH = "AUTH\r\n";
private static final String AUTH_HANDLE_RESPONSE =
"+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String CAPA =
"CAPA\r\n";
private static final String CAPA_RESPONSE =
"+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
"SASL PLAIN CRAM-MD5 EXTERNAL\r\n" +
".\r\n";
private static final String AUTH_PLAIN_WITH_LOGIN = "AUTH PLAIN\r\n" +
new String(Base64.encodeBase64(("\000"+username+"\000"+password).getBytes())) + "\r\n";
private static final String AUTH_PLAIN_AUTHENTICATED_RESPONSE = "+OK\r\n" + "+OK\r\n";
private static final String SUCCESSFUL_PLAIN_AUTH = AUTH + CAPA + AUTH_PLAIN_WITH_LOGIN;
private static final String SUCCESSFUL_PLAIN_AUTH = CAPA + AUTH_PLAIN_WITH_LOGIN;
private static final String SUCCESSFUL_PLAIN_AUTH_RESPONSE =
INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE;
/**
@ -323,12 +313,9 @@ public class Pop3ConnectionTest {
private MockPop3Server setupUnavailableStartTLSConnection() throws IOException {new MockPop3Server();
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("SASL PLAIN");
server.output(".");
server.start();
settings.setHost(server.getHost());
@ -339,13 +326,10 @@ public class Pop3ConnectionTest {
private void setupServerWithStartTLSAvailable(MockPop3Server server) {
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("STLS");
server.output("SASL PLAIN");
server.output(".");
}
@ -357,17 +341,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH PLAIN");
server.output("+OK");
@ -385,17 +361,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH PLAIN");
server.output("+OK");
@ -416,15 +384,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("USER user");
server.output("+OK");
@ -445,15 +407,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("USER user");
server.output("+OK");
@ -471,17 +427,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH CRAM-MD5");
server.output("+ abcd");
@ -500,17 +448,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH CRAM-MD5");
server.output("+ abcd");
@ -531,15 +471,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK abc<a>abcd");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("EXTERNAL");
server.output("SASL PLAIN EXTERNAL");
server.output(".");
server.expect("APOP user c8e8c560e385faaa6367d4145572b8ea");
server.output("+OK");
@ -556,15 +490,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK abc<a>abcd");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("EXTERNAL");
server.output("SASL PLAIN EXTERNAL");
server.output(".");
server.expect("APOP user c8e8c560e385faaa6367d4145572b8ea");
server.output("-ERR");
@ -583,17 +511,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH EXTERNAL dXNlcg==");
server.output("+OK");
@ -609,16 +529,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5");
server.output(".");
try {
@ -638,17 +551,9 @@ public class Pop3ConnectionTest {
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output("CRAM-MD5");
server.output("EXTERNAL");
server.output("SASL PLAIN CRAM-MD5 EXTERNAL");
server.output(".");
server.expect("AUTH EXTERNAL dXNlcg==");
server.output("-ERR Invalid certificate");

View file

@ -28,17 +28,9 @@ import static org.mockito.Mockito.when;
public class Pop3StoreTest {
private static final String INITIAL_RESPONSE = "+OK POP3 server greeting\r\n";
private static final String AUTH = "AUTH\r\n";
private static final String AUTH_HANDLE_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String CAPA = "CAPA\r\n";
private static final String CAPA_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
"SASL PLAIN CRAM-MD5 EXTERNAL\r\n" +
".\r\n";
private static final String AUTH_PLAIN_WITH_LOGIN = "AUTH PLAIN\r\n" +
new String(Base64.encodeBase64(("\000user\000password").getBytes())) + "\r\n";
@ -94,7 +86,6 @@ public class Pop3StoreTest {
public void checkSetting_whenUidlUnsupported_shouldThrowMessagingException()
throws Exception {
String response = INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE +
STAT_RESPONSE +
@ -109,7 +100,6 @@ public class Pop3StoreTest {
public void checkSetting_whenUidlSupported_shouldReturn()
throws Exception {
String response = INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE +
STAT_RESPONSE +
@ -125,7 +115,6 @@ public class Pop3StoreTest {
@Test
public void open_withAuthResponseUsingAuthPlain_shouldRetrieveMessageCountOnAuthenticatedSocket() throws Exception {
String response = INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE +
STAT_RESPONSE;
@ -137,13 +126,12 @@ public class Pop3StoreTest {
folder.open();
assertEquals(20, folder.getMessageCount());
assertEquals(AUTH + CAPA + AUTH_PLAIN_WITH_LOGIN + STAT, byteArrayOutputStream.toString("UTF-8"));
assertEquals(CAPA + AUTH_PLAIN_WITH_LOGIN + STAT, byteArrayOutputStream.toString("UTF-8"));
}
@Test(expected = AuthenticationFailedException.class)
public void open_withFailedAuth_shouldThrow() throws Exception {
String response = INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_FAILED_RESPONSE;
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes("UTF-8")));