Codebase list telepathy-idle / c5d839c
Copy TLS channel code from gabble Take the TLS channel handling code from Gabble and s/gabble/idle in the various files, but no other changes Sjoerd Simons 11 years ago
6 changed file(s) with 1448 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 /*
1 * server-tls-channel.c - Source for IdleServerTLSChannel
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <config.h>
21
22 #include "server-tls-channel.h"
23
24 #include <telepathy-glib/telepathy-glib.h>
25 #include <telepathy-glib/telepathy-glib-dbus.h>
26
27 #include <wocky/wocky.h>
28
29 #define DEBUG_FLAG IDLE_DEBUG_TLS
30 #include "debug.h"
31 #include "connection.h"
32 #include "tls-certificate.h"
33
34 G_DEFINE_TYPE_WITH_CODE (IdleServerTLSChannel, idle_server_tls_channel,
35 TP_TYPE_BASE_CHANNEL,
36 G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_SERVER_TLS_CONNECTION,
37 NULL));
38
39 static void idle_server_tls_channel_close (TpBaseChannel *base);
40
41 enum {
42 /* server TLS channel iface */
43 PROP_SERVER_CERTIFICATE = 1,
44 PROP_HOSTNAME,
45 PROP_REFERENCE_IDENTITIES,
46
47 /* not exported */
48 PROP_TLS_SESSION,
49
50 NUM_PROPERTIES
51 };
52
53 struct _IdleServerTLSChannelPrivate {
54 WockyTLSSession *tls_session;
55
56 IdleTLSCertificate *server_cert;
57 gchar *server_cert_path;
58 gchar *hostname;
59 GStrv reference_identities;
60
61 gboolean dispose_has_run;
62 };
63
64 static void
65 idle_server_tls_channel_get_property (GObject *object,
66 guint property_id,
67 GValue *value,
68 GParamSpec *pspec)
69 {
70 IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object);
71
72 switch (property_id)
73 {
74 case PROP_SERVER_CERTIFICATE:
75 g_value_set_boxed (value, self->priv->server_cert_path);
76 break;
77 case PROP_HOSTNAME:
78 g_value_set_string (value, self->priv->hostname);
79 break;
80 case PROP_REFERENCE_IDENTITIES:
81 g_value_set_boxed (value, self->priv->reference_identities);
82 break;
83 case PROP_TLS_SESSION:
84 g_value_set_object (value, self->priv->tls_session);
85 break;
86 default:
87 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
88 break;
89 }
90 }
91
92 static void
93 idle_server_tls_channel_set_property (GObject *object,
94 guint property_id,
95 const GValue *value,
96 GParamSpec *pspec)
97 {
98 IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object);
99
100 switch (property_id)
101 {
102 case PROP_TLS_SESSION:
103 self->priv->tls_session = g_value_dup_object (value);
104 break;
105 case PROP_HOSTNAME:
106 self->priv->hostname = g_value_dup_string (value);
107 break;
108 case PROP_REFERENCE_IDENTITIES:
109 self->priv->reference_identities = g_value_dup_boxed (value);
110 break;
111 default:
112 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
113 break;
114 }
115 }
116
117 static void
118 idle_server_tls_channel_finalize (GObject *object)
119 {
120 IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object);
121
122 DEBUG ("Finalize TLS channel");
123
124 g_free (self->priv->server_cert_path);
125 g_free (self->priv->hostname);
126 g_strfreev (self->priv->reference_identities);
127
128 G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->finalize (object);
129 }
130
131 static void
132 idle_server_tls_channel_dispose (GObject *object)
133 {
134 IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object);
135
136 if (self->priv->dispose_has_run)
137 return;
138
139 DEBUG ("Dispose TLS channel");
140
141 self->priv->dispose_has_run = TRUE;
142
143 tp_clear_object (&self->priv->server_cert);
144 tp_clear_object (&self->priv->tls_session);
145
146 G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->dispose (object);
147 }
148
149 static const gchar *
150 cert_type_to_str (WockyTLSCertType type)
151 {
152 const gchar *retval = NULL;
153
154 switch (type)
155 {
156 case WOCKY_TLS_CERT_TYPE_X509:
157 retval = "x509";
158 break;
159 case WOCKY_TLS_CERT_TYPE_OPENPGP:
160 retval = "pgp";
161 break;
162 default:
163 break;
164 }
165
166 return retval;
167 }
168
169 static void
170 idle_server_tls_channel_constructed (GObject *object)
171 {
172 IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object);
173 TpBaseChannel *base = TP_BASE_CHANNEL (self);
174 TpBaseConnection *base_conn = tp_base_channel_get_connection (base);
175 void (*chain_up) (GObject *) =
176 G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->constructed;
177 WockyTLSCertType cert_type;
178 const gchar *path;
179 gchar *cert_object_path;
180 GPtrArray *certificates;
181
182 if (chain_up != NULL)
183 chain_up (object);
184
185 tp_base_channel_register (base);
186
187 /* create the TLS certificate object */
188 path = tp_base_channel_get_object_path (base);
189 cert_object_path = g_strdup_printf ("%s/TLSCertificateObject", path);
190 certificates = wocky_tls_session_get_peers_certificate (
191 self->priv->tls_session, &cert_type);
192
193 self->priv->server_cert = g_object_new (IDLE_TYPE_TLS_CERTIFICATE,
194 "object-path", cert_object_path,
195 "certificate-chain-data", certificates,
196 "certificate-type", cert_type_to_str (cert_type),
197 "dbus-daemon", IDLE_CONNECTION (base_conn)->daemon,
198 NULL);
199 self->priv->server_cert_path = cert_object_path;
200
201 DEBUG ("Server TLS channel constructed at %s", path);
202 }
203
204 static void
205 idle_server_tls_channel_fill_immutable_properties (
206 TpBaseChannel *chan,
207 GHashTable *properties)
208 {
209 TP_BASE_CHANNEL_CLASS (idle_server_tls_channel_parent_class)
210 ->fill_immutable_properties (chan, properties);
211
212 tp_dbus_properties_mixin_fill_properties_hash (
213 G_OBJECT (chan), properties,
214 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "ServerCertificate",
215 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "Hostname",
216 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "ReferenceIdentities",
217 NULL);
218 }
219
220 static gchar *
221 idle_server_tls_channel_get_object_path_suffix (TpBaseChannel *base)
222 {
223 static guint count = 0;
224
225 return g_strdup_printf ("ServerTLSChannel%u", ++count);
226 }
227
228 static void
229 idle_server_tls_channel_init (IdleServerTLSChannel *self)
230 {
231 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
232 IDLE_TYPE_SERVER_TLS_CHANNEL, IdleServerTLSChannelPrivate);
233 }
234
235 static void
236 idle_server_tls_channel_class_init (IdleServerTLSChannelClass *klass)
237 {
238 static TpDBusPropertiesMixinPropImpl server_tls_props[] = {
239 { "ServerCertificate", "server-certificate", NULL },
240 { "Hostname", "hostname", NULL },
241 { "ReferenceIdentities", "reference-identities", NULL },
242 { NULL }
243 };
244
245 GObjectClass *oclass = G_OBJECT_CLASS (klass);
246 TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
247 GParamSpec *pspec;
248
249 g_type_class_add_private (klass, sizeof (IdleServerTLSChannelPrivate));
250
251 oclass->get_property = idle_server_tls_channel_get_property;
252 oclass->set_property = idle_server_tls_channel_set_property;
253 oclass->dispose = idle_server_tls_channel_dispose;
254 oclass->finalize = idle_server_tls_channel_finalize;
255 oclass->constructed = idle_server_tls_channel_constructed;
256
257 base_class->channel_type = TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION;
258 base_class->target_handle_type = TP_HANDLE_TYPE_NONE;
259 base_class->fill_immutable_properties =
260 idle_server_tls_channel_fill_immutable_properties;
261 base_class->get_object_path_suffix =
262 idle_server_tls_channel_get_object_path_suffix;
263 base_class->close = idle_server_tls_channel_close;
264
265 pspec = g_param_spec_boxed ("server-certificate", "Server certificate path",
266 "The object path of the server certificate.",
267 DBUS_TYPE_G_OBJECT_PATH,
268 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
269 g_object_class_install_property (oclass, PROP_SERVER_CERTIFICATE, pspec);
270
271 pspec = g_param_spec_string ("hostname", "The hostname to be verified",
272 "The hostname which should be certified by the server certificate.",
273 NULL,
274 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
275 g_object_class_install_property (oclass, PROP_HOSTNAME, pspec);
276
277 pspec = g_param_spec_boxed ("reference-identities",
278 "The various identities to check the certificate against",
279 "The server certificate identity should match one of these identities.",
280 G_TYPE_STRV,
281 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
282 g_object_class_install_property (oclass, PROP_REFERENCE_IDENTITIES, pspec);
283
284 pspec = g_param_spec_object ("tls-session", "The WockyTLSSession",
285 "The WockyTLSSession object containing the TLS information",
286 WOCKY_TYPE_TLS_SESSION,
287 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
288 g_object_class_install_property (oclass, PROP_TLS_SESSION, pspec);
289
290 tp_dbus_properties_mixin_implement_interface (oclass,
291 TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION,
292 tp_dbus_properties_mixin_getter_gobject_properties, NULL,
293 server_tls_props);
294 }
295
296 static void
297 idle_server_tls_channel_close (TpBaseChannel *base)
298 {
299 DEBUG ("Close() called on the TLS channel %p", base);
300 tp_base_channel_destroyed (base);
301 }
302
303 IdleTLSCertificate *
304 idle_server_tls_channel_get_certificate (IdleServerTLSChannel *self)
305 {
306 return self->priv->server_cert;
307 }
0 /*
1 * server-tls-channel.h - Header for IdleServerTLSChannel
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef __IDLE_SERVER_TLS_CHANNEL_H__
21 #define __IDLE_SERVER_TLS_CHANNEL_H__
22
23 #include <glib-object.h>
24
25 #include <telepathy-glib/telepathy-glib.h>
26
27 #include <extensions/extensions.h>
28
29 #include "tls-certificate.h"
30
31 G_BEGIN_DECLS
32
33 typedef struct _IdleServerTLSChannelPrivate IdleServerTLSChannelPrivate;
34 typedef struct _IdleServerTLSChannelClass IdleServerTLSChannelClass;
35 typedef struct _IdleServerTLSChannel IdleServerTLSChannel;
36
37 struct _IdleServerTLSChannelClass {
38 TpBaseChannelClass base_class;
39 };
40
41 struct _IdleServerTLSChannel {
42 TpBaseChannel parent;
43
44 IdleServerTLSChannelPrivate *priv;
45 };
46
47 GType idle_server_tls_channel_get_type (void);
48
49 #define IDLE_TYPE_SERVER_TLS_CHANNEL \
50 (idle_server_tls_channel_get_type ())
51 #define IDLE_SERVER_TLS_CHANNEL(obj) \
52 (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_SERVER_TLS_CHANNEL, \
53 IdleServerTLSChannel))
54 #define IDLE_SERVER_TLS_CHANNEL_CLASS(klass) \
55 (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_SERVER_TLS_CHANNEL, \
56 IdleServerTLSChannelClass))
57 #define IDLE_IS_SERVER_TLS_CHANNEL(obj) \
58 (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_SERVER_TLS_CHANNEL))
59 #define IDLE_IS_SERVER_TLS_CHANNEL_CLASS(klass) \
60 (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_SERVER_TLS_CHANNEL))
61 #define IDLE_SERVER_TLS_CHANNEL_GET_CLASS(obj) \
62 (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_SERVER_TLS_CHANNEL,\
63 IdleServerTLSChannelClass))
64
65 IdleTLSCertificate * idle_server_tls_channel_get_certificate (
66 IdleServerTLSChannel *self);
67
68 G_END_DECLS
69
70 #endif /* #ifndef __IDLE_SERVER_TLS_CHANNEL_H__*/
0 /*
1 * server-tls-manager.c - Source for IdleServerTLSManager
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "config.h"
21 #include "server-tls-manager.h"
22
23 #include <telepathy-glib/telepathy-glib.h>
24 #include <telepathy-glib/telepathy-glib-dbus.h>
25
26 #define DEBUG_FLAG IDLE_DEBUG_TLS
27 #include "debug.h"
28 #include "gabble/caps-channel-manager.h"
29 #include "connection.h"
30 #include "server-tls-channel.h"
31 #include "util.h"
32
33 #include "extensions/extensions.h"
34
35 #include <wocky/wocky.h>
36
37 static void channel_manager_iface_init (gpointer, gpointer);
38
39 G_DEFINE_TYPE_WITH_CODE (IdleServerTLSManager, idle_server_tls_manager,
40 WOCKY_TYPE_TLS_HANDLER,
41 G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
42 channel_manager_iface_init);
43 G_IMPLEMENT_INTERFACE (IDLE_TYPE_CAPS_CHANNEL_MANAGER,
44 NULL));
45
46 enum {
47 PROP_CONNECTION = 1,
48 PROP_INTERACTIVE_TLS,
49 NUM_PROPERTIES
50 };
51
52 struct _IdleServerTLSManagerPrivate {
53 /* Properties */
54 IdleConnection *connection;
55 gboolean interactive_tls;
56
57 /* Current operation data */
58 gchar *peername;
59 GStrv reference_identities;
60 WockyTLSSession *tls_session;
61 IdleServerTLSChannel *channel;
62 GSimpleAsyncResult *async_result;
63
64 /* List of owned TpBaseChannel not yet closed by the client */
65 GList *completed_channels;
66
67 gboolean dispose_has_run;
68 };
69
70 #define chainup ((WockyTLSHandlerClass *) \
71 idle_server_tls_manager_parent_class)
72
73 static void
74 idle_server_tls_manager_get_property (GObject *object,
75 guint property_id,
76 GValue *value,
77 GParamSpec *pspec)
78 {
79 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object);
80
81 switch (property_id)
82 {
83 case PROP_CONNECTION:
84 g_value_set_object (value, self->priv->connection);
85 break;
86 case PROP_INTERACTIVE_TLS:
87 g_value_set_boolean (value, self->priv->interactive_tls);
88 break;
89 default:
90 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
91 break;
92 }
93 }
94
95 static void
96 idle_server_tls_manager_set_property (GObject *object,
97 guint property_id,
98 const GValue *value,
99 GParamSpec *pspec)
100 {
101 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object);
102
103 switch (property_id)
104 {
105 case PROP_CONNECTION:
106 self->priv->connection = g_value_dup_object (value);
107 break;
108 case PROP_INTERACTIVE_TLS:
109 self->priv->interactive_tls = g_value_get_boolean (value);
110 break;
111 default:
112 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
113 break;
114 }
115 }
116
117 static void
118 close_all (IdleServerTLSManager *self)
119 {
120 GList *l;
121
122 if (self->priv->channel != NULL)
123 tp_base_channel_close (TP_BASE_CHANNEL (self->priv->channel));
124
125 l = self->priv->completed_channels;
126 while (l != NULL)
127 {
128 /* use a temporary variable as the ::closed callback will delete
129 * the link from the list. */
130 GList *next = l->next;
131
132 tp_base_channel_close (l->data);
133
134 l = next;
135 }
136 }
137
138 static void
139 connection_status_changed_cb (IdleConnection *conn,
140 guint status,
141 guint reason,
142 gpointer user_data)
143 {
144 IdleServerTLSManager *self = user_data;
145
146 DEBUG ("Connection status changed, now %d", status);
147
148 if (status == TP_CONNECTION_STATUS_DISCONNECTED)
149 {
150 close_all (self);
151 tp_clear_object (&self->priv->connection);
152 }
153 }
154
155 static void
156 complete_verify (IdleServerTLSManager *self)
157 {
158 /* Move channel to a list until a client Close() it */
159 if (self->priv->channel != NULL)
160 {
161 self->priv->completed_channels = g_list_prepend (
162 self->priv->completed_channels,
163 g_object_ref (self->priv->channel));
164 }
165
166 g_simple_async_result_complete (self->priv->async_result);
167
168 /* Reset to initial state */
169 tp_clear_pointer (&self->priv->peername, g_free);
170 tp_clear_pointer (&self->priv->reference_identities, g_strfreev);
171 g_clear_object (&self->priv->tls_session);
172 g_clear_object (&self->priv->channel);
173 g_clear_object (&self->priv->async_result);
174 }
175
176 static void
177 verify_fallback_cb (GObject *source,
178 GAsyncResult *result,
179 gpointer user_data)
180 {
181 IdleServerTLSManager *self = (IdleServerTLSManager *) source;
182 GError *error = NULL;
183
184 if (!chainup->verify_finish_func (WOCKY_TLS_HANDLER (self), result, &error))
185 g_simple_async_result_take_error (self->priv->async_result, error);
186
187 complete_verify (self);
188 }
189
190 static void
191 server_tls_channel_closed_cb (IdleServerTLSChannel *channel,
192 gpointer user_data)
193 {
194 IdleServerTLSManager *self = user_data;
195
196 DEBUG ("Server TLS channel closed.");
197
198 if (channel == self->priv->channel)
199 {
200 /* fallback to the old-style non interactive TLS verification */
201 DEBUG ("Channel closed, but unhandled, falling back...");
202
203 chainup->verify_async_func (WOCKY_TLS_HANDLER (self),
204 self->priv->tls_session, self->priv->peername,
205 self->priv->reference_identities, verify_fallback_cb, NULL);
206
207 self->priv->channel = NULL;
208 }
209 else
210 {
211 GList *l;
212
213 l = g_list_find (self->priv->completed_channels, channel);
214 g_assert (l != NULL);
215
216 self->priv->completed_channels = g_list_delete_link (
217 self->priv->completed_channels, l);
218 }
219
220 tp_channel_manager_emit_channel_closed_for_object (self,
221 TP_EXPORTABLE_CHANNEL (channel));
222 g_object_unref (channel);
223 }
224
225 GQuark
226 idle_server_tls_error_quark (void)
227 {
228 static GQuark quark = 0;
229
230 if (!quark)
231 quark = g_quark_from_static_string ("server-tls-error");
232
233 return quark;
234 }
235
236 static void
237 tls_certificate_accepted_cb (IdleTLSCertificate *certificate,
238 gpointer user_data)
239 {
240 IdleServerTLSManager *self = user_data;
241
242 DEBUG ("TLS certificate accepted");
243
244 complete_verify (self);
245 }
246
247 static void
248 tls_certificate_rejected_cb (IdleTLSCertificate *certificate,
249 GPtrArray *rejections,
250 gpointer user_data)
251 {
252 IdleServerTLSManager *self = user_data;
253
254 DEBUG ("TLS certificate rejected with rejections %p, length %u.",
255 rejections, rejections->len);
256
257 g_simple_async_result_set_error (self->priv->async_result,
258 IDLE_SERVER_TLS_ERROR, 0, "TLS certificate rejected");
259
260 complete_verify (self);
261 }
262
263 static void
264 extend_string_ptr_array (GPtrArray *array,
265 GStrv new_elements)
266 {
267 gint i;
268
269 if (new_elements != NULL)
270 {
271 for (i = 0; new_elements[i] != NULL; i++)
272 {
273 if (!tp_str_empty (new_elements[i]))
274 g_ptr_array_add (array, g_strdup (new_elements[i]));
275 }
276 }
277 }
278
279 static void
280 fill_reference_identities (IdleServerTLSManager *self,
281 const gchar *peername,
282 GStrv original_extra_identities)
283 {
284 GPtrArray *identities;
285 gchar *connect_server = NULL;
286 gchar *explicit_server = NULL;
287 GStrv extra_certificate_identities = NULL;
288
289 g_return_if_fail (self->priv->reference_identities == NULL);
290
291 g_object_get (self->priv->connection,
292 "connect-server", &connect_server,
293 "explicit-server", &explicit_server,
294 "extra-certificate-identities", &extra_certificate_identities,
295 NULL);
296
297 identities = g_ptr_array_new ();
298
299 /* The peer name, i.e, the domain part of the JID */
300 g_ptr_array_add (identities, g_strdup (peername));
301
302 /* The extra identities that the caller of verify_async() passed */
303 extend_string_ptr_array (identities, original_extra_identities);
304
305 /* The explicitly overridden server (if in use) */
306 if (!tp_str_empty (explicit_server) &&
307 !tp_strdiff (connect_server, explicit_server))
308 {
309 g_ptr_array_add (identities, g_strdup (explicit_server));
310 }
311
312 /* Extra identities added to the account as a result of user choices */
313 extend_string_ptr_array (identities, extra_certificate_identities);
314
315 /* Null terminate, since this is a gchar** */
316 g_ptr_array_add (identities, NULL);
317
318 self->priv->reference_identities = (GStrv) g_ptr_array_free (identities,
319 FALSE);
320
321 g_strfreev (extra_certificate_identities);
322 g_free (explicit_server);
323 g_free (connect_server);
324 }
325
326 static void
327 idle_server_tls_manager_verify_async (WockyTLSHandler *handler,
328 WockyTLSSession *tls_session,
329 const gchar *peername,
330 GStrv extra_identities,
331 GAsyncReadyCallback callback,
332 gpointer user_data)
333 {
334 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (handler);
335 IdleTLSCertificate *certificate;
336 GSimpleAsyncResult *result;
337
338 g_return_if_fail (self->priv->async_result == NULL);
339
340 DEBUG ("verify_async() called on the IdleServerTLSManager.");
341
342 result = g_simple_async_result_new (G_OBJECT (self),
343 callback, user_data, idle_server_tls_manager_verify_async);
344
345 if (self->priv->connection == NULL)
346 {
347 DEBUG ("connection already went away; failing immediately");
348 g_simple_async_result_set_error (result, TP_ERROR, TP_ERROR_CANCELLED,
349 "The Telepathy connection has already been disconnected");
350 g_simple_async_result_complete_in_idle (result);
351 g_object_unref (result);
352 return;
353 }
354
355 self->priv->async_result = result;
356
357 fill_reference_identities (self, peername, extra_identities);
358
359 if (!self->priv->interactive_tls)
360 {
361 DEBUG ("ignore-ssl-errors is set, fallback to non-interactive "
362 "verification.");
363
364 chainup->verify_async_func (WOCKY_TLS_HANDLER (self), tls_session,
365 peername, self->priv->reference_identities, verify_fallback_cb, NULL);
366
367 return;
368 }
369
370 self->priv->tls_session = g_object_ref (tls_session);
371 self->priv->peername = g_strdup (peername);
372
373 self->priv->channel = g_object_new (IDLE_TYPE_SERVER_TLS_CHANNEL,
374 "connection", self->priv->connection,
375 "tls-session", tls_session,
376 "hostname", peername,
377 "reference-identities", self->priv->reference_identities,
378 NULL);
379
380 g_signal_connect (self->priv->channel, "closed",
381 G_CALLBACK (server_tls_channel_closed_cb), self);
382
383 certificate = idle_server_tls_channel_get_certificate (self->priv->channel);
384
385 g_signal_connect (certificate, "accepted",
386 G_CALLBACK (tls_certificate_accepted_cb), self);
387 g_signal_connect (certificate, "rejected",
388 G_CALLBACK (tls_certificate_rejected_cb), self);
389
390 /* emit NewChannel on the ChannelManager iface */
391 tp_channel_manager_emit_new_channel (self,
392 (TpExportableChannel *) self->priv->channel, NULL);
393 }
394
395 static gboolean
396 idle_server_tls_manager_verify_finish (WockyTLSHandler *self,
397 GAsyncResult *result,
398 GError **error)
399 {
400 wocky_implement_finish_void (self, idle_server_tls_manager_verify_async);
401 }
402
403 static void
404 idle_server_tls_manager_init (IdleServerTLSManager *self)
405 {
406 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
407 IDLE_TYPE_SERVER_TLS_MANAGER, IdleServerTLSManagerPrivate);
408 }
409
410 static void
411 idle_server_tls_manager_dispose (GObject *object)
412 {
413 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object);
414
415 DEBUG ("%p", self);
416
417 if (self->priv->dispose_has_run)
418 return;
419
420 self->priv->dispose_has_run = TRUE;
421
422 tp_clear_object (&self->priv->tls_session);
423 tp_clear_object (&self->priv->connection);
424
425 G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->dispose (object);
426 }
427
428 static void
429 idle_server_tls_manager_finalize (GObject *object)
430 {
431 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object);
432
433 DEBUG ("%p", self);
434
435 close_all (self);
436
437 g_free (self->priv->peername);
438 g_strfreev (self->priv->reference_identities);
439
440 G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->finalize (object);
441 }
442
443 static void
444 idle_server_tls_manager_constructed (GObject *object)
445 {
446 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object);
447 void (*chain_up) (GObject *) =
448 G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->constructed;
449
450 if (chain_up != NULL)
451 chain_up (object);
452
453 DEBUG ("Server TLS Manager constructed");
454
455 idle_signal_connect_weak (self->priv->connection, "status-changed",
456 G_CALLBACK (connection_status_changed_cb), object);
457 }
458
459 static void
460 idle_server_tls_manager_class_init (IdleServerTLSManagerClass *klass)
461 {
462 GObjectClass *oclass = G_OBJECT_CLASS (klass);
463 WockyTLSHandlerClass *hclass = WOCKY_TLS_HANDLER_CLASS (klass);
464 GParamSpec *pspec;
465
466 g_type_class_add_private (klass, sizeof (IdleServerTLSManagerPrivate));
467
468 oclass->dispose = idle_server_tls_manager_dispose;
469 oclass->finalize = idle_server_tls_manager_finalize;
470 oclass->constructed = idle_server_tls_manager_constructed;
471 oclass->set_property = idle_server_tls_manager_set_property;
472 oclass->get_property = idle_server_tls_manager_get_property;
473
474 hclass->verify_async_func = idle_server_tls_manager_verify_async;
475 hclass->verify_finish_func = idle_server_tls_manager_verify_finish;
476
477 pspec = g_param_spec_object ("connection", "IdleConnection object",
478 "Idle connection object that owns this manager.",
479 IDLE_TYPE_CONNECTION,
480 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
481 g_object_class_install_property (oclass, PROP_CONNECTION, pspec);
482
483 pspec = g_param_spec_boolean ("interactive-tls", "Interactive TLS setting",
484 "Whether interactive TLS certificate verification is enabled.",
485 FALSE,
486 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
487 g_object_class_install_property (oclass, PROP_INTERACTIVE_TLS, pspec);
488 }
489
490 static void
491 idle_server_tls_manager_foreach_channel (TpChannelManager *manager,
492 TpExportableChannelFunc func,
493 gpointer user_data)
494 {
495 IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (manager);
496 GList *l;
497
498 if (self->priv->channel != NULL)
499 func (TP_EXPORTABLE_CHANNEL (self->priv->channel), user_data);
500
501 for (l = self->priv->completed_channels; l != NULL; l = l->next)
502 {
503 func (l->data, user_data);
504 }
505 }
506
507 static void
508 channel_manager_iface_init (gpointer g_iface,
509 gpointer iface_data)
510 {
511 TpChannelManagerIface *iface = g_iface;
512
513 iface->foreach_channel = idle_server_tls_manager_foreach_channel;
514
515 /* these channels are not requestable. */
516 iface->ensure_channel = NULL;
517 iface->create_channel = NULL;
518 iface->request_channel = NULL;
519 iface->foreach_channel_class = NULL;
520 }
521
522 static TpConnectionStatusReason
523 cert_reject_reason_to_conn_reason (TpTLSCertificateRejectReason tls_reason)
524 {
525 #define EASY_CASE(x) \
526 case TP_TLS_CERTIFICATE_REJECT_REASON_ ## x: \
527 return TP_CONNECTION_STATUS_REASON_CERT_ ## x;
528
529 switch (tls_reason)
530 {
531 EASY_CASE (UNTRUSTED);
532 EASY_CASE (EXPIRED);
533 EASY_CASE (NOT_ACTIVATED);
534 EASY_CASE (FINGERPRINT_MISMATCH);
535 EASY_CASE (HOSTNAME_MISMATCH);
536 EASY_CASE (SELF_SIGNED);
537 EASY_CASE (REVOKED);
538 EASY_CASE (INSECURE);
539 EASY_CASE (LIMIT_EXCEEDED);
540
541 case TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN:
542 default:
543 return TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR;
544 }
545
546 #undef EASY_CASE
547 }
548
549 void
550 idle_server_tls_manager_get_rejection_details (IdleServerTLSManager *self,
551 gchar **dbus_error,
552 GHashTable **details,
553 TpConnectionStatusReason *reason)
554 {
555 IdleTLSCertificate *certificate;
556 GPtrArray *rejections;
557 GValueArray *rejection;
558 TpTLSCertificateRejectReason tls_reason;
559
560 /* We probably want the rejection details of last completed operation */
561 g_return_if_fail (self->priv->completed_channels != NULL);
562
563 certificate = idle_server_tls_channel_get_certificate (
564 self->priv->completed_channels->data);
565 g_object_get (certificate,
566 "rejections", &rejections,
567 NULL);
568
569 /* we return 'Invalid_Argument' if Reject() is called with zero
570 * reasons, so if this fails something bad happened.
571 */
572 g_assert (rejections->len >= 1);
573
574 rejection = g_ptr_array_index (rejections, 0);
575
576 tls_reason = g_value_get_uint (g_value_array_get_nth (rejection, 0));
577 *dbus_error = g_value_dup_string (g_value_array_get_nth (rejection, 1));
578 *details = g_value_dup_boxed (g_value_array_get_nth (rejection, 2));
579
580 *reason = cert_reject_reason_to_conn_reason (tls_reason);
581
582 tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
583 &rejections);
584 }
0 /*
1 * server-tls-manager.h - Header for IdleServerTLSManager
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef __IDLE_SERVER_TLS_MANAGER_H__
21 #define __IDLE_SERVER_TLS_MANAGER_H__
22
23 #include <glib-object.h>
24 #include <wocky/wocky.h>
25 #include <telepathy-glib/telepathy-glib.h>
26
27 #include "extensions/extensions.h"
28
29 G_BEGIN_DECLS
30
31 typedef struct _IdleServerTLSManager IdleServerTLSManager;
32 typedef struct _IdleServerTLSManagerClass IdleServerTLSManagerClass;
33 typedef struct _IdleServerTLSManagerPrivate IdleServerTLSManagerPrivate;
34
35 struct _IdleServerTLSManagerClass {
36 WockyTLSHandlerClass parent_class;
37 };
38
39 struct _IdleServerTLSManager {
40 WockyTLSHandler parent;
41 IdleServerTLSManagerPrivate *priv;
42 };
43
44 GType idle_server_tls_manager_get_type (void);
45
46 #define IDLE_TYPE_SERVER_TLS_MANAGER \
47 (idle_server_tls_manager_get_type ())
48 #define IDLE_SERVER_TLS_MANAGER(obj) \
49 (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_SERVER_TLS_MANAGER, \
50 IdleServerTLSManager))
51 #define IDLE_SERVER_TLS_MANAGER_CLASS(klass) \
52 (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_SERVER_TLS_MANAGER, \
53 IdleServerTLSManagerClass))
54 #define IDLE_IS_SERVER_TLS_MANAGER(obj) \
55 (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_SERVER_TLS_MANAGER))
56 #define IDLE_IS_SERVER_TLS_MANAGER_CLASS(klass) \
57 (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_SERVER_TLS_MANAGER))
58 #define IDLE_SERVER_TLS_MANAGER_GET_CLASS(obj) \
59 (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_SERVER_TLS_MANAGER, \
60 IdleServerTLSManagerClass))
61
62 #define IDLE_SERVER_TLS_ERROR idle_server_tls_error_quark ()
63 GQuark idle_server_tls_error_quark (void);
64
65 void idle_server_tls_manager_get_rejection_details (
66 IdleServerTLSManager *self,
67 gchar **dbus_error,
68 GHashTable **details,
69 TpConnectionStatusReason *reason);
70
71 G_END_DECLS
72
73 #endif /* #ifndef __IDLE_SERVER_TLS_MANAGER_H__ */
0 /*
1 * tls-certificate.c - Source for IdleTLSCertificate
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "config.h"
21 #include "tls-certificate.h"
22
23 #include <telepathy-glib/telepathy-glib.h>
24 #include <telepathy-glib/telepathy-glib-dbus.h>
25
26 #define DEBUG_FLAG IDLE_DEBUG_TLS
27 #include "debug.h"
28
29 static void
30 tls_certificate_iface_init (gpointer g_iface, gpointer iface_data);
31
32 G_DEFINE_TYPE_WITH_CODE (IdleTLSCertificate,
33 idle_tls_certificate,
34 G_TYPE_OBJECT,
35 G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE,
36 tls_certificate_iface_init);
37 G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
38 tp_dbus_properties_mixin_iface_init);)
39
40 struct _IdleTLSCertificatePrivate {
41 gchar *object_path;
42
43 gchar *cert_type;
44 TpTLSCertificateState cert_state;
45
46 GPtrArray *rejections;
47 GPtrArray *cert_data;
48
49 TpDBusDaemon *daemon;
50
51 gboolean dispose_has_run;
52 };
53
54 enum {
55 PROP_OBJECT_PATH = 1,
56 PROP_STATE,
57 PROP_REJECTIONS,
58 PROP_CERTIFICATE_TYPE,
59 PROP_CERTIFICATE_CHAIN_DATA,
60
61 /* not exported */
62 PROP_DBUS_DAEMON,
63
64 NUM_PROPERTIES
65 };
66
67 static void
68 idle_tls_certificate_get_property (GObject *object,
69 guint property_id,
70 GValue *value,
71 GParamSpec *pspec)
72 {
73 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object);
74
75 switch (property_id)
76 {
77 case PROP_OBJECT_PATH:
78 g_value_set_string (value, self->priv->object_path);
79 break;
80 case PROP_STATE:
81 g_value_set_uint (value, self->priv->cert_state);
82 break;
83 case PROP_REJECTIONS:
84 g_value_set_boxed (value, self->priv->rejections);
85 break;
86 case PROP_CERTIFICATE_TYPE:
87 g_value_set_string (value, self->priv->cert_type);
88 break;
89 case PROP_CERTIFICATE_CHAIN_DATA:
90 g_value_set_boxed (value, self->priv->cert_data);
91 break;
92 default:
93 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
94 break;
95 }
96 }
97
98 static void
99 idle_tls_certificate_set_property (GObject *object,
100 guint property_id,
101 const GValue *value,
102 GParamSpec *pspec)
103 {
104 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object);
105
106 switch (property_id)
107 {
108 case PROP_OBJECT_PATH:
109 self->priv->object_path = g_value_dup_string (value);
110 break;
111 case PROP_CERTIFICATE_TYPE:
112 self->priv->cert_type = g_value_dup_string (value);
113 break;
114 case PROP_CERTIFICATE_CHAIN_DATA:
115 self->priv->cert_data = g_value_dup_boxed (value);
116 break;
117 case PROP_DBUS_DAEMON:
118 self->priv->daemon = g_value_dup_object (value);
119 break;
120 default:
121 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, value);
122 break;
123 }
124 }
125
126 static void
127 idle_tls_certificate_finalize (GObject *object)
128 {
129 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object);
130
131 tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
132 &self->priv->rejections);
133
134 g_free (self->priv->object_path);
135 g_free (self->priv->cert_type);
136 g_ptr_array_unref (self->priv->cert_data);
137
138 G_OBJECT_CLASS (idle_tls_certificate_parent_class)->finalize (object);
139 }
140
141 static void
142 idle_tls_certificate_dispose (GObject *object)
143 {
144 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object);
145
146 if (self->priv->dispose_has_run)
147 return;
148
149 self->priv->dispose_has_run = TRUE;
150
151 tp_clear_object (&self->priv->daemon);
152
153 G_OBJECT_CLASS (idle_tls_certificate_parent_class)->dispose (object);
154 }
155
156 static void
157 idle_tls_certificate_constructed (GObject *object)
158 {
159 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object);
160 void (*chain_up) (GObject *) =
161 G_OBJECT_CLASS (idle_tls_certificate_parent_class)->constructed;
162
163 if (chain_up != NULL)
164 chain_up (object);
165
166 /* register the certificate on the bus */
167 tp_dbus_daemon_register_object (self->priv->daemon,
168 self->priv->object_path, self);
169 }
170
171 static void
172 idle_tls_certificate_init (IdleTLSCertificate *self)
173 {
174 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
175 IDLE_TYPE_TLS_CERTIFICATE, IdleTLSCertificatePrivate);
176 self->priv->rejections = g_ptr_array_new ();
177 }
178
179 static void
180 idle_tls_certificate_class_init (IdleTLSCertificateClass *klass)
181 {
182 static TpDBusPropertiesMixinPropImpl object_props[] = {
183 { "State", "state", NULL },
184 { "Rejections", "rejections", NULL },
185 { "CertificateType", "certificate-type", NULL },
186 { "CertificateChainData", "certificate-chain-data", NULL },
187 { NULL }
188 };
189 static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
190 { TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE,
191 tp_dbus_properties_mixin_getter_gobject_properties,
192 NULL,
193 object_props,
194 },
195 { NULL }
196 };
197 GObjectClass *oclass = G_OBJECT_CLASS (klass);
198 GParamSpec *pspec;
199
200 g_type_class_add_private (klass, sizeof (IdleTLSCertificatePrivate));
201
202 oclass->finalize = idle_tls_certificate_finalize;
203 oclass->dispose = idle_tls_certificate_dispose;
204 oclass->set_property = idle_tls_certificate_set_property;
205 oclass->get_property = idle_tls_certificate_get_property;
206 oclass->constructed = idle_tls_certificate_constructed;
207
208 pspec = g_param_spec_string ("object-path",
209 "D-Bus object path",
210 "The D-Bus object path used for this object on the bus.",
211 NULL,
212 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
213 g_object_class_install_property (oclass, PROP_OBJECT_PATH, pspec);
214
215 pspec = g_param_spec_uint ("state",
216 "State of this certificate",
217 "The state of this TLS certificate.",
218 0, NUM_TP_TLS_CERTIFICATE_STATES - 1,
219 TP_TLS_CERTIFICATE_STATE_PENDING,
220 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
221 g_object_class_install_property (oclass, PROP_STATE, pspec);
222
223 pspec = g_param_spec_boxed ("rejections",
224 "The reject reasons",
225 "The reasons why this TLS certificate has been rejected",
226 TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
227 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
228 g_object_class_install_property (oclass, PROP_REJECTIONS, pspec);
229
230 pspec = g_param_spec_string ("certificate-type",
231 "The certificate type",
232 "The type of this certificate.",
233 NULL,
234 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
235 g_object_class_install_property (oclass, PROP_CERTIFICATE_TYPE, pspec);
236
237 pspec = g_param_spec_boxed ("certificate-chain-data",
238 "The certificate chain data",
239 "The raw PEM-encoded trust chain of this certificate.",
240 TP_ARRAY_TYPE_UCHAR_ARRAY_LIST,
241 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
242 g_object_class_install_property (oclass, PROP_CERTIFICATE_CHAIN_DATA, pspec);
243
244 pspec = g_param_spec_object ("dbus-daemon",
245 "The DBus daemon connection",
246 "The connection to the DBus daemon owning the CM",
247 TP_TYPE_DBUS_DAEMON,
248 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
249 g_object_class_install_property (oclass, PROP_DBUS_DAEMON, pspec);
250
251 klass->dbus_props_class.interfaces = prop_interfaces;
252 tp_dbus_properties_mixin_class_init (oclass,
253 G_STRUCT_OFFSET (IdleTLSCertificateClass, dbus_props_class));
254 }
255
256 static void
257 idle_tls_certificate_accept (TpSvcAuthenticationTLSCertificate *cert,
258 DBusGMethodInvocation *context)
259 {
260 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (cert);
261
262 DEBUG ("Accept() called on the TLS certificate; current state %u",
263 self->priv->cert_state);
264
265 if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING)
266 {
267 GError error =
268 { TP_ERROR,
269 TP_ERROR_INVALID_ARGUMENT,
270 "Calling Accept() on a certificate with state != PENDING "
271 "doesn't make sense."
272 };
273
274 dbus_g_method_return_error (context, &error);
275 return;
276 }
277
278 self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_ACCEPTED;
279 tp_svc_authentication_tls_certificate_emit_accepted (self);
280
281 tp_svc_authentication_tls_certificate_return_from_accept (context);
282 }
283
284 static void
285 idle_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *cert,
286 const GPtrArray *rejections,
287 DBusGMethodInvocation *context)
288 {
289 IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (cert);
290
291 DEBUG ("Reject() called on the TLS certificate with rejections %p, "
292 "length %u; current state %u", rejections, rejections->len,
293 self->priv->cert_state);
294
295 if (rejections->len < 1)
296 {
297 GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
298 "Calling Reject() with a zero-length rejection list." };
299
300 dbus_g_method_return_error (context, &error);
301 return;
302 }
303
304 if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING)
305 {
306 GError error =
307 { TP_ERROR,
308 TP_ERROR_INVALID_ARGUMENT,
309 "Calling Reject() on a certificate with state != PENDING "
310 "doesn't make sense."
311 };
312
313 dbus_g_method_return_error (context, &error);
314 return;
315 }
316
317 tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
318 &self->priv->rejections);
319
320 self->priv->rejections =
321 g_boxed_copy (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
322 rejections);
323 self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_REJECTED;
324
325 tp_svc_authentication_tls_certificate_emit_rejected (
326 self, self->priv->rejections);
327
328 tp_svc_authentication_tls_certificate_return_from_reject (context);
329 }
330
331 static void
332 tls_certificate_iface_init (gpointer g_iface,
333 gpointer iface_data)
334 {
335 TpSvcAuthenticationTLSCertificateClass *klass = g_iface;
336
337 #define IMPLEMENT(x) \
338 tp_svc_authentication_tls_certificate_implement_##x ( \
339 klass, idle_tls_certificate_##x)
340 IMPLEMENT (accept);
341 IMPLEMENT (reject);
342 #undef IMPLEMENT
343 }
0 /*
1 * tls-certificate.h - Header for IdleTLSCertificate
2 * Copyright (C) 2010 Collabora Ltd.
3 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #ifndef __IDLE_TLS_CERTIFICATE_H__
21 #define __IDLE_TLS_CERTIFICATE_H__
22
23 #include <glib-object.h>
24
25 #include <telepathy-glib/telepathy-glib.h>
26
27 G_BEGIN_DECLS
28
29 typedef struct _IdleTLSCertificate IdleTLSCertificate;
30 typedef struct _IdleTLSCertificateClass IdleTLSCertificateClass;
31 typedef struct _IdleTLSCertificatePrivate IdleTLSCertificatePrivate;
32
33 struct _IdleTLSCertificateClass {
34 GObjectClass parent_class;
35
36 TpDBusPropertiesMixinClass dbus_props_class;
37 };
38
39 struct _IdleTLSCertificate {
40 GObject parent;
41
42 IdleTLSCertificatePrivate *priv;
43 };
44
45 GType idle_tls_certificate_get_type (void);
46
47 #define IDLE_TYPE_TLS_CERTIFICATE \
48 (idle_tls_certificate_get_type ())
49 #define IDLE_TLS_CERTIFICATE(obj) \
50 (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_TLS_CERTIFICATE, \
51 IdleTLSCertificate))
52 #define IDLE_TLS_CERTIFICATE_CLASS(klass) \
53 (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_TLS_CERTIFICATE, \
54 IdleTLSCertificateClass))
55 #define IDLE_IS_TLS_CERTIFICATE(obj) \
56 (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_TLS_CERTIFICATE))
57 #define IDLE_IS_TLS_CERTIFICATE_CLASS(klass) \
58 (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_TLS_CERTIFICATE))
59 #define IDLE_TLS_CERTIFICATE_GET_CLASS(obj) \
60 (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_TLS_CERTIFICATE, \
61 IdleTLSCertificateClass))
62
63 G_END_DECLS
64
65 #endif /* #ifndef __IDLE_TLS_CERTIFICATE_H__*/