Updated Portuguese translation
[empathy-mirror.git] / libempathy / empathy-server-tls-handler.c
blobf5f60d649176c52fa74f3135f09b1153d43e399a
1 /*
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
21 #include "config.h"
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);
33 enum {
34 PROP_CHANNEL = 1,
35 PROP_TLS_CERTIFICATE,
36 PROP_HOSTNAME,
37 PROP_REFERENCE_IDENTITIES,
38 LAST_PROPERTY,
41 typedef struct {
42 TpChannel *channel;
44 TpTLSCertificate *certificate;
45 gchar *hostname;
46 gchar **reference_identities;
48 GSimpleAsyncResult *async_init_res;
49 } EmpathyServerTLSHandlerPriv;
51 G_DEFINE_TYPE_WITH_CODE (EmpathyServerTLSHandler, empathy_server_tls_handler,
52 G_TYPE_OBJECT,
53 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init));
55 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyServerTLSHandler);
57 static void
58 tls_certificate_prepared_cb (GObject *source,
59 GAsyncResult *result,
60 gpointer user_data)
62 TpTLSCertificate *certificate = TP_TLS_CERTIFICATE (source);
63 EmpathyServerTLSHandler *self = user_data;
64 GError *error = NULL;
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);
70 g_error_free (error);
73 g_simple_async_result_complete_in_idle (priv->async_init_res);
74 tp_clear_object (&priv->async_init_res);
77 static gboolean
78 tls_handler_init_finish (GAsyncInitable *initable,
79 GAsyncResult *res,
80 GError **error)
82 gboolean retval = TRUE;
84 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
85 error))
86 retval = FALSE;
88 return retval;
91 static void
92 tls_handler_init_async (GAsyncInitable *initable,
93 gint io_priority,
94 GCancellable *cancellable,
95 GAsyncReadyCallback callback,
96 gpointer user_data)
98 GVariant *properties;
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);
137 else
139 #ifdef ENABLE_DEBUG
140 gchar *output = g_strjoinv (", ", (gchar **) priv->reference_identities);
141 DEBUG ("Received reference identities: %s", output);
142 g_free (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);
159 if (error != NULL)
161 DEBUG ("Unable to create the TpTLSCertificate: error %s",
162 error->message);
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);
170 return;
173 tp_proxy_prepare_async (priv->certificate, features,
174 tls_certificate_prepared_cb, self);
177 static void
178 async_initable_iface_init (GAsyncInitableIface *iface)
180 iface->init_async = tls_handler_init_async;
181 iface->init_finish = tls_handler_init_finish;
184 static void
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);
199 static void
200 empathy_server_tls_handler_get_property (GObject *object,
201 guint property_id,
202 GValue *value,
203 GParamSpec *pspec)
205 EmpathyServerTLSHandlerPriv *priv = GET_PRIV (object);
207 switch (property_id)
209 case PROP_CHANNEL:
210 g_value_set_object (value, priv->channel);
211 break;
212 case PROP_TLS_CERTIFICATE:
213 g_value_set_object (value, priv->certificate);
214 break;
215 case PROP_HOSTNAME:
216 g_value_set_string (value, priv->hostname);
217 break;
218 case PROP_REFERENCE_IDENTITIES:
219 g_value_set_boxed (value, priv->reference_identities);
220 break;
221 default:
222 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
223 break;
227 static void
228 empathy_server_tls_handler_set_property (GObject *object,
229 guint property_id,
230 const GValue *value,
231 GParamSpec *pspec)
233 EmpathyServerTLSHandlerPriv *priv = GET_PRIV (object);
235 switch (property_id)
237 case PROP_CHANNEL:
238 priv->channel = g_value_dup_object (value);
239 break;
240 default:
241 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
242 break;
246 static void
247 empathy_server_tls_handler_class_init (EmpathyServerTLSHandlerClass *klass)
249 GObjectClass *oclass = G_OBJECT_CLASS (klass);
250 GParamSpec *pspec;
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.",
260 TP_TYPE_CHANNEL,
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.",
272 NULL,
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);
283 static void
284 empathy_server_tls_handler_init (EmpathyServerTLSHandler *self)
286 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
287 EMPATHY_TYPE_SERVER_TLS_HANDLER, EmpathyServerTLSHandlerPriv);
290 void
291 empathy_server_tls_handler_new_async (TpChannel *channel,
292 GAsyncReadyCallback callback,
293 gpointer user_data)
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,
305 GError **error)
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),
312 result, error);
313 g_object_unref (source_object);
315 if (object != NULL)
316 return EMPATHY_SERVER_TLS_HANDLER (object);
317 else
318 return NULL;
321 TpTLSCertificate *
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;