]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-server-tls-handler.c
sort contacts by most recent event
[empathy.git] / libempathy / empathy-server-tls-handler.c
index feabdfbcda8d94fd9ed77043a9299504187c82ce..f5f60d649176c52fa74f3135f09b1153d43e399a 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include "config.h"
 #include "empathy-server-tls-handler.h"
 
-#define DEBUG_FLAG EMPATHY_DEBUG_TLS
-#include "empathy-debug.h"
-#include "empathy-tls-certificate.h"
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
 #include "empathy-utils.h"
 
-#include "extensions/extensions.h"
+#define DEBUG_FLAG EMPATHY_DEBUG_TLS
+#include "empathy-debug.h"
 
 static void async_initable_iface_init (GAsyncInitableIface *iface);
 
@@ -33,14 +34,16 @@ enum {
   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;
@@ -52,66 +55,23 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyServerTLSHandler, empathy_server_tls_handler,
 #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);
-}
-
-static void
-server_tls_channel_got_all_cb (TpProxy *proxy,
-    GHashTable *properties,
-    const GError *error,
-    gpointer user_data,
-    GObject *weak_object)
-{
-  EmpathyServerTLSHandler *self = EMPATHY_SERVER_TLS_HANDLER (weak_object);
-  EmpathyServerTLSHandlerPriv *priv = GET_PRIV (self);
-  
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (priv->async_init_res, error);
-      g_simple_async_result_complete_in_idle (priv->async_init_res);
-    }
-  else
-    {
-      const gchar *cert_object_path;
-      const gchar *hostname;
-
-      cert_object_path = tp_asv_get_object_path (properties,
-          "ServerCertificate");
-
-      DEBUG ("Creating an EmpathyTLSCertificate for path %s, bus name %s",
-          cert_object_path, tp_proxy_get_bus_name (proxy));
-
-      empathy_tls_certificate_new_async (
-          tp_proxy_get_bus_name (proxy),
-          cert_object_path,
-          tls_certificate_constructed_cb, self);
-
-      hostname = tp_asv_get_string (properties, "Hostname");
-      priv->hostname = g_strdup (hostname);
-
-      DEBUG ("Received hostname: %s", hostname);
-    }
+  tp_clear_object (&priv->async_init_res);
 }
 
 static gboolean
@@ -120,10 +80,9 @@ tls_handler_init_finish (GAsyncInitable *initable,
     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;
@@ -136,18 +95,83 @@ tls_handler_init_async (GAsyncInitable *initable,
     GAsyncReadyCallback callback,
     gpointer user_data)
 {
+  GVariant *properties;
+  const gchar *cert_object_path;
+  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, NULL);
+      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);
+
+  DEBUG ("Received hostname: %s", priv->hostname);
 
-  /* call GetAll() on the channel properties */
-  tp_cli_dbus_properties_call_get_all (priv->channel,
-      -1, EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION,
-      server_tls_channel_got_all_cb, NULL, NULL, G_OBJECT (self));
+  g_variant_lookup (properties,
+      TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_REFERENCE_IDENTITIES,
+      "^as", &priv->reference_identities);
+
+  /*
+   * 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,
+      TP_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 TpTLSCertificate for path %s, bus name %s",
+      cert_object_path, bus_name);
+
+  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
@@ -163,9 +187,11 @@ empathy_server_tls_handler_finalize (GObject *object)
   EmpathyServerTLSHandlerPriv *priv = GET_PRIV (object);
 
   DEBUG ("%p", object);
-  
-  if (priv->channel != NULL)
-    g_object_unref (priv->channel);
+
+  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);
 }
@@ -189,6 +215,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;
@@ -232,17 +261,23 @@ empathy_server_tls_handler_class_init (EmpathyServerTLSHandlerClass *klass)
       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
@@ -283,12 +318,12 @@ empathy_server_tls_handler_new_finish (GAsyncResult *result,
     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;
 }