diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java index 4beb1404e..d20981f24 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapConnection.java @@ -465,6 +465,10 @@ class ImapConnection { try { saslAuthPlain(); } catch (AuthenticationFailedException e) { + if (!isConnected()) { + throw e; + } + login(); } } @@ -486,6 +490,10 @@ class ImapConnection { try { extractCapabilities(responseParser.readStatusResponse(tag, command, getLogId(), null)); } catch (NegativeImapResponseException e) { + if (e.wasByeResponseReceived()) { + close(); + } + throw new AuthenticationFailedException(e.getMessage()); } } diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapResponseParser.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapResponseParser.java index 4176168ee..a3878c9f1 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapResponseParser.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapResponseParser.java @@ -118,8 +118,7 @@ class ImapResponseParser { if (response.size() < 1 || !equalsIgnoreCase(response.get(0), Responses.OK)) { String message = "Command: " + commandToLog + "; response: " + response.toString(); - String alertText = AlertResponse.getAlertText(response); - throw new NegativeImapResponseException(message, alertText); + throw new NegativeImapResponseException(message, responses); } return responses; diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/NegativeImapResponseException.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/NegativeImapResponseException.java index 4bce55424..783cb8ea8 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/NegativeImapResponseException.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/NegativeImapResponseException.java @@ -1,18 +1,39 @@ package com.fsck.k9.mail.store.imap; +import java.util.List; + import com.fsck.k9.mail.MessagingException; +import static com.fsck.k9.mail.store.imap.ImapResponseParser.equalsIgnoreCase; + + class NegativeImapResponseException extends MessagingException { private static final long serialVersionUID = 3725007182205882394L; - private final String alertText; + private final List responses; + private String alertText; - public NegativeImapResponseException(String message, String alertText) { + public NegativeImapResponseException(String message, List responses) { super(message, true); - this.alertText = alertText; + this.responses = responses; } public String getAlertText() { + if (alertText == null) { + ImapResponse lastResponse = responses.get(responses.size() - 1); + alertText = AlertResponse.getAlertText(lastResponse); + } + return alertText; } + + public boolean wasByeResponseReceived() { + for (ImapResponse response : responses) { + if (response.getTag() == null && response.size() >= 1 && equalsIgnoreCase(response.get(0), Responses.BYE)) { + return true; + } + } + + return false; + } } diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapConnectionTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapConnectionTest.java index aa7f2a1ac..7d944f670 100644 --- a/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapConnectionTest.java +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapConnectionTest.java @@ -199,6 +199,32 @@ public class ImapConnectionTest { server.verifyInteractionCompleted(); } + @Test + public void open_authPlainWithByeResponseAndConnectionClose_shouldThrowAuthenticationFailedException() + throws Exception { + settings.setAuthType(AuthType.PLAIN); + MockImapServer server = new MockImapServer(); + preAuthenticationDialog(server, "AUTH=PLAIN"); + server.expect("2 AUTHENTICATE PLAIN"); + server.output("+"); + server.expect(ByteString.encodeUtf8("\000" + USERNAME + "\000" + PASSWORD).base64()); + server.output("* BYE Go away"); + server.output("2 NO Login Failure"); + server.closeConnection(); + ImapConnection imapConnection = startServerAndCreateImapConnection(server); + + try { + imapConnection.open(); + fail("Expected exception"); + } catch (AuthenticationFailedException e) { + //FIXME: improve exception message + assertThat(e.getMessage(), containsString("Login Failure")); + } + + server.verifyConnectionClosed(); + server.verifyInteractionCompleted(); + } + @Test public void open_authPlainWithoutAuthPlainCapability_shouldUseLoginMethod() throws Exception { settings.setAuthType(AuthType.PLAIN);