Commit 9c2aa03d authored by Jens Georg's avatar Jens Georg
Browse files

piwigo: Add option to override the SSL verification


Signed-off-by: Jens Georg's avatarJens Georg <mail@jensge.org>

https://bugzilla.gnome.org/show_bug.cgi?id=767473
parent 73007e57
......@@ -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:
......
......@@ -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);
}
}
}
/**
......
......@@ -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>
<?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>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment