From c096b46ff3eb522a756acede590e7573de7b89a4 Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Tue, 17 Jul 2012 01:09:15 +0200 Subject: [PATCH] TLS error in-page and Trust/ Revoke in details dialog --- midori/midori-locationaction.c | 88 +++++++++++++++++++++++++--------- midori/midori-view.c | 17 ++++++- 2 files changed, 81 insertions(+), 24 deletions(-) diff --git a/midori/midori-locationaction.c b/midori/midori-locationaction.c index 154b9899..0bfea5ba 100644 --- a/midori/midori-locationaction.c +++ b/midori/midori-locationaction.c @@ -1143,7 +1143,7 @@ midori_map_add_message (SoupMessage* message) g_hash_table_insert (message_map, g_strdup (uri->host), g_object_ref (message)); } -static SoupMessage* +SoupMessage* midori_map_get_message (SoupMessage* message) { SoupURI* uri = soup_message_get_uri (message); @@ -1154,9 +1154,60 @@ midori_map_get_message (SoupMessage* message) return full; } +#if HAVE_GCR +typedef enum { + MIDORI_CERT_TRUST, + MIDORI_CERT_REVOKE, +} MidoriCertTrust; + +static void +midori_location_action_cert_response_cb (GtkWidget* dialog, + gint response, + GcrCertificate* gcr_cert) +{ + gchar* peer = g_object_get_data (G_OBJECT (gcr_cert), "peer"); + GError* error = NULL; + if (response == MIDORI_CERT_TRUST) + gcr_trust_add_pinned_certificate (gcr_cert, GCR_PURPOSE_SERVER_AUTH, peer, NULL, &error); + else if (response == MIDORI_CERT_REVOKE) + gcr_trust_remove_pinned_certificate (gcr_cert, GCR_PURPOSE_SERVER_AUTH, peer, NULL, &error); + if (error != NULL) + { + g_warning ("Error %s trust: %s", response == MIDORI_CERT_TRUST ? + "granting" : "revoking", error->message); + g_error_free (error); + } + gtk_widget_destroy (dialog); +} +#endif + +const gchar* +midori_location_action_tls_flags_to_string (GTlsCertificateFlags tls_flags) +{ + const gchar* tls_error; + if (tls_flags & G_TLS_CERTIFICATE_UNKNOWN_CA) + tls_error = _("The signing certificate authority is not known."); + else if (tls_flags & G_TLS_CERTIFICATE_BAD_IDENTITY) + tls_error = _("The certificate does not match the expected identity of the site that it was retrieved from."); + else if(tls_flags & G_TLS_CERTIFICATE_NOT_ACTIVATED) + tls_error = _("The certificate's activation time is still in the future."); + else if (tls_flags & G_TLS_CERTIFICATE_EXPIRED) + tls_error = _("The certificate has expired"); + else if (tls_flags & G_TLS_CERTIFICATE_REVOKED) + tls_error = _("The certificate has been revoked according to the GTlsConnection's certificate revocation list."); + else if (tls_flags & G_TLS_CERTIFICATE_INSECURE) + tls_error = _("The certificate's algorithm is considered insecure."); + else if (tls_flags & G_TLS_CERTIFICATE_GENERIC_ERROR) + tls_error = _("Some other error occurred validating the certificate."); + else + tls_error = "Unknown GTLSCertificateFlags value"; + return tls_error; +} + void midori_location_action_show_page_info (GtkWidget* widget, - GtkBox* box) + GtkBox* box, + GtkWidget* dialog) { MidoriBrowser* browser = midori_browser_get_for_widget (widget); MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser)); @@ -1178,38 +1229,31 @@ midori_location_action_show_page_info (GtkWidget* widget, GByteArray* der_cert; GcrCertificate* gcr_cert; GtkWidget* details; + SoupURI* uri = soup_message_get_uri (message); g_object_get (tls_cert, "certificate", &der_cert, NULL); gcr_cert = gcr_simple_certificate_new ( der_cert->data, der_cert->len); g_byte_array_unref (der_cert); - g_object_unref (tls_cert); details = (GtkWidget*)gcr_certificate_details_widget_new (gcr_cert); gtk_widget_show (details); gtk_container_add (GTK_CONTAINER (box), details); + if (gcr_trust_is_certificate_pinned (gcr_cert, GCR_PURPOSE_SERVER_AUTH, uri->host, NULL, NULL)) + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + ("_Don't trust this website"), MIDORI_CERT_REVOKE, NULL); + else if (tls_flags > 0) + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + ("_Trust this website"), MIDORI_CERT_TRUST, NULL); + g_object_set_data_full (G_OBJECT (gcr_cert), "peer", g_strdup (uri->host), (GDestroyNotify)g_free); + g_object_set_data_full (G_OBJECT (dialog), "gcr-cert", gcr_cert, (GDestroyNotify)g_object_unref); + g_signal_connect (dialog, "response", + G_CALLBACK (midori_location_action_cert_response_cb), gcr_cert); #else - const gchar* tls_error; + const gchar* tls_error = midori_location_action_tls_flags_to_string (tls_clags); if (!g_tls_certificate_get_issuer (tls_cert)) gtk_box_pack_start (box, gtk_label_new (_("Self-signed")), FALSE, FALSE, 0); - if (tls_flags & G_TLS_CERTIFICATE_UNKNOWN_CA) - tls_error = _("The signing certificate authority is not known."); - else if (tls_flags & G_TLS_CERTIFICATE_BAD_IDENTITY) - tls_error = _("The certificate does not match the expected identity of the site that it was retrieved from."); - else if(tls_flags & G_TLS_CERTIFICATE_NOT_ACTIVATED) - tls_error = _("The certificate's activation time is still in the future."); - else if (tls_flags & G_TLS_CERTIFICATE_EXPIRED) - tls_error = _("The certificate has expired"); - else if (tls_flags & G_TLS_CERTIFICATE_REVOKED) - tls_error = _("The certificate has been revoked according to the GTlsConnection's certificate revocation list."); - else if (tls_flags & G_TLS_CERTIFICATE_INSECURE) - tls_error = _("The certificate's algorithm is considered insecure."); - else if (tls_flags & G_TLS_CERTIFICATE_GENERIC_ERROR) - tls_error = _("Some other error occurred validating the certificate."); - else - tls_error = "Unknown GTLSCertificateFlags value"; - gtk_box_pack_start (box, gtk_label_new (tls_error), FALSE, FALSE, 0); #endif @@ -1262,7 +1306,7 @@ midori_location_action_icon_released_cb (GtkWidget* widget, gtk_label_new (gtk_icon_entry_get_tooltip (GTK_ICON_ENTRY (widget), icon_pos)), FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0); #if defined (HAVE_LIBSOUP_2_34_0) - midori_location_action_show_page_info (widget, GTK_BOX (content_area)); + midori_location_action_show_page_info (widget, GTK_BOX (content_area), dialog); #endif gtk_widget_show_all (dialog); } diff --git a/midori/midori-view.c b/midori/midori-view.c index c10ca98b..234c9077 100644 --- a/midori/midori-view.c +++ b/midori/midori-view.c @@ -998,6 +998,14 @@ midori_view_display_error (MidoriView* view, const gchar* try_again, WebKitWebFrame* web_frame); +#if HAVE_GCR +const gchar* +midori_location_action_tls_flags_to_string (GTlsCertificateFlags flags); + +SoupMessage* +midori_map_get_message (SoupMessage* message); +#endif + static void webkit_web_view_load_committed_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, @@ -1050,17 +1058,22 @@ webkit_web_view_load_committed_cb (WebKitWebView* web_view, if (message && soup_message_get_flags (message) & SOUP_MESSAGE_CERTIFICATE_TRUSTED) view->security = MIDORI_SECURITY_TRUSTED; - else if (!view->special) + #if HAVE_GCR + else if (!view->special && message != NULL) { + GTlsCertificateFlags tls_flags; + message = midori_map_get_message (message); + g_object_get (message, "tls-errors", &tls_flags, NULL); view->security = MIDORI_SECURITY_UNKNOWN; midori_view_stop_loading (view); midori_view_display_error ( view, view->uri, view->title ? view->title : view->uri, _("Security unknown"), - _("The certificate is invalid or unknown"), + midori_location_action_tls_flags_to_string (tls_flags), _("Load Page"), NULL); } + #endif else #endif view->security = MIDORI_SECURITY_UNKNOWN;