2 * @file telepathy-tls.c
6 * Copyright (C) 2013 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * TLS certificate accept/reject user interaction
25 #include <glib-object.h>
26 #include <telepathy-glib/svc-channel.h>
27 #include <telepathy-glib/telepathy-glib.h>
29 #include "sipe-backend.h"
30 #include "sipe-common.h"
32 #include "telepathy-private.h"
34 /* TLS information required for user interaction */
35 struct sipe_tls_info
{
37 gchar
*server_cert_path
;
38 GStrv reference_identities
;
43 * TLS Manager class - data structures
45 typedef struct _SipeTLSManagerClass
{
46 GObjectClass parent_class
;
47 } SipeTLSManagerClass
;
49 typedef struct _SipeTLSManager
{
58 * TLS Manager class - type macros
60 static GType
sipe_tls_manager_get_type(void);
61 #define SIPE_TYPE_TLS_MANAGER \
62 (sipe_tls_manager_get_type())
63 #define SIPE_TLS_MANAGER(obj) \
64 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_MANAGER, \
68 * TLS Channel class - data structures
70 typedef struct _SipeTLSChannelClass
{
71 TpBaseChannelClass parent_class
;
72 } SipeTLSChannelClass
;
74 typedef struct _SipeTLSChannel
{
77 const struct sipe_tls_info
*tls_info
;
79 GSimpleAsyncResult
*result
;
83 * TLS Channel class - type macros
85 static GType
sipe_tls_channel_get_type(void) G_GNUC_CONST
;
86 #define SIPE_TYPE_TLS_CHANNEL \
87 (sipe_tls_channel_get_type())
88 #define SIPE_TLS_CHANNEL(obj) \
89 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_CHANNEL, \
94 * TLS Manager class - type definition
96 static void channel_manager_iface_init(gpointer
, gpointer
);
97 G_DEFINE_TYPE_WITH_CODE(SipeTLSManager
,
100 G_IMPLEMENT_INTERFACE(TP_TYPE_CHANNEL_MANAGER
,
101 channel_manager_iface_init
);
105 * TLS Channel class - type definition
107 G_DEFINE_TYPE_WITH_CODE(SipeTLSChannel
,
109 TP_TYPE_BASE_CHANNEL
,
110 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
115 * TLS Manager class - instance methods
117 static void sipe_tls_manager_constructed(GObject
*object
)
119 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
120 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
125 self
->channels
= NULL
;
128 static void sipe_tls_manager_dispose(GObject
*object
)
130 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
131 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
133 tp_clear_object(&self
->connection
);
139 static void sipe_tls_manager_finalize(GObject
*object
)
141 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
142 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
143 GSList
*entry
= self
->channels
;
147 GSList
*next
= entry
->next
;
148 /* removes entry from list */
149 tp_base_channel_close(entry
->data
);
153 tp_clear_object(&self
->connection
);
161 * TLS Manager class - type implementation
163 static void sipe_tls_manager_class_init(SipeTLSManagerClass
*klass
)
165 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
167 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::class_init");
169 object_class
->constructed
= sipe_tls_manager_constructed
;
170 object_class
->dispose
= sipe_tls_manager_dispose
;
171 object_class
->finalize
= sipe_tls_manager_finalize
;
174 static void sipe_tls_manager_init(SIPE_UNUSED_PARAMETER SipeTLSManager
*self
)
176 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::init");
180 * TLS Manager class - interface implementation
184 static void foreach_channel(TpChannelManager
*manager
,
185 TpExportableChannelFunc func
,
188 SipeTLSManager
*self
= SIPE_TLS_MANAGER(manager
);
190 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::foreach_channel");
198 static void channel_manager_iface_init(gpointer g_iface
,
199 SIPE_UNUSED_PARAMETER gpointer iface_data
)
201 TpChannelManagerIface
*iface
= g_iface
;
203 #define IMPLEMENT(x, y) iface->x = y
204 IMPLEMENT(foreach_channel
, foreach_channel
);
205 /* These channels are not requestable. */
206 IMPLEMENT(type_foreach_channel_class
, NULL
);
207 IMPLEMENT(create_channel
, NULL
);
208 IMPLEMENT(request_channel
, NULL
);
209 IMPLEMENT(ensure_channel
, NULL
);
213 /* create new TLS manager object */
214 SipeTLSManager
*sipe_telepathy_tls_new(TpBaseConnection
*connection
)
216 SipeTLSManager
*self
= g_object_new(SIPE_TYPE_TLS_MANAGER
, NULL
);
217 self
->connection
= g_object_ref(connection
);
221 static void channel_closed_cb(SipeTLSChannel
*channel
,
222 SipeTLSManager
*self
)
224 self
->channels
= g_slist_remove(self
->channels
, channel
);
225 tp_channel_manager_emit_channel_closed_for_object(self
,
226 TP_EXPORTABLE_CHANNEL(channel
));
227 g_object_unref(channel
);
230 static void manager_new_channel(SipeTLSManager
*self
,
231 SipeTLSChannel
*channel
)
233 self
->channels
= g_slist_prepend(self
->channels
,
234 g_object_ref(channel
));
236 g_signal_connect(channel
,
238 G_CALLBACK(channel_closed_cb
),
241 /* emit NewChannel on the ChannelManager iface */
242 tp_channel_manager_emit_new_channel(self
,
243 TP_EXPORTABLE_CHANNEL(channel
),
249 * TLS Channel class - instance methods
252 CHANNEL_PROP_SERVER_CERTIFICATE
= 1,
253 CHANNEL_PROP_HOSTNAME
,
254 CHANNEL_PROP_REFERENCE_IDENTITIES
,
258 static void get_property(GObject
*object
,
263 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
265 switch (property_id
) {
266 case CHANNEL_PROP_SERVER_CERTIFICATE
:
267 g_value_set_boxed(value
, self
->tls_info
->server_cert_path
);
269 case CHANNEL_PROP_HOSTNAME
:
270 g_value_set_string(value
, self
->tls_info
->hostname
);
272 case CHANNEL_PROP_REFERENCE_IDENTITIES
:
273 g_value_set_boxed(value
, self
->tls_info
->reference_identities
);
276 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, property_id
, pspec
);
281 static void fill_immutable_properties(TpBaseChannel
*channel
,
282 GHashTable
*properties
)
284 TP_BASE_CHANNEL_CLASS(sipe_tls_channel_parent_class
)->fill_immutable_properties(channel
,
286 tp_dbus_properties_mixin_fill_properties_hash(G_OBJECT(channel
),
288 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ServerCertificate",
289 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "Hostname",
290 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ReferenceIdentities",
294 static gchar
*get_object_path_suffix(TpBaseChannel
*base
)
296 return(g_strdup_printf("TLSChannel_%p", base
));
299 static void sipe_tls_channel_constructed(GObject
*object
)
301 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
302 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->constructed
;
311 static void sipe_tls_channel_finalize(GObject
*object
)
313 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
315 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::finalize");
317 g_simple_async_result_complete(self
->result
);
318 g_clear_object(&self
->result
);
320 G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->finalize(object
);
324 * TLS Channel class - type implementation
326 static void sipe_tls_channel_class_init(SipeTLSChannelClass
*klass
)
328 static TpDBusPropertiesMixinPropImpl props
[] = {
330 .name
= "ServerCertificate",
331 .getter_data
= "server-certificate",
336 .getter_data
= "hostname",
340 .name
= "ReferenceIdentities",
341 .getter_data
= "reference-identities",
348 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
349 TpBaseChannelClass
*base_class
= TP_BASE_CHANNEL_CLASS(klass
);
352 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::class_init");
354 object_class
->constructed
= sipe_tls_channel_constructed
;
355 object_class
->finalize
= sipe_tls_channel_finalize
;
356 object_class
->get_property
= get_property
;
358 base_class
->channel_type
= TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
;
359 base_class
->target_handle_type
= TP_HANDLE_TYPE_NONE
;
360 base_class
->fill_immutable_properties
= fill_immutable_properties
;
361 base_class
->get_object_path_suffix
= get_object_path_suffix
;
362 base_class
->interfaces
= NULL
;
363 base_class
->close
= tp_base_channel_destroyed
;
365 ps
= g_param_spec_boxed("server-certificate",
366 "Server certificate path",
367 "The object path of the server certificate.",
368 DBUS_TYPE_G_OBJECT_PATH
,
369 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
370 g_object_class_install_property(object_class
,
371 CHANNEL_PROP_SERVER_CERTIFICATE
,
374 ps
= g_param_spec_string("hostname",
375 "The hostname to be verified",
376 "The hostname which should be certified by the server certificate.",
378 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
379 g_object_class_install_property(object_class
,
380 CHANNEL_PROP_HOSTNAME
,
383 ps
= g_param_spec_boxed("reference-identities",
384 "The various identities to check the certificate against",
385 "The server certificate identity should match one of these identities.",
387 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
388 g_object_class_install_property(object_class
,
389 CHANNEL_PROP_REFERENCE_IDENTITIES
,
392 tp_dbus_properties_mixin_implement_interface(object_class
,
393 TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
394 tp_dbus_properties_mixin_getter_gobject_properties
,
399 static void sipe_tls_channel_init(SIPE_UNUSED_PARAMETER SipeTLSChannel
*self
)
401 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::init");
404 struct sipe_tls_info
*sipe_telepathy_tls_info_new(const gchar
*hostname
,
405 SIPE_UNUSED_PARAMETER
struct _GTlsCertificate
*certificate
)
407 struct sipe_tls_info
*tls_info
= g_new0(struct sipe_tls_info
, 1);
409 tls_info
->hostname
= g_strdup(hostname
);
413 * tls_info->reference_identities = g_boxed_copy(G_TYPE_STRV, reference_identities);??
414 * tls_info->tls_info->server_cert_path
420 void sipe_telepathy_tls_info_free(struct sipe_tls_info
*tls_info
)
422 g_free(tls_info
->hostname
);
423 g_free(tls_info
->server_cert_path
);
424 g_strfreev(tls_info
->reference_identities
);
428 /* create new tls channel object */
429 void sipe_telepathy_tls_verify_async(GObject
*connection
,
430 struct sipe_tls_info
*tls_info
,
431 GAsyncReadyCallback callback
,
434 struct sipe_backend_private
*telepathy_private
= sipe_telepathy_connection_private(connection
);
436 /* property "connection" required by TpBaseChannel */
437 SipeTLSChannel
*self
= g_object_new(SIPE_TYPE_TLS_CHANNEL
,
438 "connection", connection
,
441 self
->tls_info
= tls_info
;
442 self
->result
= g_simple_async_result_new(G_OBJECT(self
),
445 sipe_telepathy_tls_verify_async
);
447 tp_base_channel_register(TP_BASE_CHANNEL(self
));
449 manager_new_channel(telepathy_private
->tls_manager
, self
);