[shotwell] piwigo: Add option to override the SSL verification



commit 9c2aa03dde6538800ab3916635444c343058f462
Author: Jens Georg <mail jensge org>
Date:   Sun Oct 2 19:41:48 2016 +0200

    piwigo: Add option to override the SSL verification
    
    Signed-off-by: Jens Georg <mail jensge org>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=767473

 plugins/common/RESTSupport.vala                    |   59 ++++++++++++
 plugins/shotwell-publishing/PiwigoPublishing.vala  |   92 ++++++++++++++++++-
 .../org.gnome.Shotwell.Publishing.gresource.xml    |    1 +
 .../shotwell-publishing/piwigo_ssl_failure_pane.ui |   97 ++++++++++++++++++++
 4 files changed, 246 insertions(+), 3 deletions(-)
---
diff --git a/plugins/common/RESTSupport.vala b/plugins/common/RESTSupport.vala
index 64351ac..94d5da7 100644
--- a/plugins/common/RESTSupport.vala
+++ b/plugins/common/RESTSupport.vala
@@ -73,6 +73,11 @@ public abstract class Session {
         
         soup_session.request_unqueued.disconnect(notify_wire_message_unqueued);
     }
+
+    public void set_insecure () {
+        this.soup_session.ssl_use_system_ca_file = false;
+        this.soup_session.ssl_strict = false;
+    }
 }
 
 public enum HttpMethod {
@@ -186,6 +191,60 @@ public class Transaction {
         }
     }
 
