aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2010-12-03 02:08:51 +0800
committerStef Walter <stefw@collabora.co.uk>2010-12-24 21:40:01 +0800
commit8d72b18028c35d887c2352e3f08aacd9b7096f4c (patch)
tree773f3615574bc7accead92879416222c9668869b
parentc55c9a4dd8848f7257794dc9fc8f8138f1b47f43 (diff)
downloadgsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar.gz
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar.bz2
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar.lz
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar.xz
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.tar.zst
gsoc2013-empathy-8d72b18028c35d887c2352e3f08aacd9b7096f4c.zip
libempathy: Store certificate exceptions in gnome-keyring.
Use libgcr to store certificate trust exceptions properly.
-rw-r--r--libempathy/empathy-tls-certificate.c127
-rw-r--r--libempathy/empathy-tls-certificate.h2
-rw-r--r--libempathy/empathy-tls-verifier.c21
-rw-r--r--libempathy/empathy-tls-verifier.h2
-rw-r--r--src/empathy-auth-client.c14
5 files changed, 33 insertions, 133 deletions
diff --git a/libempathy/empathy-tls-certificate.c b/libempathy/empathy-tls-certificate.c
index 931bbcc64..c14deec57 100644
--- a/libempathy/empathy-tls-certificate.c
+++ b/libempathy/empathy-tls-certificate.c
@@ -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);
-}
diff --git a/libempathy/empathy-tls-certificate.h b/libempathy/empathy-tls-certificate.h
index d9dd07d44..8ad3d209e 100644
--- a/libempathy/empathy-tls-certificate.h
+++ b/libempathy/empathy-tls-certificate.h
@@ -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__*/
diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c
index 638b46bb7..3c547fb1c 100644
--- a/libempathy/empathy-tls-verifier.c
+++ b/libempathy/empathy-tls-verifier.c
@@ -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);
+}
diff --git a/libempathy/empathy-tls-verifier.h b/libempathy/empathy-tls-verifier.h
index e73a71aeb..e333bc81e 100644
--- a/libempathy/empathy-tls-verifier.h
+++ b/libempathy/empathy-tls-verifier.h
@@ -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__*/
diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c
index 98a736fb9..530aa17ec 100644
--- a/src/empathy-auth-client.c
+++ b/src/empathy-auth-client.c
@@ -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);
}