2 * empathy-server-tls-handler.c - Source for EmpathyServerTLSHandler
3 * Copyright (C) 2010 Collabora Ltd.
4 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "empathy-server-tls-handler.h"
24 #include <telepathy-glib/telepathy-glib-dbus.h>
26 #include "empathy-utils.h"
28 #define DEBUG_FLAG EMPATHY_DEBUG_TLS
29 #include "empathy-debug.h"
31 static void async_initable_iface_init (GAsyncInitableIface
*iface
);
37 PROP_REFERENCE_IDENTITIES
,
44 TpTLSCertificate
*certificate
;
46 gchar
**reference_identities
;
48 GSimpleAsyncResult
*async_init_res
;
49 } EmpathyServerTLSHandlerPriv
;
51 G_DEFINE_TYPE_WITH_CODE (EmpathyServerTLSHandler
, empathy_server_tls_handler
,
53 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE
, async_initable_iface_init
));
55 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerTLSHandler);
58 tls_certificate_prepared_cb (GObject
*source
,
62 TpTLSCertificate
*certificate
= TP_TLS_CERTIFICATE (source
);
63 EmpathyServerTLSHandler
*self
= user_data
;
65 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (self
);
67 if (!tp_proxy_prepare_finish (certificate
, result
, &error
))
69 g_simple_async_result_set_from_error (priv
->async_init_res
, error
);
73 g_simple_async_result_complete_in_idle (priv
->async_init_res
);
74 tp_clear_object (&priv
->async_init_res
);
78 tls_handler_init_finish (GAsyncInitable
*initable
,
82 gboolean retval
= TRUE
;
84 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res
),
92 tls_handler_init_async (GAsyncInitable
*initable
,
94 GCancellable
*cancellable
,
95 GAsyncReadyCallback callback
,
99 const gchar
*cert_object_path
;
100 const gchar
*bus_name
;
101 GError
*error
= NULL
;
102 GQuark features
[] = { TP_TLS_CERTIFICATE_FEATURE_CORE
, 0 };
104 * Used when channel doesn't implement ReferenceIdentities. A GStrv
105 * with [0] the hostname, and [1] a NULL terminator.
107 gchar
*default_identities
[2];
108 EmpathyServerTLSHandler
*self
= EMPATHY_SERVER_TLS_HANDLER (initable
);
109 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (self
);
111 g_assert (priv
->channel
!= NULL
);
113 priv
->async_init_res
= g_simple_async_result_new (G_OBJECT (self
),
114 callback
, user_data
, empathy_server_tls_handler_new_async
);
115 properties
= tp_channel_dup_immutable_properties (priv
->channel
);
117 g_variant_lookup (properties
,
118 TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_HOSTNAME
,
119 "s", &priv
->hostname
);
121 DEBUG ("Received hostname: %s", priv
->hostname
);
123 g_variant_lookup (properties
,
124 TP_PROP_CHANNEL_TYPE_SERVER_TLS_CONNECTION_REFERENCE_IDENTITIES
,
125 "^as", &priv
->reference_identities
);
128 * If the channel doesn't implement the ReferenceIdentities parameter
129 * then fallback to the hostname.
131 if (priv
->reference_identities
== NULL
)
133 default_identities
[0] = (gchar
*) priv
->hostname
;
134 default_identities
[1] = NULL
;
135 priv
->reference_identities
= g_strdupv (default_identities
);
140 gchar
*output
= g_strjoinv (", ", (gchar
**) priv
->reference_identities
);
141 DEBUG ("Received reference identities: %s", output
);
143 #endif /* ENABLE_DEBUG */
146 g_variant_lookup (properties
,
147 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
".ServerCertificate",
148 "&o", &cert_object_path
);
149 bus_name
= tp_proxy_get_bus_name (TP_PROXY (priv
->channel
));
151 DEBUG ("Creating an TpTLSCertificate for path %s, bus name %s",
152 cert_object_path
, bus_name
);
154 priv
->certificate
= tp_tls_certificate_new (TP_PROXY (priv
->channel
),
155 cert_object_path
, &error
);
157 g_variant_unref (properties
);
161 DEBUG ("Unable to create the TpTLSCertificate: error %s",
164 g_simple_async_result_set_from_error (priv
->async_init_res
, error
);
165 g_simple_async_result_complete_in_idle (priv
->async_init_res
);
167 g_error_free (error
);
168 tp_clear_object (&priv
->async_init_res
);
173 tp_proxy_prepare_async (priv
->certificate
, features
,
174 tls_certificate_prepared_cb
, self
);
178 async_initable_iface_init (GAsyncInitableIface
*iface
)
180 iface
->init_async
= tls_handler_init_async
;
181 iface
->init_finish
= tls_handler_init_finish
;
185 empathy_server_tls_handler_finalize (GObject
*object
)
187 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (object
);
189 DEBUG ("%p", object
);
191 tp_clear_object (&priv
->channel
);
192 tp_clear_object (&priv
->certificate
);
193 g_strfreev (priv
->reference_identities
);
194 g_free (priv
->hostname
);
196 G_OBJECT_CLASS (empathy_server_tls_handler_parent_class
)->finalize (object
);
200 empathy_server_tls_handler_get_property (GObject
*object
,
205 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (object
);
210 g_value_set_object (value
, priv
->channel
);
212 case PROP_TLS_CERTIFICATE
:
213 g_value_set_object (value
, priv
->certificate
);
216 g_value_set_string (value
, priv
->hostname
);
218 case PROP_REFERENCE_IDENTITIES
:
219 g_value_set_boxed (value
, priv
->reference_identities
);
222 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
228 empathy_server_tls_handler_set_property (GObject
*object
,
233 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (object
);
238 priv
->channel
= g_value_dup_object (value
);
241 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
247 empathy_server_tls_handler_class_init (EmpathyServerTLSHandlerClass
*klass
)
249 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
252 oclass
->get_property
= empathy_server_tls_handler_get_property
;
253 oclass
->set_property
= empathy_server_tls_handler_set_property
;
254 oclass
->finalize
= empathy_server_tls_handler_finalize
;
256 g_type_class_add_private (klass
, sizeof (EmpathyServerTLSHandlerPriv
));
258 pspec
= g_param_spec_object ("channel", "The TpChannel",
259 "The TpChannel this handler is supposed to handle.",
261 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
| G_PARAM_STATIC_STRINGS
);
262 g_object_class_install_property (oclass
, PROP_CHANNEL
, pspec
);
264 pspec
= g_param_spec_object ("certificate", "The TpTLSCertificate",
265 "The TpTLSCertificate carried by the channel.",
266 TP_TYPE_TLS_CERTIFICATE
,
267 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
268 g_object_class_install_property (oclass
, PROP_TLS_CERTIFICATE
, pspec
);
270 pspec
= g_param_spec_string ("hostname", "The hostname",
271 "The hostname the user is expecting to connect to.",
273 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
274 g_object_class_install_property (oclass
, PROP_HOSTNAME
, pspec
);
276 pspec
= g_param_spec_boxed ("reference-identities", "Reference Identities",
277 "The server certificate should certify one of these identities",
278 G_TYPE_STRV
, G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
279 g_object_class_install_property (oclass
, PROP_REFERENCE_IDENTITIES
, pspec
);
284 empathy_server_tls_handler_init (EmpathyServerTLSHandler
*self
)
286 self
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (self
,
287 EMPATHY_TYPE_SERVER_TLS_HANDLER
, EmpathyServerTLSHandlerPriv
);
291 empathy_server_tls_handler_new_async (TpChannel
*channel
,
292 GAsyncReadyCallback callback
,
295 g_assert (TP_IS_CHANNEL (channel
));
296 g_assert (channel
!= NULL
);
298 g_async_initable_new_async (EMPATHY_TYPE_SERVER_TLS_HANDLER
,
299 G_PRIORITY_DEFAULT
, NULL
, callback
, user_data
,
300 "channel", channel
, NULL
);
303 EmpathyServerTLSHandler
*
304 empathy_server_tls_handler_new_finish (GAsyncResult
*result
,
307 GObject
*object
, *source_object
;
309 source_object
= g_async_result_get_source_object (result
);
311 object
= g_async_initable_new_finish (G_ASYNC_INITABLE (source_object
),
313 g_object_unref (source_object
);
316 return EMPATHY_SERVER_TLS_HANDLER (object
);
322 empathy_server_tls_handler_get_certificate (EmpathyServerTLSHandler
*self
)
324 EmpathyServerTLSHandlerPriv
*priv
= GET_PRIV (self
);
326 g_assert (priv
->certificate
!= NULL
);
328 return priv
->certificate
;