diff --git a/res/values/strings.xml b/res/values/strings.xml
index 44e80e7ad..d1b691547 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -221,6 +221,8 @@ Please submit bug reports, contribute new features and ask questions at
Reply
Read
Delete
+ Certificate error
+ Check your server settings
Checking mail: %s:%s
Checking mail
diff --git a/src/com/fsck/k9/K9.java b/src/com/fsck/k9/K9.java
index f9ade23e5..124290ce8 100644
--- a/src/com/fsck/k9/K9.java
+++ b/src/com/fsck/k9/K9.java
@@ -345,12 +345,14 @@ public class K9 extends Application {
- public static final int NOTIFICATION_LED_SENDING_FAILURE_COLOR = 0xffff0000;
+ public static final int NOTIFICATION_LED_FAILURE_COLOR = 0xffff0000;
// Must not conflict with an account number
public static final int FETCHING_EMAIL_NOTIFICATION = -5000;
public static final int SEND_FAILED_NOTIFICATION = -1500;
public static final int CONNECTIVITY_ID = -3;
+ public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING = -4;
+ public static final int CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING = -5;
public static class Intents {
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
index 6ce001788..bf4773c9b 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
@@ -3,6 +3,9 @@ package com.fsck.k9.activity.setup;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.Application;
+import android.app.NotificationManager;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
@@ -105,6 +108,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
finish();
return;
}
+ clearCertificateErrorNotifications();
if (mCheckIncoming) {
store = mAccount.getRemoteStore();
@@ -195,6 +199,19 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
});
}
+ private void clearCertificateErrorNotifications() {
+ final Application app = getApplication();
+ final NotificationManager notifMgr = (NotificationManager) app
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ final String uuid = mAccount.getUuid();
+ if (mCheckOutgoing){
+ notifMgr.cancel(uuid, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING);
+ }
+ if (mCheckIncoming){
+ notifMgr.cancel(uuid, K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING);
+ }
+ }
+
private void showErrorDialog(final int msgResId, final Object... args) {
mHandler.post(new Runnable() {
public void run() {
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index 23fa80406..4e341aa28 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -33,7 +33,7 @@ import java.util.HashMap;
import java.util.Map;
public class AccountSetupIncoming extends K9Activity implements OnClickListener {
- private static final String EXTRA_ACCOUNT = "account";
+ public static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final int[] POP3_PORTS = {
diff --git a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
index 15f1c9bb4..d49059a43 100644
--- a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
+++ b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
@@ -26,7 +26,7 @@ import java.net.URLEncoder;
public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
OnCheckedChangeListener {
- private static final String EXTRA_ACCOUNT = "account";
+ public static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java
index 07b22e6d2..f2284c9e7 100644
--- a/src/com/fsck/k9/controller/MessagingController.java
+++ b/src/com/fsck/k9/controller/MessagingController.java
@@ -3295,13 +3295,30 @@ public class MessagingController implements Runnable {
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
builder.setContentIntent(pi);
- configureNotification(builder, null, null, K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR,
+ configureNotification(builder, null, null, K9.NOTIFICATION_LED_FAILURE_COLOR,
K9.NOTIFICATION_LED_BLINK_FAST, true);
notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(),
builder.build());
}
+ public void notify(String tag, int id, String title, String text, PendingIntent pi) {
+ final NotificationManager notifMgr = (NotificationManager) mApplication
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(mApplication);
+ builder.setSmallIcon(R.drawable.stat_notify_email_generic);
+ builder.setWhen(System.currentTimeMillis());
+ builder.setAutoCancel(true);
+ builder.setTicker(title);
+ builder.setContentTitle(title);
+ builder.setContentText(text);
+ builder.setContentIntent(pi);
+ configureNotification(builder, null, null,
+ K9.NOTIFICATION_LED_FAILURE_COLOR,
+ K9.NOTIFICATION_LED_BLINK_FAST, true);
+ notifMgr.notify(tag, id, builder.build());
+ }
+
/**
* Display an ongoing notification while checking for new messages on the server.
*
diff --git a/src/com/fsck/k9/mail/CertificateValidationException.java b/src/com/fsck/k9/mail/CertificateValidationException.java
index ed35cf8ac..b34b66f44 100644
--- a/src/com/fsck/k9/mail/CertificateValidationException.java
+++ b/src/com/fsck/k9/mail/CertificateValidationException.java
@@ -1,6 +1,18 @@
package com.fsck.k9.mail;
+import android.app.Application;
+import android.app.PendingIntent;
+import android.content.Intent;
+import com.fsck.k9.Account;
+import com.fsck.k9.K9;
+import com.fsck.k9.R;
+import com.fsck.k9.activity.setup.AccountSetupIncoming;
+import com.fsck.k9.activity.setup.AccountSetupOutgoing;
+import com.fsck.k9.controller.MessagingController;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertificateException;
+
public class CertificateValidationException extends MessagingException {
public static final long serialVersionUID = -1;
@@ -8,7 +20,44 @@ public class CertificateValidationException extends MessagingException {
super(message);
}
- public CertificateValidationException(String message, Throwable throwable) {
+ public CertificateValidationException(final String message,
+ Throwable throwable, final Account account, final boolean incoming) {
super(message, throwable);
+ /*
+ * We get here because of an SSLException. We are only interested in
+ * creating a notification if the underlying cause is certificate
+ * related.
+ */
+ while (throwable != null
+ && !(throwable instanceof CertPathValidatorException)
+ && !(throwable instanceof CertificateException)) {
+ throwable = throwable.getCause();
+ }
+ if (throwable == null)
+ return;
+ final Application app = K9.app;
+ final String title = app
+ .getString(R.string.notification_certificate_error_title);
+ final String text = app
+ .getString(R.string.notification_certificate_error_text);
+ final Class> className;
+ final String extraName;
+ final int id;
+ if (incoming) {
+ className = AccountSetupIncoming.class;
+ extraName = AccountSetupIncoming.EXTRA_ACCOUNT;
+ id = K9.CERTIFICATE_EXCEPTION_NOTIFICATION_INCOMING;
+ } else {
+ className = AccountSetupOutgoing.class;
+ extraName = AccountSetupOutgoing.EXTRA_ACCOUNT;
+ id = K9.CERTIFICATE_EXCEPTION_NOTIFICATION_OUTGOING;
+ }
+ final Intent i = new Intent(app, className);
+ final String uuid = account.getUuid();
+ i.setAction(Intent.ACTION_EDIT);
+ i.putExtra(extraName, uuid);
+ final PendingIntent pi = PendingIntent.getActivity(app, 0, i, 0);
+ MessagingController controller = MessagingController.getInstance(app);
+ controller.notify(uuid, id, title, text, pi);
}
}
\ No newline at end of file
diff --git a/src/com/fsck/k9/mail/Transport.java b/src/com/fsck/k9/mail/Transport.java
index a0450ffeb..28011dacd 100644
--- a/src/com/fsck/k9/mail/Transport.java
+++ b/src/com/fsck/k9/mail/Transport.java
@@ -14,7 +14,7 @@ public abstract class Transport {
public synchronized static Transport getInstance(Account account) throws MessagingException {
String uri = account.getTransportUri();
if (uri.startsWith("smtp")) {
- return new SmtpTransport(uri);
+ return new SmtpTransport(account);
} else if (uri.startsWith("webdav")) {
return new WebDavTransport(account);
} else {
diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java
index 9bca9990e..9b0efca3f 100644
--- a/src/com/fsck/k9/mail/store/ImapStore.java
+++ b/src/com/fsck/k9/mail/store/ImapStore.java
@@ -429,6 +429,10 @@ public class ImapStore extends Store {
mCombinedPrefix = prefix;
}
+ @Override
+ public Account getAccount() {
+ return mAccount;
+ }
}
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
@@ -2623,7 +2627,7 @@ public class ImapStore extends Store {
} catch (SSLException e) {
- throw new CertificateValidationException(e.getMessage(), e);
+ throw new CertificateValidationException(e.getMessage(), e, mSettings.getAccount(), true);
} catch (GeneralSecurityException gse) {
throw new MessagingException(
"Unable to open connection to IMAP server due to security error.", gse);
diff --git a/src/com/fsck/k9/mail/store/Pop3Store.java b/src/com/fsck/k9/mail/store/Pop3Store.java
index ec7c56961..85b85110b 100644
--- a/src/com/fsck/k9/mail/store/Pop3Store.java
+++ b/src/com/fsck/k9/mail/store/Pop3Store.java
@@ -391,7 +391,7 @@ public class Pop3Store extends Store {
mCapabilities = getCapabilities();
} catch (SSLException e) {
- throw new CertificateValidationException(e.getMessage(), e);
+ throw new CertificateValidationException(e.getMessage(), e, mAccount, true);
} catch (GeneralSecurityException gse) {
throw new MessagingException(
"Unable to open connection to POP server due to security error.", gse);
diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java
index 770e61e38..26199a285 100644
--- a/src/com/fsck/k9/mail/store/WebDavStore.java
+++ b/src/com/fsck/k9/mail/store/WebDavStore.java
@@ -848,7 +848,7 @@ public class WebDavStore extends Store {
response.getStatusLine().toString());
}
} catch (SSLException e) {
- throw new CertificateValidationException(e.getMessage(), e);
+ throw new CertificateValidationException(e.getMessage(), e, mAccount, true);
} catch (IOException ioe) {
Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
throw new MessagingException("IOException", ioe);
diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java
index 050a582b3..99cd76d61 100644
--- a/src/com/fsck/k9/mail/transport/SmtpTransport.java
+++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java
@@ -182,6 +182,7 @@ public class SmtpTransport extends Transport {
}
+ Account mAccount;
String mHost;
int mPort;
String mUsername;
@@ -194,14 +195,15 @@ public class SmtpTransport extends Transport {
private boolean m8bitEncodingAllowed;
private int mLargestAcceptableMessage;
- public SmtpTransport(String uri) throws MessagingException {
+ public SmtpTransport(Account account) throws MessagingException {
ServerSettings settings;
try {
- settings = decodeUri(uri);
+ settings = decodeUri(account.getTransportUri());
} catch (IllegalArgumentException e) {
throw new MessagingException("Error while decoding transport URI", e);
}
+ mAccount = account;
mHost = settings.host;
mPort = settings.port;
@@ -387,7 +389,7 @@ public class SmtpTransport extends Transport {
}
}
} catch (SSLException e) {
- throw new CertificateValidationException(e.getMessage(), e);
+ throw new CertificateValidationException(e.getMessage(), e, mAccount, false);
} catch (GeneralSecurityException gse) {
throw new MessagingException(
"Unable to open connection to SMTP server due to security error.", gse);
diff --git a/src/com/fsck/k9/mail/transport/imap/ImapSettings.java b/src/com/fsck/k9/mail/transport/imap/ImapSettings.java
index 769763015..7e367cac6 100644
--- a/src/com/fsck/k9/mail/transport/imap/ImapSettings.java
+++ b/src/com/fsck/k9/mail/transport/imap/ImapSettings.java
@@ -1,5 +1,6 @@
package com.fsck.k9.mail.transport.imap;
+import com.fsck.k9.Account;
import com.fsck.k9.mail.store.ImapStore;
import com.fsck.k9.mail.store.ImapStore.AuthType;
import com.fsck.k9.mail.store.ImapStore.ImapConnection;
@@ -34,4 +35,6 @@ public interface ImapSettings {
void setCombinedPrefix(String prefix);
+ Account getAccount();
+
}