Repository: thundernest/k-9
Issue: Can't connect to POP3 server (IONOS, GMX, maybe others)

### Checklist

- [X] I have used the search function to see if someone else has already submitted the same bug report.
- [X] I will describe the problem with as much detail as possible.

### App version

5.806

### Where did you get the app from?

Google Play

### Android version

8.0

### Device model

Shift 5me

### Steps to reproduce

Open K-9 mail inbox; start refreshing the view manually.

### Expected behavior

K-9 is supposed to load new mails. Or at least give some error message saying that something's wrong.

### Actual behavior

Nothing. K-9 shows the reload-icon for a second and nothing else happens. Checking the inbox settings reveals an actual error message which I try to translate from German: "Unable to finish setup. Connection to server not possible. (Unable to exectute pop3 command)"

But my server settings are fine. I didn't change anything and other mail clients work ok using the same settings. I also checked if sending a message works: It does.

Restarting the app doesn't help; restarting the phone doesn't help. Currently K-9 is useless for me.

### Logs

_No response_

Changed files:
mail/protocols/pop3/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Connection.java
mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3StoreTest.java
mail/protocols/pop3/src/test/java/com/fsck/k9/mail/store/pop3/Pop3ConnectionTest.java

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 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");
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")));