]> spindle.queued.net Git - midori/commitdiff
TLS error in-page and Trust/ Revoke in details dialog
authorChristian Dywan <christian@twotoasts.de>
Mon, 16 Jul 2012 23:09:15 +0000 (01:09 +0200)
committerChristian Dywan <christian@twotoasts.de>
Mon, 16 Jul 2012 23:09:15 +0000 (01:09 +0200)
midori/midori-locationaction.c
midori/midori-view.c

index 154b989938eaf0e13de37338bdf56af234921dd4..0bfea5ba87fd0e7b0b9001f4148cbb385c84b7f8 100644 (file)
@@ -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);
     }
index c10ca98bf528849454fe5b38e6772fd777281206..234c907714ebe50a017fc2e5669e7a6c5aa4c02c 100644 (file)
@@ -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;