[geary/wip/713247-tls] Fixed for SMTP/Outbox
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/713247-tls] Fixed for SMTP/Outbox
- Date: Wed, 27 Aug 2014 23:01:32 +0000 (UTC)
commit 551b98be86b97c4f3e331e1da5d6749f00544a64
Author: Jim Nelson <jim yorba org>
Date: Wed Aug 27 16:01:22 2014 -0700
Fixed for SMTP/Outbox
src/client/application/geary-controller.vala | 2 +-
src/client/dialogs/certificate-warning-dialog.vala | 7 ++-
src/engine/api/geary-endpoint.vala | 21 +++++++++
src/engine/api/geary-service.vala | 22 ++++++++++
src/engine/imap-db/outbox/smtp-outbox-folder.vala | 45 ++++++++++++++-----
src/engine/smtp/smtp-client-connection.vala | 11 ++++-
6 files changed, 91 insertions(+), 17 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index cb19076..43af7b6 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -520,7 +520,7 @@ public class GearyController : Geary.BaseObject {
return;
CertificateWarningDialog dialog = new CertificateWarningDialog(main_window, endpoint,
- warnings);
+ service, warnings);
switch (dialog.run()) {
case CertificateWarningDialog.Result.TRUST:
endpoint.trust_untrusted_host = Geary.Trillian.TRUE;
diff --git a/src/client/dialogs/certificate-warning-dialog.vala
b/src/client/dialogs/certificate-warning-dialog.vala
index 816402c..b95fc6a 100644
--- a/src/client/dialogs/certificate-warning-dialog.vala
+++ b/src/client/dialogs/certificate-warning-dialog.vala
@@ -17,7 +17,8 @@ public class CertificateWarningDialog {
private Gtk.Label top_label;
private Gtk.Label warnings_label;
- public CertificateWarningDialog(Gtk.Window? parent, Geary.Endpoint endpoint, TlsCertificateFlags
warnings) {
+ public CertificateWarningDialog(Gtk.Window? parent, Geary.Endpoint endpoint, Geary.Service service,
+ TlsCertificateFlags warnings) {
Gtk.Builder builder = GearyApplication.instance.create_builder("certificate_warning_dialog.glade");
dialog = (Gtk.Dialog) builder.get_object("CertificateWarningDialog");
@@ -27,8 +28,8 @@ public class CertificateWarningDialog {
dialog.transient_for = parent;
dialog.modal = true;
- top_label.label = _("The identity of the mail server at %s:%u could not be verified:").printf(
- endpoint.remote_address.hostname, endpoint.remote_address.port);
+ top_label.label = _("The identity of the %s mail server at %s:%u could not be verified:").printf(
+ service.user_label(), endpoint.remote_address.hostname, endpoint.remote_address.port);
warnings_label.label = generate_warning_list(warnings);
warnings_label.use_markup = true;
diff --git a/src/engine/api/geary-endpoint.vala b/src/engine/api/geary-endpoint.vala
index bbbd0a1..1386c4a 100644
--- a/src/engine/api/geary-endpoint.vala
+++ b/src/engine/api/geary-endpoint.vala
@@ -66,6 +66,27 @@ public class Geary.Endpoint : BaseObject {
*/
public Trillian trust_untrusted_host { get; set; default = Trillian.UNKNOWN; }
+ /**
+ * Returns true if (a) no TLS warnings have been detected or (b) user has explicitly acceded
+ * to ignoring them and continuing the connection.
+ *
+ * This returns true if no connection has been attempted or connected and STARTTLS has not
+ * been issued. It's only when a connection is attempted can the certificate be examined
+ * and this can accurately return false. This behavior allows for a single code path to
+ * first attempt a connection and thereafter only attempt connections when TLS issues have
+ * been resolved by the user.
+ *
+ * @see tls_validation_warnings
+ * @see trust_untrusted_host
+ */
+ public bool is_trusted_or_unconnected {
+ get {
+ return (tls_validation_warnings != 0)
+ ? trust_untrusted_host.is_certain()
+ : trust_untrusted_host.is_possible();
+ }
+ }
+
public bool is_ssl { get {
return flags.is_all_set(Flags.SSL);
} }
diff --git a/src/engine/api/geary-service.vala b/src/engine/api/geary-service.vala
index 679e9d1..7745293 100644
--- a/src/engine/api/geary-service.vala
+++ b/src/engine/api/geary-service.vala
@@ -4,11 +4,33 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+/**
+ * The type of mail service provided by a particular destination.
+ */
public enum Geary.Service {
IMAP,
SMTP;
+
+ /**
+ * Returns a user-visible label for the { link Service}.
+ */
+ public string user_label() {
+ switch (this) {
+ case IMAP:
+ return _("IMAP");
+
+ case SMTP:
+ return _("SMTP");
+
+ default:
+ assert_not_reached();
+ }
+ }
}
+/**
+ * A bitfield of { link Service}s.
+ */
[Flags]
public enum Geary.ServiceFlag {
IMAP,
diff --git a/src/engine/imap-db/outbox/smtp-outbox-folder.vala
b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
index f994786..c190e15 100644
--- a/src/engine/imap-db/outbox/smtp-outbox-folder.vala
+++ b/src/engine/imap-db/outbox/smtp-outbox-folder.vala
@@ -215,16 +215,26 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
}
// Send the message, but only remove from database once sent
+ bool should_nap = false;
+ bool mail_sent = false;
try {
- debug("Outbox postman: Sending \"%s\" (ID:%s)...", message_subject(message),
- row.outbox_id.to_string());
- yield send_email_async(message, null);
+ // only try if (a) no TLS issues or (b) user has acknowledged them and says to
+ // continue
+ if (_account.information.get_smtp_endpoint().is_trusted_or_unconnected) {
+ debug("Outbox postman: Sending \"%s\" (ID:%s)...", message_subject(message),
+ row.outbox_id.to_string());
+ yield send_email_async(message, null);
+ mail_sent = true;
+ } else {
+ // user was warned via Geary.Engine signal, need to wait for that to be cleared
+ // befor sending
+ outbox_queue.send(row);
+ should_nap = true;
+ }
} catch (Error send_err) {
debug("Outbox postman send error, retrying: %s", send_err.message);
- outbox_queue.send(row);
-
- bool should_nap = true;
+ should_nap = true;
if (send_err is SmtpError.AUTHENTICATION_FAILED) {
bool report = true;
@@ -243,16 +253,27 @@ private class Geary.SmtpOutboxFolder : Geary.AbstractLocalFolder, Geary.FolderSu
if (report)
report_problem(Geary.Account.Problem.SEND_EMAIL_LOGIN_FAILED, send_err);
+ } else if (send_err is TlsError) {
+ // up to application to be aware of problem via Geary.Engine, but do nap and
+ // try later
+ debug("TLS connection warnings connecting to %s, user must confirm connection to
continue",
+ _account.information.get_smtp_endpoint().to_string());
} else {
report_problem(Geary.Account.Problem.EMAIL_DELIVERY_FAILURE, send_err);
}
+ }
+
+ if (should_nap) {
+ debug("Outbox napping for %u seconds...", send_retry_seconds);
- if (should_nap) {
- // Take a brief nap before continuing to allow connection problems to resolve.
- yield Geary.Scheduler.sleep_async(send_retry_seconds);
- send_retry_seconds *= 2;
- send_retry_seconds = Geary.Numeric.uint_ceiling(send_retry_seconds,
MAX_SEND_RETRY_INTERVAL_SEC);
- }
+ // Take a brief nap before continuing to allow connection problems to resolve.
+ yield Geary.Scheduler.sleep_async(send_retry_seconds);
+ send_retry_seconds = Geary.Numeric.uint_ceiling(send_retry_seconds * 2,
MAX_SEND_RETRY_INTERVAL_SEC);
+ }
+
+ if (!mail_sent) {
+ // don't drop row until it's sent
+ outbox_queue.send(row);
continue;
}
diff --git a/src/engine/smtp/smtp-client-connection.vala b/src/engine/smtp/smtp-client-connection.vala
index f629a64..1010eed 100644
--- a/src/engine/smtp/smtp-client-connection.vala
+++ b/src/engine/smtp/smtp-client-connection.vala
@@ -48,9 +48,18 @@ public class Geary.Smtp.ClientConnection {
if (cx == null)
return false;
- yield cx.close_async(Priority.DEFAULT, cancellable);
+ Error? disconnect_error = null;
+ try {
+ yield cx.close_async(Priority.DEFAULT, cancellable);
+ } catch (Error err) {
+ disconnect_error = err;
+ }
+
cx = null;
+ if (disconnect_error != null)
+ throw disconnect_error;
+
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]