[geary/wip/20-cert-pinning: 32/36] Handle untrusted certs when adding a new account



commit 2e344d7ce18b6c48acc759d4d629fa7ad233bbf8
Author: Michael Gratton <mike vee net>
Date:   Tue Jan 8 23:44:44 2019 +1100

    Handle untrusted certs when adding a new account
    
    Make the cert mamager easily available to acccount editor panes, hook up
    to untrusted-host when validating the new account and prompt to pin
    certs as needed.

 src/client/accounts/accounts-editor-add-pane.vala | 74 +++++++++++++++++++----
 src/client/accounts/accounts-editor.vala          |  6 ++
 2 files changed, 69 insertions(+), 11 deletions(-)
---
diff --git a/src/client/accounts/accounts-editor-add-pane.vala 
b/src/client/accounts/accounts-editor-add-pane.vala
index 3c5468df..5d9f54ae 100644
--- a/src/client/accounts/accounts-editor-add-pane.vala
+++ b/src/client/accounts/accounts-editor-add-pane.vala
@@ -163,7 +163,7 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
         this.is_operation_running = true;
 
         bool is_valid = false;
-        string message = "";
+        string? message = null;
         Gtk.Widget? to_focus = null;
 
         Geary.AccountInformation account =
@@ -178,6 +178,7 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
 
         account.incoming = new_imap_service();
         account.outgoing = new_smtp_service();
+        account.untrusted_host.connect(on_untrusted_host);
 
         if (this.provider == Geary.ServiceProvider.OTHER) {
             bool imap_valid = false;
@@ -193,11 +194,17 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
                 to_focus = this.imap_login.value;
                 // Translators: In-app notification label
                 message = _("Check your receiving login and password");
+            } catch (GLib.TlsError.BAD_CERTIFICATE err) {
+                debug("Error validating IMAP certifiate: %s", err.message);
+                // Nothing to do here, since the untrusted host
+                // handler will be dealing with it
             } catch (GLib.IOError.CANCELLED err) {
                 // Nothing to do here, someone just cancelled
                 debug("IMAP validation was cancelled: %s", err.message);
             } catch (GLib.Error err) {
-                debug("Error validating IMAP service: %s", err.message);
+                Geary.ErrorContext context = new Geary.ErrorContext(err);
+                debug("Error validating IMAP service: %s",
+                      context.format_full_error());
                 this.imap_tls.show();
                 to_focus = this.imap_hostname.value;
                 // Translators: In-app notification label
@@ -224,11 +231,17 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
                     to_focus = this.smtp_login.value;
                     // Translators: In-app notification label
                     message = _("Check your sending login and password");
+                } catch (GLib.TlsError.BAD_CERTIFICATE err) {
+                    debug("Error validating SMTP certifiate: %s", err.message);
+                    // Nothing to do here, since the untrusted host
+                    // handler will be dealing with it
                 } catch (GLib.IOError.CANCELLED err) {
                     // Nothing to do here, someone just cancelled
                     debug("SMTP validation was cancelled: %s", err.message);
                 } catch (GLib.Error err) {
-                    debug("Error validating SMTP service: %s", err.message);
+                    Geary.ErrorContext context = new Geary.ErrorContext(err);
+                    debug("Error validating SMTP service: %s",
+                          context.format_full_error());
                     this.smtp_tls.show();
                     to_focus = this.smtp_hostname.value;
                     // Translators: In-app notification label
@@ -249,7 +262,9 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
                 // Translators: In-app notification label
                 message = _("Check your email address and password");
             } catch (GLib.Error err) {
-                debug("Error validating provider service: %s", err.message);
+                Geary.ErrorContext context = new Geary.ErrorContext(err);
+                debug("Error validating SMTP service: %s",
+                      context.format_full_error());
                 is_valid = false;
                 // Translators: In-app notification label
                 message = _("Could not connect, check your network");
@@ -269,6 +284,7 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
             }
         }
 
+        account.untrusted_host.disconnect(on_untrusted_host);
         this.is_operation_running = false;
 
         // Focus and pop up the notification after re-sensitising
@@ -277,13 +293,15 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
             if (to_focus != null) {
                 to_focus.grab_focus();
             }
-            this.editor.add_notification(
-                new InAppNotification(
-                    // Translators: In-app notification label, the
-                    // string substitution is a more detailed reason.
-                    _("Account not created: %s").printf(message)
-                )
-            );
+            if (message != null) {
+                this.editor.add_notification(
+                    new InAppNotification(
+                        // Translators: In-app notification label, the
+                        // string substitution is a more detailed reason.
+                        _("Account not created: %s").printf(message)
+                    )
+                );
+            }
         }
     }
 
@@ -419,6 +437,40 @@ internal class Accounts.EditorAddPane : Gtk.Grid, EditorPane {
         check_validation();
     }
 
+    private void on_untrusted_host(Geary.AccountInformation account,
+                                   Geary.ServiceInformation service,
+                                   Geary.Endpoint endpoint,
+                                   GLib.TlsConnection cx) {
+        this.editor.certificates.prompt_pin_certificate.begin(
+            this.editor, account, service, endpoint, true, this.op_cancellable,
+            (obj, res) => {
+                try {
+                    this.editor.certificates.prompt_pin_certificate.end(res);
+                } catch (Application.CertificateManagerError.UNTRUSTED err) {
+                    // All good, just drop back into the editor window.
+                    return;
+                } catch (Application.CertificateManagerError.STORE_FAILED err) {
+                    // All good, just drop back into the editor
+                    // window. XXX show error info bar rather than a
+                    // notification
+                    this.editor.add_notification(
+                        new InAppNotification(
+                            // Translators: In-app notification label,
+                            // when the app had a problem pinning an
+                            // otherwise untrusted TLS certificate
+                            _("Failed to store certificate")
+                        )
+                    );
+                    return;
+                } catch (Application.CertificateManagerError err) {
+                    debug("Unexptected error pinning cert: %s", err.message);
+                }
+
+                // Kick off another attempt to validate
+                this.validate_account.begin(this.op_cancellable);
+            });
+    }
+
     [GtkCallback]
     private void on_create_button_clicked() {
         this.validate_account.begin(this.op_cancellable);
diff --git a/src/client/accounts/accounts-editor.vala b/src/client/accounts/accounts-editor.vala
index 7b6f0a04..1d1a8be6 100644
--- a/src/client/accounts/accounts-editor.vala
+++ b/src/client/accounts/accounts-editor.vala
@@ -36,6 +36,9 @@ public class Accounts.Editor : Gtk.Dialog {
 
     internal Manager accounts { get; private set; }
 
+    internal Application.CertificateManager certificates {
+        get; private set;
+    }
 
     private SimpleActionGroup actions = new SimpleActionGroup();
 
@@ -55,6 +58,9 @@ public class Accounts.Editor : Gtk.Dialog {
         this.application = application;
         this.transient_for = parent;
 
+        this.accounts = application.controller.account_manager;
+        this.certificates = application.controller.certificate_manager;
+
         // Can't set this in Glade 3.22.1 :(
         this.get_content_area().border_width = 0;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]