diff options
author | Stef Walter <stefw@collabora.co.uk> | 2010-12-03 02:08:51 +0800 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2010-12-24 21:40:01 +0800 |
commit | 8d72b18028c35d887c2352e3f08aacd9b7096f4c (patch) | |
tree | 773f3615574bc7accead92879416222c9668869b | |
parent | c55c9a4dd8848f7257794dc9fc8f8138f1b47f43 (diff) | |
download | gsoc2013-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.c | 127 | ||||
-rw-r--r-- | libempathy/empathy-tls-certificate.h | 2 | ||||
-rw-r--r-- | libempathy/empathy-tls-verifier.c | 21 | ||||
-rw-r--r-- | libempathy/empathy-tls-verifier.h | 2 | ||||
-rw-r--r-- | src/empathy-auth-client.c | 14 |
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); } |