Merge pull request #2144 from k9mail/GH-2134_authentication_failure_handling
Handle connection closing after authentication failure
This commit is contained in:
commit
3bd84de9c9
4 changed files with 59 additions and 5 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<ImapResponse> responses;
|
||||
private String alertText;
|
||||
|
||||
public NegativeImapResponseException(String message, String alertText) {
|
||||
public NegativeImapResponseException(String message, List<ImapResponse> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue