]> git.0d.be Git - empathy.git/commitdiff
libempathy: Store certificate exceptions in gnome-keyring.
authorStef Walter <stefw@collabora.co.uk>
Thu, 2 Dec 2010 18:08:51 +0000 (18:08 +0000)
committerStef Walter <stefw@collabora.co.uk>
Fri, 24 Dec 2010 13:40:01 +0000 (07:40 -0600)
Use libgcr to store certificate trust exceptions properly.

libempathy/empathy-tls-certificate.c
libempathy/empathy-tls-certificate.h
libempathy/empathy-tls-verifier.c
libempathy/empathy-tls-verifier.h
src/empathy-auth-client.c

index 931bbcc6489df27e4e610a324b01db6122e5786f..c14deec579d25a3d3eb62165c82247d6b022b890 100644 (file)
@@ -430,130 +430,3 @@ empathy_tls_certificate_reject_finish (EmpathyTLSCertificate *self,
 
   return TRUE;
 }
-
-static gsize
-get_exported_size (gnutls_x509_crt_t cert)
-{
-  gsize retval = 2;
-  guchar fake[2] = { 0, 0 };
-
-  /* fake an export so we get the size to allocate */
-  gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM,
-      fake, &retval);
-
-  DEBUG ("Should allocate %lu bytes", (gulong) retval);
-
-  return retval + 1;
-}
-
-void
-empathy_tls_certificate_store_ca (EmpathyTLSCertificate *self)
-{
-  GArray *last_cert;
-  gnutls_x509_crt_t cert;
-  gnutls_datum_t datum = { NULL, 0 };
-  gsize exported_len;
-  guchar *exported_cert = NULL;
-  gint res, offset;
-  gchar *user_certs_dir = NULL, *filename = NULL, *path = NULL;
-  gchar *hostname = NULL;
-  GError *error = NULL;
-  EmpathyTLSCertificatePriv *priv = GET_PRIV (self);
-
-  last_cert = g_ptr_array_index (priv->cert_data, priv->cert_data->len - 1);
-  datum.data = (guchar *) last_cert->data;
-  datum.size = last_cert->len;
-
-  gnutls_x509_crt_init (&cert);
-  gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER);
-
-  /* make sure it's self-signed, otherwise it's not a CA */
-  if (gnutls_x509_crt_check_issuer (cert, cert) <= 0)
-    {
-      DEBUG ("Can't import the CA, as it's not self-signed");
-      gnutls_x509_crt_deinit (cert);
-
-      return;
-    }
-
-  if (gnutls_x509_crt_get_ca_status (cert, NULL) <= 0)
-    {
-      DEBUG ("Can't import the CA, it's not a valid CA certificate");
-      gnutls_x509_crt_deinit (cert);
-
-      goto out;
-    }
-
-  exported_len = get_exported_size (cert);
-  exported_cert = g_malloc (sizeof (guchar) * exported_len);
-
-  res = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM,
-      exported_cert, &exported_len);
-
-  if (res < 0)
-    {
-      DEBUG ("Failed to export the CA certificate; GnuTLS returned %d,"
-          "and should be %lu bytes long", res, (gulong) exported_len);
-      gnutls_x509_crt_deinit (cert);
-
-      goto out;
-    }
-
-  hostname = empathy_get_x509_certificate_hostname (cert);
-
-  if (hostname == NULL)
-    hostname = g_strdup ("ca");
-
-  gnutls_x509_crt_deinit (cert);
-
-  /* write the file */
-  user_certs_dir = g_build_filename (g_get_user_config_dir (),
-      "telepathy", "certs", NULL);
-
-  res = g_mkdir_with_parents (user_certs_dir, S_IRWXU | S_IRWXG);
-
-  if (res < 0)
-    {
-      DEBUG ("Failed to create the user certificate directory: %s",
-          g_strerror (errno));
-
-      goto out;
-    }
-
-  offset = 0;
-
-  do
-    {
-      g_free (path);
-
-      if (offset == 0)
-        filename = g_strdup_printf ("cert-%s", hostname);
-      else
-        filename = g_strdup_printf ("cert-%s-%d", hostname, offset);
-
-      path = g_build_filename (user_certs_dir, filename, NULL);
-
-      offset++;
-      g_free (filename);
-    }
-  while (g_file_test (path, G_FILE_TEST_EXISTS));
-
-  DEBUG ("Will save to %s", path);
-
-  g_file_set_contents (path, (const gchar *) exported_cert, exported_len,
-      &error);
-
-  if (error != NULL)
-    {
-      DEBUG ("Can't save the CA certificate to %s: %s",
-          path, error->message);
-
-      g_error_free (error);
-    }
-
- out:
-  g_free (path);
-  g_free (exported_cert);
-  g_free (user_certs_dir);
-  g_free (hostname);
-}
index d9dd07d44896fee78387e95609109750b6c4fbbe..8ad3d209ef1c224527b3272800d79e26d7c94c0f 100644 (file)
@@ -88,8 +88,6 @@ gboolean empathy_tls_certificate_reject_finish (EmpathyTLSCertificate *self,
     GAsyncResult *result,
     GError **error);
 
-void empathy_tls_certificate_store_ca (EmpathyTLSCertificate *self);
-
 G_END_DECLS
 
 #endif /* #ifndef __EMPATHY_TLS_CERTIFICATE_H__*/
index 638b46bb72d3e98252644884da77843aa7ed4e63..3c547fb1ccc9643e9a9f6c4f856de22add4f85ac 100644 (file)
@@ -489,3 +489,24 @@ empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self,
 
   return TRUE;
 }
+
+void
+empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self)
+{
+  GArray *last_cert;
+  GcrCertificate *cert;
+  GPtrArray *certs;
+  GError *error = NULL;
+  EmpathyTLSVerifierPriv *priv = GET_PRIV (self);
+
+  g_object_get (priv->certificate, "cert-data", &certs, NULL);
+  last_cert = g_ptr_array_index (certs, certs->len - 1);
+  cert = gcr_simple_certificate_new_static ((gpointer)last_cert->data,
+          last_cert->len);
+
+  if (!gcr_trust_add_certificate_exception (cert, GCR_PURPOSE_CLIENT_AUTH,
+          priv->hostname, NULL, &error))
+      DEBUG ("Can't store the certificate exeption: %s", error->message);
+
+  g_object_unref (cert);
+}
index e73a71aeba8b687352c2eb37c273a579f9bcc67c..e333bc81e2bcab5b89048f2616b72daf39842171 100644 (file)
@@ -74,6 +74,8 @@ gboolean empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self,
     GHashTable **details,
     GError **error);
 
+void empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self);
+
 G_END_DECLS
 
 #endif /* #ifndef __EMPATHY_TLS_VERIFIER_H__*/
index 98a736fb994ffe58da877cb8287a974038741034..530aa17ec680b6752e3c609dd12de9a98d774061 100644 (file)
@@ -93,6 +93,7 @@ tls_dialog_response_cb (GtkDialog *dialog,
   GHashTable *details = NULL;
   EmpathyTLSDialog *tls_dialog = EMPATHY_TLS_DIALOG (dialog);
   gboolean remember = FALSE;
+  EmpathyTLSVerifier *verifier = EMPATHY_TLS_VERIFIER (user_data);
 
   DEBUG ("Response %d", response_id);
 
@@ -117,7 +118,7 @@ tls_dialog_response_cb (GtkDialog *dialog,
     }
 
   if (remember)
-    empathy_tls_certificate_store_ca (certificate);
+    empathy_tls_verifier_store_exception (verifier);
 
   g_object_unref (certificate);
   g_hash_table_unref (details);
@@ -133,6 +134,7 @@ tls_dialog_response_cb (GtkDialog *dialog,
 
 static void
 display_interactive_dialog (EmpathyTLSCertificate *certificate,
+    EmpathyTLSVerifier *verifier,
     EmpTLSCertificateRejectReason reason,
     GHashTable *details)
 {
@@ -143,8 +145,9 @@ display_interactive_dialog (EmpathyTLSCertificate *certificate,
   stop_timer ();
 
   tls_dialog = empathy_tls_dialog_new (certificate, reason, details);
-  g_signal_connect (tls_dialog, "response",
-      G_CALLBACK (tls_dialog_response_cb), NULL);
+  g_signal_connect_data (tls_dialog, "response",
+      G_CALLBACK (tls_dialog_response_cb), g_object_ref (verifier),
+      (GClosureNotify)g_object_unref, 0);
 
   gtk_widget_show (tls_dialog);
 }
@@ -159,6 +162,7 @@ verifier_verify_cb (GObject *source,
   GError *error = NULL;
   EmpathyTLSCertificate *certificate = NULL;
   GHashTable *details = NULL;
+  gchar *hostname = NULL;
 
   g_object_get (source,
       "certificate", &certificate,
@@ -170,7 +174,8 @@ verifier_verify_cb (GObject *source,
   if (error != NULL)
     {
       DEBUG ("Error: %s", error->message);
-      display_interactive_dialog (certificate, reason, details);
+      display_interactive_dialog (certificate, EMPATHY_TLS_VERIFIER (source),
+              reason, details);
 
       g_error_free (error);
     }
@@ -179,6 +184,7 @@ verifier_verify_cb (GObject *source,
       empathy_tls_certificate_accept_async (certificate, NULL, NULL);
     }
 
+  g_free (hostname);
   g_object_unref (certificate);
 }