]> git.0d.be Git - empathy.git/blob - libempathy/empathy-tls-certificate.c
Add EmpathyTLSCertificate.
[empathy.git] / libempathy / empathy-tls-certificate.c
1 /*
2  * empathy-tls-certificate.c - Source for EmpathyTLSCertificate
3  * Copyright (C) 2010 Collabora Ltd.
4  * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <config.h>
22
23 #include "empathy-tls-certificate.h"
24
25 #define DEBUG_FLAG EMPATHY_DEBUG_TLS
26 #include "empathy-debug.h"
27 #include "empathy-utils.h"
28
29 #include "extensions/extensions.h"
30
31 static void async_initable_iface_init (GAsyncInitableIface *iface);
32
33 enum {
34   PROP_OBJECT_PATH = 1,
35   PROP_BUS_NAME,
36   LAST_PROPERTY,
37 };
38
39 typedef struct {
40   gchar *object_path;
41   gchar *bus_name;
42
43   TpProxy *proxy;
44
45   GSimpleAsyncResult *async_init_res;
46
47   /* TLSCertificate properties */
48   gchar *cert_type;
49   GPtrArray *cert_data;
50   EmpTLSCertificateState state;
51   EmpTLSCertificateRejectReason reject_reason;
52 } EmpathyTLSCertificatePriv;
53
54 G_DEFINE_TYPE_WITH_CODE (EmpathyTLSCertificate, empathy_tls_certificate,
55     G_TYPE_OBJECT,
56     G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init));
57
58 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTLSCertificate);
59
60 static gboolean
61 tls_certificate_init_finish (GAsyncInitable *initable,
62     GAsyncResult *res,
63     GError **error)
64 {
65   gboolean retval = TRUE;
66   EmpathyTLSCertificate *self = EMPATHY_TLS_CERTIFICATE (initable);
67   EmpathyTLSCertificatePriv *priv = GET_PRIV (self);
68
69   if (g_simple_async_result_propagate_error (priv->async_init_res, error))
70     retval = FALSE;
71
72   return retval;  
73 }
74
75 static GType
76 array_of_ay_get_type (void)
77 {
78   static GType t = 0;
79
80   if (G_UNLIKELY (t == 0))
81     {
82       t = dbus_g_type_get_collection ("GPtrArray",
83           dbus_g_type_get_collection ("GArray",
84               G_TYPE_UCHAR));
85     }
86
87   return t;
88 }
89
90 static void
91 tls_certificate_got_all_cb (TpProxy *proxy,
92     GHashTable *properties,
93     const GError *error,
94     gpointer user_data,
95     GObject *weak_object)
96 {
97   GPtrArray *cert_data;
98   EmpathyTLSCertificate *self = EMPATHY_TLS_CERTIFICATE (weak_object);
99   EmpathyTLSCertificatePriv *priv = GET_PRIV (self);
100
101   if (error != NULL)
102     {
103       g_simple_async_result_set_from_error (priv->async_init_res, error);
104       g_simple_async_result_complete_in_idle (priv->async_init_res);
105
106       return;
107     }
108
109   priv->cert_type = g_strdup (tp_asv_get_string (properties,
110           "CertificateType"));
111   priv->state = tp_asv_get_uint32 (properties, "State", NULL);
112   priv->reject_reason = tp_asv_get_uint32 (properties, "RejectReason", NULL);
113
114   cert_data = tp_asv_get_boxed (properties, "CertificateChainData",
115       array_of_ay_get_type ());
116   g_assert (cert_data != NULL);
117   priv->cert_data = g_boxed_copy (array_of_ay_get_type (), cert_data);
118
119   DEBUG ("Got a certificate chain long %u, of type %s",
120       priv->cert_data->len, priv->cert_type);
121
122   g_simple_async_result_complete_in_idle (priv->async_init_res);
123 }
124
125 static void
126 tls_certificate_init_async (GAsyncInitable *initable,
127     gint io_priority,
128     GCancellable *cancellable,
129     GAsyncReadyCallback callback,
130     gpointer user_data)
131 {
132   TpDBusDaemon *dbus;
133   GError *error = NULL;
134   EmpathyTLSCertificate *self = EMPATHY_TLS_CERTIFICATE (initable);
135   EmpathyTLSCertificatePriv *priv = GET_PRIV (self);
136
137   g_assert (priv->object_path != NULL);
138   g_assert (priv->bus_name != NULL);
139
140   priv->async_init_res = g_simple_async_result_new (G_OBJECT (self),
141       callback, user_data, NULL);
142   dbus = tp_dbus_daemon_dup (&error);
143
144   if (error != NULL)
145     {
146       g_simple_async_result_set_from_error (priv->async_init_res, error);
147       g_simple_async_result_complete_in_idle (priv->async_init_res);
148
149       g_error_free (error);
150       return;
151     }
152
153   DEBUG ("Creating a proxy for object at path %s, owned by %s",
154       priv->object_path, priv->bus_name);
155
156   priv->proxy = g_object_new (TP_TYPE_PROXY,
157       "object-path", priv->object_path,
158       "bus-name", priv->bus_name,
159       "dbus-daemon", dbus, NULL);
160
161   /* call GetAll() on the certificate */
162   tp_cli_dbus_properties_call_get_all (priv->proxy,
163       -1, EMP_IFACE_AUTHENTICATION_TLS_CERTIFICATE,
164       tls_certificate_got_all_cb, NULL, NULL, G_OBJECT (self));
165
166   g_object_unref (dbus);
167 }
168
169 static void
170 async_initable_iface_init (GAsyncInitableIface *iface)
171 {
172   iface->init_async = tls_certificate_init_async;
173   iface->init_finish = tls_certificate_init_finish;
174 }
175
176 static void
177 empathy_tls_certificate_finalize (GObject *object)
178 {
179   EmpathyTLSCertificatePriv *priv = GET_PRIV (object);
180
181   g_free (priv->object_path);
182
183   G_OBJECT_CLASS (empathy_tls_certificate_parent_class)->finalize (object);
184 }
185
186 static void
187 empathy_tls_certificate_get_property (GObject *object,
188     guint property_id,
189     GValue *value,
190     GParamSpec *pspec)
191 {
192   EmpathyTLSCertificatePriv *priv = GET_PRIV (object);
193
194   switch (property_id)
195     {
196     case PROP_OBJECT_PATH:
197       g_value_set_string (value, priv->object_path);
198       break;
199     case PROP_BUS_NAME:
200       g_value_set_string (value, priv->bus_name);
201       break;
202     default:
203       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
204       break;
205     }
206 }
207
208 static void
209 empathy_tls_certificate_set_property (GObject *object,
210     guint property_id,
211     const GValue *value,
212     GParamSpec *pspec)
213 {
214   EmpathyTLSCertificatePriv *priv = GET_PRIV (object);
215
216   switch (property_id)
217     {
218     case PROP_OBJECT_PATH:
219       priv->object_path = g_value_dup_string (value);
220       break;
221     case PROP_BUS_NAME:
222       priv->bus_name = g_value_dup_string (value);
223       break;
224     default:
225       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
226       break;
227     }
228 }
229
230 static void
231 empathy_tls_certificate_init (EmpathyTLSCertificate *self)
232 {
233   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
234       EMPATHY_TYPE_TLS_CERTIFICATE, EmpathyTLSCertificatePriv);
235 }
236
237 static void
238 empathy_tls_certificate_class_init (EmpathyTLSCertificateClass *klass)
239 {
240   GParamSpec *pspec;
241   GObjectClass *oclass = G_OBJECT_CLASS (klass);
242
243   oclass->get_property = empathy_tls_certificate_get_property;
244   oclass->set_property = empathy_tls_certificate_set_property;
245   oclass->finalize = empathy_tls_certificate_finalize;
246   
247   g_type_class_add_private (klass, sizeof (EmpathyTLSCertificatePriv));
248
249   pspec = g_param_spec_string ("object-path", "The object path",
250       "The path on the bus where the object we proxy is living.",
251       NULL,
252       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
253   g_object_class_install_property (oclass, PROP_OBJECT_PATH, pspec);
254
255   pspec = g_param_spec_string ("bus-name", "The bus name",
256       "The bus name owning this certificate.",
257       NULL,
258       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
259   g_object_class_install_property (oclass, PROP_BUS_NAME, pspec);
260 }
261
262 void
263 empathy_tls_certificate_new_async (const gchar *bus_name,
264     const gchar *object_path,
265     GAsyncReadyCallback callback,
266     gpointer user_data)
267 {
268   g_assert (object_path != NULL);
269
270   g_async_initable_new_async (EMPATHY_TYPE_TLS_CERTIFICATE,
271       G_PRIORITY_DEFAULT, NULL, callback, user_data,
272       "bus-name", bus_name,
273       "object-path", object_path, NULL);
274 }
275
276 EmpathyTLSCertificate *
277 empathy_tls_certificate_new_finish (GAsyncResult *res,
278     GError **error)
279 {
280   GObject *object, *source_object;
281
282   source_object = g_async_result_get_source_object (res);
283
284   object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
285       res, error);
286   g_object_unref (source_object);
287
288   if (object != NULL)
289     return EMPATHY_TLS_CERTIFICATE (object);
290   else
291     return NULL;
292 }