From 251a221b3b3fd86b11b5f58f2a4fe197c45bf36e Mon Sep 17 00:00:00 2001 From: cketti Date: Tue, 25 Jan 2022 17:19:54 +0100 Subject: [PATCH] Stop using AUTH without arguments (POP3) At least one server software closes the connection right away after receiving the AUTH command without arguments. Since using the AUTH command without arguments never made it into a standard, I decided to completely remove this functionality. --- .../k9/mail/store/pop3/Pop3Connection.java | 37 +----- .../mail/store/pop3/Pop3ConnectionTest.java | 125 +++--------------- .../k9/mail/store/pop3/Pop3StoreTest.java | 16 +-- 3 files changed, 20 insertions(+), 158 deletions(-) diff --git a/mail/protocols/pop3/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Connection.java b/mail/protocols/pop3/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Connection.java index 666d40065..2a0d004e2 100644 --- a/mail/protocols/pop3/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Connection.java +++ b/mail/protocols/pop3/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Connection.java @@ -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; + } } } diff --git a/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3ConnectionTest.java b/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3ConnectionTest.java index 5bcab0b02..9f8d0b6e1 100644 --- a/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3ConnectionTest.java +++ b/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3ConnectionTest.java @@ -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 abcabcd"); - 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 abcabcd"); - 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"); diff --git a/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3StoreTest.java b/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3StoreTest.java index 6363592e4..d7021637c 100644 --- a/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3StoreTest.java +++ b/mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3StoreTest.java @@ -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")));