diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java index 9eefc98c9..60c814b10 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java @@ -186,10 +186,11 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList } else { showErrorDialog( R.string.account_setup_failed_dlg_server_message_fmt, - (cve.getMessage() == null ? "" : cve.getMessage())); + errorMessageForCertificateException(cve)); } } + @Override public void onDestroy() { super.onDestroy(); @@ -461,4 +462,15 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList public void dialogCancelled(int dialogId) { // nothing to do here... } + + private String errorMessageForCertificateException(CertificateValidationException e) { + switch (e.getReason()) { + case Expired: return getString(R.string.client_certificate_expired, e.getAlias(), e.getMessage()); + case MissingCapability: return getString(R.string.auth_external_error); + case RetrievalFailure: return getString(R.string.client_certificate_retrieval_failure, e.getAlias()); + case UseMessage: return e.getMessage(); + case Unknown: + default: return ""; + } + } } diff --git a/src/com/fsck/k9/mail/CertificateChainException.java b/src/com/fsck/k9/mail/CertificateChainException.java index c76145607..2dc1af204 100644 --- a/src/com/fsck/k9/mail/CertificateChainException.java +++ b/src/com/fsck/k9/mail/CertificateChainException.java @@ -24,5 +24,4 @@ public class CertificateChainException extends CertificateException { public X509Certificate[] getCertChain() { return mCertChain; } - } diff --git a/src/com/fsck/k9/mail/CertificateValidationException.java b/src/com/fsck/k9/mail/CertificateValidationException.java index d853b80bf..18bd457f1 100644 --- a/src/com/fsck/k9/mail/CertificateValidationException.java +++ b/src/com/fsck/k9/mail/CertificateValidationException.java @@ -11,23 +11,48 @@ import android.security.KeyChainException; public class CertificateValidationException extends MessagingException { public static final long serialVersionUID = -1; + private final Reason mReason; private X509Certificate[] mCertChain; private boolean mNeedsUserAttention = false; + private String mAlias; + + public enum Reason { + Unknown, UseMessage, Expired, MissingCapability, RetrievalFailure + } public CertificateValidationException(String message) { + this(message, Reason.UseMessage, null); + } + + public CertificateValidationException(Reason reason) { + this(null, reason, null); + } + + public CertificateValidationException(String message, Reason reason, String alias) { super(message); /* * Instances created without a Throwable parameter as a cause are * presumed to need user attention. */ mNeedsUserAttention = true; + mReason = reason; + mAlias = alias; } public CertificateValidationException(final String message, Throwable throwable) { super(message, throwable); + mReason = Reason.Unknown; scanForCause(); } + public String getAlias() { + return mAlias; + } + + public Reason getReason() { + return mReason; + } + private void scanForCause() { Throwable throwable = getCause(); @@ -101,4 +126,4 @@ public class CertificateValidationException extends MessagingException { public X509Certificate[] getCertChain() { return mCertChain; } -} \ No newline at end of file +} diff --git a/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java index 273b7dd9a..80a412e18 100644 --- a/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java +++ b/src/com/fsck/k9/mail/ssl/KeyChainKeyManager.java @@ -20,11 +20,12 @@ import android.security.KeyChain; import android.security.KeyChainException; import android.util.Log; -import com.fsck.k9.R; import com.fsck.k9.mail.CertificateValidationException; import com.fsck.k9.mail.MessagingException; import static com.fsck.k9.mail.K9MailLib.LOG_TAG; +import static com.fsck.k9.mail.CertificateValidationException.Reason; +import static com.fsck.k9.mail.CertificateValidationException.Reason.RetrievalFailure; /** * For client certificate authentication! Provide private keys and certificates @@ -61,13 +62,9 @@ class KeyChainKeyManager extends X509ExtendedKeyManager { mPrivateKey = fetchPrivateKey(context, alias); } catch (KeyChainException e) { // The certificate was possibly deleted. Notify user of error. - final String message = context.getString( - R.string.client_certificate_retrieval_failure, alias); - throw new CertificateValidationException(message, e); + throw new CertificateValidationException(e.getMessage(), RetrievalFailure, alias); } catch (InterruptedException e) { - final String message = context.getString( - R.string.client_certificate_retrieval_failure, alias); - throw new MessagingException(message, e); + throw new CertificateValidationException(e.getMessage(), RetrievalFailure, alias); } } @@ -83,8 +80,7 @@ class KeyChainKeyManager extends X509ExtendedKeyManager { certificate.checkValidity(); } } catch (CertificateException e) { - // Client certificate has expired or is not yet valid - throw new CertificateValidationException(context.getString(R.string.client_certificate_expired, alias, e.toString())); + throw new CertificateValidationException(e.getMessage(), Reason.Expired, alias); } return chain; diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index ae54c870b..b9655b4fe 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -56,7 +56,6 @@ import android.text.TextUtils; import android.util.Log; import com.fsck.k9.K9; -import com.fsck.k9.R; import com.fsck.k9.helper.power.TracingPowerManager; import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock; import com.fsck.k9.mail.AuthType; @@ -98,6 +97,7 @@ import org.apache.commons.io.IOUtils; import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_IMAP; import static com.fsck.k9.mail.K9MailLib.LOG_TAG; import static com.fsck.k9.mail.K9MailLib.PUSH_WAKE_LOCK_TIMEOUT; +import static com.fsck.k9.mail.CertificateValidationException.Reason; /** *
@@ -687,7 +687,7 @@ public class ImapStore extends RemoteStore { autoconfigureFolders(connection); connection.close(); } catch (IOException ioe) { - throw new MessagingException(K9.app.getString(R.string.error_unable_to_connect), ioe); + throw new MessagingException("Unable to connect", ioe); } } @@ -2510,7 +2510,7 @@ public class ImapStore extends RemoteStore { saslAuthExternal(); } else { // Provide notification to user of a problem authenticating using client certificates - throw new CertificateValidationException(K9.app.getString(R.string.auth_external_error)); + throw new CertificateValidationException(Reason.MissingCapability); } break; diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java index 73366e4ae..0aeb0a9db 100644 --- a/src/com/fsck/k9/mail/store/Pop3Store.java +++ b/src/com/fsck/k9/mail/store/Pop3Store.java @@ -3,12 +3,11 @@ package com.fsck.k9.mail.store; import android.util.Log; -import com.fsck.k9.K9; -import com.fsck.k9.R; import com.fsck.k9.mail.*; import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.filter.Hex; import com.fsck.k9.mail.internet.MimeMessage; +import com.fsck.k9.mail.CertificateValidationException; import com.fsck.k9.mail.ssl.TrustedSocketFactory; import com.fsck.k9.mail.MessageRetrievalListener; @@ -33,6 +32,7 @@ import java.util.Set; import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_POP3; import static com.fsck.k9.mail.K9MailLib.LOG_TAG; +import static com.fsck.k9.mail.CertificateValidationException.Reason.MissingCapability; public class Pop3Store extends RemoteStore { public static final String STORE_TYPE = "POP3"; @@ -369,7 +369,7 @@ public class Pop3Store extends RemoteStore { authExternal(); } else { // Provide notification to user of a problem authenticating using client certificates - throw new CertificateValidationException(K9.app.getString(R.string.auth_external_error)); + throw new CertificateValidationException(MissingCapability); } break; diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java index 9944c6a9e..c12d1cda6 100644 --- a/src/com/fsck/k9/mail/store/WebDavStore.java +++ b/src/com/fsck/k9/mail/store/WebDavStore.java @@ -7,6 +7,7 @@ import com.fsck.k9.mail.filter.Base64; import com.fsck.k9.mail.filter.EOLConvertingOutputStream; import com.fsck.k9.mail.internet.MimeMessage; import com.fsck.k9.mail.MessageRetrievalListener; +import com.fsck.k9.mail.CertificateValidationException; import org.apache.commons.io.IOUtils; import org.apache.http.*; diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 485e45f02..0e4c39441 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -3,8 +3,6 @@ package com.fsck.k9.mail.transport; import android.util.Log; -import com.fsck.k9.K9; -import com.fsck.k9.R; import com.fsck.k9.mail.*; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.filter.Base64; @@ -13,6 +11,7 @@ import com.fsck.k9.mail.filter.LineWrapOutputStream; import com.fsck.k9.mail.filter.PeekableInputStream; import com.fsck.k9.mail.filter.SmtpDataStuffing; import com.fsck.k9.mail.internet.CharsetSupport; +import com.fsck.k9.mail.CertificateValidationException; import com.fsck.k9.mail.store.StoreConfig; import com.fsck.k9.mail.ssl.TrustedSocketFactory; @@ -28,6 +27,7 @@ import java.util.*; import static com.fsck.k9.mail.K9MailLib.DEBUG_PROTOCOL_SMTP; import static com.fsck.k9.mail.K9MailLib.LOG_TAG; +import static com.fsck.k9.mail.CertificateValidationException.Reason.MissingCapability; public class SmtpTransport extends Transport { public static final String TRANSPORT_TYPE = "SMTP"; @@ -357,7 +357,7 @@ public class SmtpTransport extends Transport { * EXTERNAL when using client certificates. That way, the * user can be notified of a problem during account setup. */ - throw new MessagingException(K9.app.getString(R.string.auth_external_error)); + throw new CertificateValidationException(MissingCapability); } break;