+    /* Texts copied from epiphany */
+    public string detailed_error_from_tls_flags () {
+        TlsCertificate cert;
+        TlsCertificateFlags tls_errors;
+        this.message.get_https_status (out cert, out tls_errors);
+
+        var list = new Gee.ArrayList<string> ();
+        if (TlsCertificateFlags.BAD_IDENTITY in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website presented identification that belongs to a different website."));
+        }
+
+        if (TlsCertificateFlags.EXPIRED in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification is too old to trust. Check the date on your 
computer’s calendar."));
+        }
+
+        if (TlsCertificateFlags.UNKNOWN_CA in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification was not issued by a trusted organization."));
+        }
+
+        if (TlsCertificateFlags.GENERIC_ERROR in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification could not be processed. It may be corrupted."));
+        }
+
+        if (TlsCertificateFlags.REVOKED in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification has been revoked by the trusted organization that 
issued it."));
+        }
+
+        if (TlsCertificateFlags.INSECURE in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification cannot be trusted because it uses very weak 
encryption."));
+        }
+
+        if (TlsCertificateFlags.NOT_ACTIVATED in tls_errors) {
+            /* Possible error message when a site presents a bad certificate. */
+            list.add (_("⚫ This website’s identification is only valid for future dates. Check the date on 
your computer’s calendar."));
+        }
+
+        var builder = new StringBuilder ();
+        if (list.size == 1) {
+            builder.append (list.get (0));
+        } else {
+            foreach (var entry in list) {
+                builder.append_printf ("%s\n", entry);
+            }
+        }
+
+        return builder.str;
+  }
+
     protected void check_response(Soup.Message message) throws Spit.Publishing.PublishingError {
         switch (message.status_code) {
             case Soup.KnownStatusCode.OK:
diff --git a/plugins/shotwell-publishing/PiwigoPublishing.vala 
b/plugins/shotwell-publishing/PiwigoPublishing.vala
index e2db60c..cc917ad 100644
--- a/plugins/shotwell-publishing/PiwigoPublishing.vala
+++ b/plugins/shotwell-publishing/PiwigoPublishing.vala
@@ -284,6 +284,30 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
         host.set_dialog_default_widget(authentication_pane.get_default_widget());
     }
 
+    private void do_show_ssl_downgrade_pane (SessionLoginTransaction trans,
+                                             string url) {
+        var uri = new Soup.URI (url);
+        host.set_service_locked (false);
+        var ssl_pane = new SSLErrorPane (trans, uri.get_host ());
+        ssl_pane.proceed.connect (() => {
+            debug ("SSL: User wants us to retry with broken certificate");
+            this.session = new Session ();
+            this.session.set_insecure ();
+
+            string? persistent_url = get_persistent_url();
+            string? persistent_username = get_persistent_username();
+            string? persistent_password = get_persistent_password();
+            if (persistent_url != null && persistent_username != null && persistent_password != null)
+                do_network_login(persistent_url, persistent_username,
+                    persistent_password, get_remember_password());
+            else
+                do_show_authentication_pane();
+        });
+        host.install_dialog_pane (ssl_pane,
+                                  Spit.Publishing.PluginHost.ButtonMode.CLOSE);
+        host.set_dialog_default_widget (ssl_pane.get_default_widget ());
+    }
+
     /**
      * Event triggered when the login button in the authentication panel is
      * clicked.
@@ -335,8 +359,13 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
         try {
             login_trans.execute();
         } catch (Spit.Publishing.PublishingError err) {
-            debug("ERROR: do_network_login");
-            do_show_error(err);
+            if (err is Spit.Publishing.PublishingError.SSL_FAILED) {
+                debug ("ERROR: SSL connection problems");
+                do_show_ssl_downgrade_pane (login_trans, url);
+            } else {
+                debug("ERROR: do_network_login");
+                do_show_error(err);
+            }
         }
     }
     
@@ -400,7 +429,6 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object {
         debug("Setting endpoint URL to %s", endpoint_url);
         string pwg_id = get_pwg_id_from_transaction(txn);
         debug("Setting session pwg_id to %s", pwg_id);
-        session = new Session();
         session.set_pwg_id(pwg_id);
 
         do_fetch_session_status(endpoint_url, pwg_id);
@@ -977,6 +1005,56 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader {
 
 // UI elements
 
+internal class SSLErrorPane : Spit.Publishing.DialogPane, Object {
+    private Gtk.Builder builder;
+    private Gtk.Widget content;
+
+    public signal void proceed ();
+
+    public SSLErrorPane (SessionLoginTransaction transaction,
+                         string host) {
+        try {
+            this.builder = new Gtk.Builder ();
+            this.builder.add_from_resource (Resources.RESOURCE_PATH +
+                                            "/piwigo_ssl_failure_pane.ui");
+            this.content = this.builder.get_object ("content") as Gtk.Widget;
+            var label = this.builder.get_object ("main_text") as Gtk.Label;
+            // %s is the host name that we tried to connect to
+            label.set_text (_("This does not look like the real <b>%s</b>. Attackers might be trying to 
steal or alter information going to or from this site (for example, private messages, credit card 
information, or passwords).").printf (host));
+            label.use_markup = true;
+
+            label = this.builder.get_object ("ssl_errors") as Gtk.Label;
+            label.set_text (transaction.detailed_error_from_tls_flags ());
+
+            var proceed = this.builder.get_object ("proceed_button") as Gtk.Button;
+            proceed.clicked.connect (() => { this.proceed (); });
+
+            if (this.content.parent != null) {
+                this.content.parent.remove (this.content);
+            }
+        } catch (Error error) {
+            warning ("Failed to create ui file: %s", error.message);
+            assert_not_reached ();
+        }
+    }
+
+    public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry () {
+        return Spit.Publishing.DialogPane.GeometryOptions.NONE;
+    }
+
+    public Gtk.Widget get_widget () {
+        return this.content;
+    }
+
+    public Gtk.Widget get_default_widget () {
+        return this.builder.get_object ("cancel_button") as Gtk.Widget;
+    }
+
+    public void on_pane_installed () { }
+
+    public void on_pane_uninstalled () { }
+}
+
 /**
  * The authentication pane used when asking service URL, user name and password
  * from the user.
@@ -1583,6 +1661,14 @@ internal class SessionLoginTransaction : Transaction {
         add_argument("username", username);
         add_argument("password", password);
     }
+
+    public SessionLoginTransaction.from_other (Session session, Transaction other) {
+        base.with_endpoint_url (session, other.get_endpoint_url ());
+
+        foreach (var argument in other.get_arguments ()) {
+            add_argument (argument.key, argument.value);
+        }
+    }
 }
 
 /**
diff --git a/plugins/shotwell-publishing/org.gnome.Shotwell.Publishing.gresource.xml 
b/plugins/shotwell-publishing/org.gnome.Shotwell.Publishing.gresource.xml
index 53bcc43..af3baad 100644
--- a/plugins/shotwell-publishing/org.gnome.Shotwell.Publishing.gresource.xml
+++ b/plugins/shotwell-publishing/org.gnome.Shotwell.Publishing.gresource.xml
@@ -12,6 +12,7 @@
       <file>picasa_publishing_options_pane.ui</file>
       <file>piwigo_authentication_pane.ui</file>
       <file>piwigo_publishing_options_pane.ui</file>
+      <file>piwigo_ssl_failure_pane.ui</file>
       <file>youtube_publishing_options_pane.ui</file>
   </gresource>
 </gresources>
diff --git a/plugins/shotwell-publishing/piwigo_ssl_failure_pane.ui 
b/plugins/shotwell-publishing/piwigo_ssl_failure_pane.ui
new file mode 100644
index 0000000..b25828b
--- /dev/null
+++ b/plugins/shotwell-publishing/piwigo_ssl_failure_pane.ui
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkWindow">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox" id="content">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">12</property>
+        <property name="margin_right">12</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">This connection is not secure</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="main_text">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label">This does not look like the real %s. Attackers might be trying to steal 
or alter information going to or from this site (for example, private messages, credit card information, or 
passwords).</property>
+            <property name="use_markup">True</property>
+            <property name="wrap">True</property>
+            <property name="width_chars">40</property>
+            <property name="max_width_chars">40</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="ssl_errors">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="margin_left">12</property>
+            <property name="label">⚫ This website presented identification that belongs to a different 
website.
+⚫ This website’s identification could not be processed. It may be corrupted.</property>
+            <property name="wrap">True</property>
+            <property name="width_chars">52</property>
+            <property name="max_width_chars">52</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButtonBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">6</property>
+            <property name="layout_style">center</property>
+            <child>
+              <object class="GtkButton" id="proceed_button">
+                <property name="label" translatable="yes">I understand, please _proceed.</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>


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