mirror of https://github.com/moparisthebest/k-9
Throw CertificateValidationException if EXTERNAL authentication fails
This is done when the SASL EXTERNAL mechanism isn't advertised (indicating the possibility that the server did not accept the client certificate) or when the command for authenticating with SASL EXTERNAL fails. The CertificateValidationException will trigger a notification to the user that there's an authentication problem that needs addressing. Also, there were instances where CertificateValidationException was being thrown with a new CertificateException as the cause for the purpose of notifying the user when STARTTLS is not available. This has been slightly simplified by eliminating the need to include a new CertificateException as a cause.
This commit is contained in:
parent
b557ba008c
commit
301ac48a38
|
@ -16,7 +16,11 @@ public class CertificateValidationException extends MessagingException {
|
||||||
|
|
||||||
public CertificateValidationException(String message) {
|
public CertificateValidationException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
scanForCause();
|
/*
|
||||||
|
* Instances created without a Throwable parameter as a cause are
|
||||||
|
* presumed to need user attention.
|
||||||
|
*/
|
||||||
|
mNeedsUserAttention = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CertificateValidationException(final String message, Throwable throwable) {
|
public CertificateValidationException(final String message, Throwable throwable) {
|
||||||
|
@ -45,10 +49,9 @@ public class CertificateValidationException extends MessagingException {
|
||||||
*
|
*
|
||||||
* The various mail protocol handlers (IMAP, POP3, ...) will catch an
|
* The various mail protocol handlers (IMAP, POP3, ...) will catch an
|
||||||
* SSLException and throw a CertificateValidationException (this class)
|
* SSLException and throw a CertificateValidationException (this class)
|
||||||
* with the SSLException as the cause. They may also throw a
|
* with the SSLException as the cause. (They may also throw a
|
||||||
* CertificateValidationException with a new CertificateException as the
|
* CertificateValidationException when STARTTLS is not available, just
|
||||||
* cause when STARTTLS is not available, just for the purpose of
|
* for the purpose of triggering a user notification.)
|
||||||
* triggering a user notification.
|
|
||||||
*
|
*
|
||||||
* SSLHandshakeException is also known to occur if the *client*
|
* SSLHandshakeException is also known to occur if the *client*
|
||||||
* certificate was not accepted by the server (unknown CA, certificate
|
* certificate was not accepted by the server (unknown CA, certificate
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.nio.charset.CharsetDecoder;
|
||||||
import java.nio.charset.CodingErrorAction;
|
import java.nio.charset.CodingErrorAction;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -2511,8 +2510,7 @@ public class ImapStore extends Store {
|
||||||
* "STARTTLS (if available)" setting.
|
* "STARTTLS (if available)" setting.
|
||||||
*/
|
*/
|
||||||
throw new CertificateValidationException(
|
throw new CertificateValidationException(
|
||||||
"STARTTLS connection security not available",
|
"STARTTLS connection security not available");
|
||||||
new CertificateException());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2539,12 +2537,10 @@ public class ImapStore extends Store {
|
||||||
|
|
||||||
case EXTERNAL:
|
case EXTERNAL:
|
||||||
if (hasCapability(CAPABILITY_AUTH_EXTERNAL)) {
|
if (hasCapability(CAPABILITY_AUTH_EXTERNAL)) {
|
||||||
executeSimpleCommand(
|
saslAuthExternal();
|
||||||
String.format("AUTHENTICATE EXTERNAL %s",
|
|
||||||
Utility.base64Encode(mSettings.getUsername())), false);
|
|
||||||
} else {
|
} else {
|
||||||
throw new MessagingException(
|
// Provide notification to user of a problem authenticating using client certificates
|
||||||
"EXTERNAL authentication not advertised by server");
|
throw new CertificateValidationException(K9.app.getString(R.string.auth_external_error));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2729,6 +2725,23 @@ public class ImapStore extends Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saslAuthExternal() throws IOException, MessagingException {
|
||||||
|
try {
|
||||||
|
receiveCapabilities(executeSimpleCommand(
|
||||||
|
String.format("AUTHENTICATE EXTERNAL %s",
|
||||||
|
Utility.base64Encode(mSettings.getUsername())), false));
|
||||||
|
} catch (ImapException e) {
|
||||||
|
/*
|
||||||
|
* Provide notification to the user of a problem authenticating
|
||||||
|
* using client certificates. We don't use an
|
||||||
|
* AuthenticationFailedException because that would trigger a
|
||||||
|
* "Username or password incorrect" notification in
|
||||||
|
* AccountSetupCheckSettings.
|
||||||
|
*/
|
||||||
|
throw new CertificateValidationException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected ImapResponse readContinuationResponse(String tag)
|
protected ImapResponse readContinuationResponse(String tag)
|
||||||
throws IOException, MessagingException {
|
throws IOException, MessagingException {
|
||||||
ImapResponse response;
|
ImapResponse response;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
|
@ -20,7 +21,6 @@ import java.net.*;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -354,8 +354,7 @@ public class Pop3Store extends Store {
|
||||||
* "STARTTLS (if available)" setting.
|
* "STARTTLS (if available)" setting.
|
||||||
*/
|
*/
|
||||||
throw new CertificateValidationException(
|
throw new CertificateValidationException(
|
||||||
"STARTTLS connection security not available",
|
"STARTTLS connection security not available");
|
||||||
new CertificateException());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,12 +377,10 @@ public class Pop3Store extends Store {
|
||||||
|
|
||||||
case EXTERNAL:
|
case EXTERNAL:
|
||||||
if (mCapabilities.external) {
|
if (mCapabilities.external) {
|
||||||
executeSimpleCommand(
|
authExternal();
|
||||||
String.format("AUTH EXTERNAL %s",
|
|
||||||
Utility.base64Encode(mUsername)), false);
|
|
||||||
} else {
|
} else {
|
||||||
throw new MessagingException(
|
// Provide notification to user of a problem authenticating using client certificates
|
||||||
"EXTERNAL authentication not advertised by server");
|
throw new CertificateValidationException(K9.app.getString(R.string.auth_external_error));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -470,6 +467,24 @@ public class Pop3Store extends Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void authExternal() throws MessagingException {
|
||||||
|
try {
|
||||||
|
executeSimpleCommand(
|
||||||
|
String.format("AUTH EXTERNAL %s",
|
||||||
|
Utility.base64Encode(mUsername)), false);
|
||||||
|
} catch (Pop3ErrorResponse e) {
|
||||||
|
/*
|
||||||
|
* Provide notification to the user of a problem authenticating
|
||||||
|
* using client certificates. We don't use an
|
||||||
|
* AuthenticationFailedException because that would trigger a
|
||||||
|
* "Username or password incorrect" notification in
|
||||||
|
* AccountSetupCheckSettings.
|
||||||
|
*/
|
||||||
|
throw new CertificateValidationException(
|
||||||
|
"POP3 client certificate authentication failed: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return (mIn != null && mOut != null && mSocket != null
|
return (mIn != null && mOut != null && mSocket != null
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class SmtpTransport extends Transport {
|
public class SmtpTransport extends Transport {
|
||||||
|
@ -300,8 +299,7 @@ public class SmtpTransport extends Transport {
|
||||||
* "STARTTLS (if available)" setting.
|
* "STARTTLS (if available)" setting.
|
||||||
*/
|
*/
|
||||||
throw new CertificateValidationException(
|
throw new CertificateValidationException(
|
||||||
"STARTTLS connection security not available",
|
"STARTTLS connection security not available");
|
||||||
new CertificateException());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue