* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
#include "empathy-server-tls-handler.h"
-#include <telepathy-glib/util.h>
+#include "empathy-utils.h"
+#include "extensions.h"
#define DEBUG_FLAG EMPATHY_DEBUG_TLS
#include "empathy-debug.h"
-#include "empathy-tls-certificate.h"
-#include "empathy-utils.h"
-
-#include "extensions/extensions.h"
static void async_initable_iface_init (GAsyncInitableIface *iface);
PROP_CHANNEL = 1,
PROP_TLS_CERTIFICATE,
PROP_HOSTNAME,
+ PROP_REFERENCE_IDENTITIES,
LAST_PROPERTY,
};
typedef struct {
TpChannel *channel;
- EmpathyTLSCertificate *certificate;
+ TpTLSCertificate *certificate;
gchar *hostname;
+ gchar **reference_identities;
GSimpleAsyncResult *async_init_res;
} EmpathyServerTLSHandlerPriv;
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerTLSHandler);
static void
-tls_certificate_constructed_cb (GObject *source,
+tls_certificate_prepared_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- EmpathyTLSCertificate *certificate;
+ TpTLSCertificate *certificate = TP_TLS_CERTIFICATE (source);
EmpathyServerTLSHandler *self = user_data;
GError *error = NULL;
EmpathyServerTLSHandlerPriv *priv = GET_PRIV (self);
- certificate = empathy_tls_certificate_new_finish (result, &error);
-
- if (error != NULL)
+ if (!tp_proxy_prepare_finish (certificate, result, &error))
{
g_simple_async_result_set_from_error (priv->async_init_res, error);
g_error_free (error);
}
- else
- {
- priv->certificate = certificate;
- }
g_simple_async_result_complete_in_idle (priv->async_init_res);
- g_object_unref (priv->async_init_res);
+ tp_clear_object (&priv->async_init_res);
}
static gboolean
GError **error)
{
gboolean retval = TRUE;
- EmpathyServerTLSHandler *self = EMPATHY_SERVER_TLS_HANDLER (initable);
- EmpathyServerTLSHandlerPriv *priv = GET_PRIV (self);
- if (g_simple_async_result_propagate_error (priv->async_init_res, error))
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
+ error))
retval = FALSE;
return retval;
GAsyncReadyCallback callback,
gpointer user_data)
{
- GHashTable *properties;
+ GVariant *properties;
const gchar *cert_object_path;
- const gchar *hostname;
const gchar *bus_name;
+ GError *error = NULL;
+ GQuark features[] = { TP_TLS_CERTIFICATE_FEATURE_CORE, 0 };
+ /*
+ * 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);
g_assert (priv->channel != NULL);
priv->async_init_res = g_simple_async_result_new (G_OBJECT (self),
- callback, user_data, empathy_tls_certificate_new_async);
- properties = tp_channel_borrow_immutable_properties (priv->channel);
+ callback, user_data, empathy_server_tls_handler_new_async);
+ properties = tp_channel_dup_immutable_properties (priv->channel);
+
+ g_variant_lookup (properties,
+ TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_HOSTNAME,
+ "s", &priv->hostname);
- hostname = tp_asv_get_string (properties,
- EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION ".Hostname");
- priv->hostname = g_strdup (hostname);
+ DEBUG ("Received hostname: %s", priv->hostname);
- DEBUG ("Received hostname: %s", hostname);
+ g_variant_lookup (properties,
+ TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_REFERENCE_IDENTITIES,
+ "^as", &priv->reference_identities);
- cert_object_path = tp_asv_get_object_path (properties,
- EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION ".ServerCertificate");
+ /*
+ * If the channel doesn't implement the ReferenceIdentities parameter
+ * then fallback to the hostname.
+ */
+ if (priv->reference_identities == NULL)
+ {
+ default_identities[0] = (gchar *) priv->hostname;
+ default_identities[1] = NULL;
+ priv->reference_identities = g_strdupv (default_identities);
+ }
+ else
+ {
+#ifdef ENABLE_DEBUG
+ gchar *output = g_strjoinv (", ", (gchar **) priv->reference_identities);
+ DEBUG ("Received reference identities: %s", output);
+ g_free (output);
+#endif /* ENABLE_DEBUG */
+ }
+
+ g_variant_lookup (properties,
+ EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION ".ServerCertificate",
+ "&o", &cert_object_path);
bus_name = tp_proxy_get_bus_name (TP_PROXY (priv->channel));
- DEBUG ("Creating an EmpathyTLSCertificate for path %s, bus name %s",
+ DEBUG ("Creating an TpTLSCertificate for path %s, bus name %s",
cert_object_path, bus_name);
- empathy_tls_certificate_new_async (bus_name, cert_object_path,
- tls_certificate_constructed_cb, self);
+ priv->certificate = tp_tls_certificate_new (TP_PROXY (priv->channel),
+ cert_object_path, &error);
+
+ g_variant_unref (properties);
+
+ if (error != NULL)
+ {
+ DEBUG ("Unable to create the TpTLSCertificate: error %s",
+ error->message);
+
+ g_simple_async_result_set_from_error (priv->async_init_res, error);
+ g_simple_async_result_complete_in_idle (priv->async_init_res);
+
+ g_error_free (error);
+ tp_clear_object (&priv->async_init_res);
+
+ return;
+ }
+
+ tp_proxy_prepare_async (priv->certificate, features,
+ tls_certificate_prepared_cb, self);
}
static void
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);
}
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;
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (oclass, PROP_CHANNEL, pspec);
- pspec = g_param_spec_object ("certificate", "The EmpathyTLSCertificate",
- "The EmpathyTLSCertificate carried by the channel.",
- EMPATHY_TYPE_TLS_CERTIFICATE,
+ pspec = g_param_spec_object ("certificate", "The TpTLSCertificate",
+ "The TpTLSCertificate carried by the channel.",
+ TP_TYPE_TLS_CERTIFICATE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
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
return NULL;
}
-EmpathyTLSCertificate *
+TpTLSCertificate *
empathy_server_tls_handler_get_certificate (EmpathyServerTLSHandler *self)
{
EmpathyServerTLSHandlerPriv *priv = GET_PRIV (self);
g_assert (priv->certificate != NULL);
-
+
return priv->certificate;
}