diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-03-22 22:22:43 +0800 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-03-22 22:22:43 +0800 |
commit | 6c5affb1f943b6685a0ac63adcfff24b47be6e2e (patch) | |
tree | 1e614836c265504c1c7c29911d5d1b8caac0f04c | |
parent | 5316d721a24d2c1c2496f751a4cf139d88e274c1 (diff) | |
parent | 698675bdc1fbc7e6e622be24e272df7e70f34716 (diff) | |
download | gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar.gz gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar.bz2 gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar.lz gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar.xz gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.tar.zst gsoc2013-empathy-6c5affb1f943b6685a0ac63adcfff24b47be6e2e.zip |
Merge branch 'reference-identities'
Conflicts:
libempathy/empathy-server-tls-handler.c
-rw-r--r-- | libempathy/empathy-server-tls-handler.c | 47 | ||||
-rw-r--r-- | libempathy/empathy-tls-verifier.c | 41 | ||||
-rw-r--r-- | libempathy/empathy-tls-verifier.h | 3 | ||||
-rw-r--r-- | src/empathy-auth-client.c | 6 |
4 files changed, 89 insertions, 8 deletions
diff --git a/libempathy/empathy-server-tls-handler.c b/libempathy/empathy-server-tls-handler.c index 6cf3290c5..31afa276c 100644 --- a/libempathy/empathy-server-tls-handler.c +++ b/libempathy/empathy-server-tls-handler.c @@ -20,6 +20,7 @@ #include "empathy-server-tls-handler.h" +#include <telepathy-glib/interfaces.h> #include <telepathy-glib/util.h> #define DEBUG_FLAG EMPATHY_DEBUG_TLS @@ -35,6 +36,7 @@ enum { PROP_CHANNEL = 1, PROP_TLS_CERTIFICATE, PROP_HOSTNAME, + PROP_REFERENCE_IDENTITIES, LAST_PROPERTY, }; @@ -43,6 +45,7 @@ typedef struct { EmpathyTLSCertificate *certificate; gchar *hostname; + gchar **reference_identities; GSimpleAsyncResult *async_init_res; } EmpathyServerTLSHandlerPriv; @@ -99,9 +102,15 @@ tls_handler_init_async (GAsyncInitable *initable, GHashTable *properties; const gchar *cert_object_path; const gchar *hostname; + const gchar * const *identities; const gchar *bus_name; TpDBusDaemon *dbus; GError *error = NULL; + /* + * Used when channel doesn't implement ReferenceIdentities. A GStrv + * with [0] the hostname, and [1] a NULL terminator. + */ + gchar *default_identities[2]; EmpathyServerTLSHandler *self = EMPATHY_SERVER_TLS_HANDLER (initable); EmpathyServerTLSHandlerPriv *priv = GET_PRIV (self); @@ -112,11 +121,35 @@ tls_handler_init_async (GAsyncInitable *initable, properties = tp_channel_borrow_immutable_properties (priv->channel); hostname = tp_asv_get_string (properties, - EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION ".Hostname"); + TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_HOSTNAME); priv->hostname = g_strdup (hostname); DEBUG ("Received hostname: %s", hostname); + identities = tp_asv_get_strv (properties, + TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_REFERENCE_IDENTITIES); + + /* + * If the channel doesn't implement the ReferenceIdentities parameter + * then fallback to the hostname. + */ + if (identities == NULL) + { + default_identities[0] = (gchar *) hostname; + default_identities[1] = NULL; + identities = (const gchar **) default_identities; + } + else + { +#ifdef ENABLE_DEBUG + gchar *output = g_strjoinv (", ", (gchar **) identities); + DEBUG ("Received reference identities: %s", output); + g_free (output); +#endif /* ENABLE_DEBUG */ + } + + priv->reference_identities = g_strdupv ((gchar **) identities); + cert_object_path = tp_asv_get_object_path (properties, EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION ".ServerCertificate"); bus_name = tp_proxy_get_bus_name (TP_PROXY (priv->channel)); @@ -162,6 +195,7 @@ empathy_server_tls_handler_finalize (GObject *object) tp_clear_object (&priv->channel); tp_clear_object (&priv->certificate); + g_strfreev (priv->reference_identities); g_free (priv->hostname); G_OBJECT_CLASS (empathy_server_tls_handler_parent_class)->finalize (object); @@ -186,6 +220,9 @@ empathy_server_tls_handler_get_property (GObject *object, case PROP_HOSTNAME: g_value_set_string (value, priv->hostname); break; + case PROP_REFERENCE_IDENTITIES: + g_value_set_boxed (value, priv->reference_identities); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -236,10 +273,16 @@ empathy_server_tls_handler_class_init (EmpathyServerTLSHandlerClass *klass) g_object_class_install_property (oclass, PROP_TLS_CERTIFICATE, pspec); pspec = g_param_spec_string ("hostname", "The hostname", - "The hostname which should be certified by the server certificate.", + "The hostname the user is expecting to connect to.", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (oclass, PROP_HOSTNAME, pspec); + + pspec = g_param_spec_boxed ("reference-identities", "Reference Identities", + "The server certificate should certify one of these identities", + G_TYPE_STRV, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_REFERENCE_IDENTITIES, pspec); + } static void diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c index 2f98d9364..47a54333c 100644 --- a/libempathy/empathy-tls-verifier.c +++ b/libempathy/empathy-tls-verifier.c @@ -42,6 +42,7 @@ G_DEFINE_TYPE (EmpathyTLSVerifier, empathy_tls_verifier, enum { PROP_TLS_CERTIFICATE = 1, PROP_HOSTNAME, + PROP_REFERENCE_IDENTITIES, LAST_PROPERTY, }; @@ -49,6 +50,7 @@ enum { typedef struct { EmpathyTLSCertificate *certificate; gchar *hostname; + gchar **reference_identities; GSimpleAsyncResult *verify_result; GHashTable *details; @@ -255,6 +257,8 @@ perform_verification (EmpathyTLSVerifier *self, guint n_list, n_anchors; guint verify_output; gint res; + gint i; + gboolean matched; EmpathyTLSVerifierPriv *priv = GET_PRIV (self); DEBUG ("Performing verification"); @@ -295,8 +299,21 @@ perform_verification (EmpathyTLSVerifier *self, goto out; } - /* now check if the certificate matches the hostname. */ - if (gnutls_x509_crt_check_hostname (list[0], priv->hostname) == 0) + /* now check if the certificate matches one of the reference identities. */ + if (priv->reference_identities != NULL) + { + for (i = 0, matched = FALSE; priv->reference_identities[i] != NULL; ++i) + { + if (gnutls_x509_crt_check_hostname (list[0], + priv->reference_identities[i]) == 1) + { + matched = TRUE; + break; + } + } + } + + if (!matched) { gchar *certified_hostname; @@ -362,6 +379,9 @@ empathy_tls_verifier_get_property (GObject *object, case PROP_HOSTNAME: g_value_set_string (value, priv->hostname); break; + case PROP_REFERENCE_IDENTITIES: + g_value_set_boxed (value, priv->reference_identities); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -384,6 +404,9 @@ empathy_tls_verifier_set_property (GObject *object, case PROP_HOSTNAME: priv->hostname = g_value_dup_string (value); break; + case PROP_REFERENCE_IDENTITIES: + priv->reference_identities = g_value_dup_boxed (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -414,6 +437,7 @@ empathy_tls_verifier_finalize (GObject *object) tp_clear_boxed (G_TYPE_HASH_TABLE, &priv->details); g_free (priv->hostname); + g_strfreev (priv->reference_identities); G_OBJECT_CLASS (empathy_tls_verifier_parent_class)->finalize (object); } @@ -448,22 +472,31 @@ empathy_tls_verifier_class_init (EmpathyTLSVerifierClass *klass) g_object_class_install_property (oclass, PROP_TLS_CERTIFICATE, pspec); pspec = g_param_spec_string ("hostname", "The hostname", - "The hostname which should be certified by the certificate.", + "The hostname which is certified by the certificate.", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (oclass, PROP_HOSTNAME, pspec); + + pspec = g_param_spec_boxed ("reference-identities", + "The reference identities", + "The certificate should certify one of these identities.", + G_TYPE_STRV, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_REFERENCE_IDENTITIES, pspec); } EmpathyTLSVerifier * empathy_tls_verifier_new (EmpathyTLSCertificate *certificate, - const gchar *hostname) + const gchar *hostname, const gchar **reference_identities) { g_assert (EMPATHY_IS_TLS_CERTIFICATE (certificate)); g_assert (hostname != NULL); + g_assert (reference_identities != NULL); return g_object_new (EMPATHY_TYPE_TLS_VERIFIER, "certificate", certificate, "hostname", hostname, + "reference-identities", reference_identities, NULL); } diff --git a/libempathy/empathy-tls-verifier.h b/libempathy/empathy-tls-verifier.h index e333bc81e..436149336 100644 --- a/libempathy/empathy-tls-verifier.h +++ b/libempathy/empathy-tls-verifier.h @@ -62,7 +62,8 @@ GType empathy_tls_verifier_get_type (void); EmpathyTLSVerifier * empathy_tls_verifier_new ( EmpathyTLSCertificate *certificate, - const gchar *hostname); + const gchar *hostname, + const gchar **reference_identities); void empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self, GAsyncReadyCallback callback, diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index df2003495..68c4543a8 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -197,6 +197,7 @@ auth_factory_new_tls_handler_cb (EmpathyAuthFactory *factory, { EmpathyTLSCertificate *certificate = NULL; gchar *hostname = NULL; + gchar **reference_identities = NULL; EmpathyTLSVerifier *verifier; DEBUG ("New TLS server handler received from the factory"); @@ -204,15 +205,18 @@ auth_factory_new_tls_handler_cb (EmpathyAuthFactory *factory, g_object_get (handler, "certificate", &certificate, "hostname", &hostname, + "reference-identities", &reference_identities, NULL); - verifier = empathy_tls_verifier_new (certificate, hostname); + verifier = empathy_tls_verifier_new (certificate, hostname, + (const gchar **) reference_identities); empathy_tls_verifier_verify_async (verifier, verifier_verify_cb, NULL); g_object_unref (verifier); g_object_unref (certificate); g_free (hostname); + g_strfreev (reference_identities); } static void |