aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-03-22 22:22:43 +0800
committerStef Walter <stefw@collabora.co.uk>2011-03-22 22:22:43 +0800
commit6c5affb1f943b6685a0ac63adcfff24b47be6e2e (patch)
tree1e614836c265504c1c7c29911d5d1b8caac0f04c
parent5316d721a24d2c1c2496f751a4cf139d88e274c1 (diff)
parent698675bdc1fbc7e6e622be24e272df7e70f34716 (diff)
downloadgsoc2013-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.c47
-rw-r--r--libempathy/empathy-tls-verifier.c41
-rw-r--r--libempathy/empathy-tls-verifier.h3
-rw-r--r--src/empathy-auth-client.c6
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