mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-25 17:18:50 -05:00
Merge remote-tracking branch 'zjw/issue_2389_cert_error_notice2'
* zjw/issue_2389_cert_error_notice2: Fix Issue 2389: Self signed certificate expiry causes silent send/receive failure.
This commit is contained in:
commit
ae6c7e37ca
@ -221,6 +221,8 @@ Please submit bug reports, contribute new features and ask questions at
|
|||||||
<string name="notification_action_reply">Reply</string>
|
<string name="notification_action_reply">Reply</string>
|
||||||
<string name="notification_action_read">Read</string>
|
<string name="notification_action_read">Read</string>
|
||||||
<string name="notification_action_delete">Delete</string>
|
<string name="notification_action_delete">Delete</string>
|
||||||
|
<string name="notification_certificate_error_title">Certificate error</string>
|
||||||
|
<string name="notification_certificate_error_text">Check your server settings</string>
|
||||||
|
|
||||||
<string name="notification_bg_sync_ticker">Checking mail: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string>
|
<string name="notification_bg_sync_ticker">Checking mail: <xliff:g id="account">%s</xliff:g>:<xliff:g id="folder">%s</xliff:g></string>
|
||||||
<string name="notification_bg_sync_title">Checking mail</string>
|
<string name="notification_bg_sync_title">Checking mail</string>
|
||||||
|
@ -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
|
// Must not conflict with an account number
|
||||||
public static final int FETCHING_EMAIL_NOTIFICATION = -5000;
|
public static final int FETCHING_EMAIL_NOTIFICATION = -5000;
|
||||||
public static final int SEND_FAILED_NOTIFICATION = -1500;
|
public static final int SEND_FAILED_NOTIFICATION = -1500;
|
||||||
public static final int CONNECTIVITY_ID = -3;
|
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 {
|
public static class Intents {
|
||||||
|
@ -3,6 +3,9 @@ package com.fsck.k9.activity.setup;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Application;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -105,6 +108,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
clearCertificateErrorNotifications();
|
||||||
if (mCheckIncoming) {
|
if (mCheckIncoming) {
|
||||||
store = mAccount.getRemoteStore();
|
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) {
|
private void showErrorDialog(final int msgResId, final Object... args) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -33,7 +33,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class AccountSetupIncoming extends K9Activity implements OnClickListener {
|
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 String EXTRA_MAKE_DEFAULT = "makeDefault";
|
||||||
|
|
||||||
private static final int[] POP3_PORTS = {
|
private static final int[] POP3_PORTS = {
|
||||||
|
@ -26,7 +26,7 @@ import java.net.URLEncoder;
|
|||||||
|
|
||||||
public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
||||||
OnCheckedChangeListener {
|
OnCheckedChangeListener {
|
||||||
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 String EXTRA_MAKE_DEFAULT = "makeDefault";
|
||||||
|
|
||||||
|
@ -3295,13 +3295,30 @@ public class MessagingController implements Runnable {
|
|||||||
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
|
||||||
builder.setContentIntent(pi);
|
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);
|
K9.NOTIFICATION_LED_BLINK_FAST, true);
|
||||||
|
|
||||||
notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(),
|
notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(),
|
||||||
builder.build());
|
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.
|
* Display an ongoing notification while checking for new messages on the server.
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
|
|
||||||
package com.fsck.k9.mail;
|
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 class CertificateValidationException extends MessagingException {
|
||||||
public static final long serialVersionUID = -1;
|
public static final long serialVersionUID = -1;
|
||||||
|
|
||||||
@ -8,7 +20,44 @@ public class CertificateValidationException extends MessagingException {
|
|||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CertificateValidationException(String message, Throwable throwable) {
|
public CertificateValidationException(final String message,
|
||||||
|
Throwable throwable, final Account account, final boolean incoming) {
|
||||||
super(message, throwable);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ public abstract class Transport {
|
|||||||
public synchronized static Transport getInstance(Account account) throws MessagingException {
|
public synchronized static Transport getInstance(Account account) throws MessagingException {
|
||||||
String uri = account.getTransportUri();
|
String uri = account.getTransportUri();
|
||||||
if (uri.startsWith("smtp")) {
|
if (uri.startsWith("smtp")) {
|
||||||
return new SmtpTransport(uri);
|
return new SmtpTransport(account);
|
||||||
} else if (uri.startsWith("webdav")) {
|
} else if (uri.startsWith("webdav")) {
|
||||||
return new WebDavTransport(account);
|
return new WebDavTransport(account);
|
||||||
} else {
|
} else {
|
||||||
|
@ -429,6 +429,10 @@ public class ImapStore extends Store {
|
|||||||
mCombinedPrefix = prefix;
|
mCombinedPrefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Account getAccount() {
|
||||||
|
return mAccount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
|
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) {
|
} catch (SSLException e) {
|
||||||
throw new CertificateValidationException(e.getMessage(), e);
|
throw new CertificateValidationException(e.getMessage(), e, mSettings.getAccount(), true);
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
throw new MessagingException(
|
throw new MessagingException(
|
||||||
"Unable to open connection to IMAP server due to security error.", gse);
|
"Unable to open connection to IMAP server due to security error.", gse);
|
||||||
|
@ -391,7 +391,7 @@ public class Pop3Store extends Store {
|
|||||||
|
|
||||||
mCapabilities = getCapabilities();
|
mCapabilities = getCapabilities();
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
throw new CertificateValidationException(e.getMessage(), e);
|
throw new CertificateValidationException(e.getMessage(), e, mAccount, true);
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
throw new MessagingException(
|
throw new MessagingException(
|
||||||
"Unable to open connection to POP server due to security error.", gse);
|
"Unable to open connection to POP server due to security error.", gse);
|
||||||
|
@ -848,7 +848,7 @@ public class WebDavStore extends Store {
|
|||||||
response.getStatusLine().toString());
|
response.getStatusLine().toString());
|
||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
throw new CertificateValidationException(e.getMessage(), e);
|
throw new CertificateValidationException(e.getMessage(), e, mAccount, true);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
|
Log.e(K9.LOG_TAG, "IOException: " + ioe + "\nTrace: " + processException(ioe));
|
||||||
throw new MessagingException("IOException", ioe);
|
throw new MessagingException("IOException", ioe);
|
||||||
|
@ -182,6 +182,7 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Account mAccount;
|
||||||
String mHost;
|
String mHost;
|
||||||
int mPort;
|
int mPort;
|
||||||
String mUsername;
|
String mUsername;
|
||||||
@ -194,14 +195,15 @@ public class SmtpTransport extends Transport {
|
|||||||
private boolean m8bitEncodingAllowed;
|
private boolean m8bitEncodingAllowed;
|
||||||
private int mLargestAcceptableMessage;
|
private int mLargestAcceptableMessage;
|
||||||
|
|
||||||
public SmtpTransport(String uri) throws MessagingException {
|
public SmtpTransport(Account account) throws MessagingException {
|
||||||
ServerSettings settings;
|
ServerSettings settings;
|
||||||
try {
|
try {
|
||||||
settings = decodeUri(uri);
|
settings = decodeUri(account.getTransportUri());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new MessagingException("Error while decoding transport URI", e);
|
throw new MessagingException("Error while decoding transport URI", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAccount = account;
|
||||||
mHost = settings.host;
|
mHost = settings.host;
|
||||||
mPort = settings.port;
|
mPort = settings.port;
|
||||||
|
|
||||||
@ -387,7 +389,7 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SSLException e) {
|
} catch (SSLException e) {
|
||||||
throw new CertificateValidationException(e.getMessage(), e);
|
throw new CertificateValidationException(e.getMessage(), e, mAccount, false);
|
||||||
} catch (GeneralSecurityException gse) {
|
} catch (GeneralSecurityException gse) {
|
||||||
throw new MessagingException(
|
throw new MessagingException(
|
||||||
"Unable to open connection to SMTP server due to security error.", gse);
|
"Unable to open connection to SMTP server due to security error.", gse);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.fsck.k9.mail.transport.imap;
|
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;
|
||||||
import com.fsck.k9.mail.store.ImapStore.AuthType;
|
import com.fsck.k9.mail.store.ImapStore.AuthType;
|
||||||
import com.fsck.k9.mail.store.ImapStore.ImapConnection;
|
import com.fsck.k9.mail.store.ImapStore.ImapConnection;
|
||||||
@ -34,4 +35,6 @@ public interface ImapSettings {
|
|||||||
|
|
||||||
void setCombinedPrefix(String prefix);
|
void setCombinedPrefix(String prefix);
|
||||||
|
|
||||||
|
Account getAccount();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user