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
27 #include <glib-object.h>
28 #include <telepathy-glib/dbus-properties-mixin.h>
29 #include <telepathy-glib/svc-channel.h>
30 #include <telepathy-glib/svc-tls.h>
31 #include <telepathy-glib/telepathy-glib.h>
33 #include "sipe-backend.h"
34 #include "sipe-common.h"
36 #include "telepathy-private.h"
38 /* TLS information required for user interaction */
39 struct _SipeTLSCertificate
;
40 struct sipe_tls_info
{
44 GStrv reference_identities
;
45 struct _SipeTLSCertificate
*certificate
;
48 /* Certificate states */
49 #define SIPE_TLS_CERTIFICATE_PENDING 0
50 #define SIPE_TLS_CERTIFICATE_REJECTED 1
51 #define SIPE_TLS_CERTIFICATE_ACCEPTED 2
55 * TLS Manager class - data structures
57 typedef struct _SipeTLSManagerClass
{
58 GObjectClass parent_class
;
59 } SipeTLSManagerClass
;
61 typedef struct _SipeTLSManager
{
70 * TLS Manager class - type macros
72 static GType
sipe_tls_manager_get_type(void);
73 #define SIPE_TYPE_TLS_MANAGER \
74 (sipe_tls_manager_get_type())
75 #define SIPE_TLS_MANAGER(obj) \
76 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_MANAGER, \
80 * TLS Channel class - data structures
82 typedef struct _SipeTLSChannelClass
{
83 TpBaseChannelClass parent_class
;
84 } SipeTLSChannelClass
;
86 typedef struct _SipeTLSChannel
{
89 const struct sipe_tls_info
*tls_info
;
91 GSimpleAsyncResult
*result
;
95 * TLS Channel class - type macros
97 static GType
sipe_tls_channel_get_type(void) G_GNUC_CONST
;
98 #define SIPE_TYPE_TLS_CHANNEL \
99 (sipe_tls_channel_get_type())
100 #define SIPE_TLS_CHANNEL(obj) \
101 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_CHANNEL, \
105 * TLS Certificate class - data structures
107 typedef struct _SipeTLSCertificateClass
{
108 GObjectClass parent_class
;
110 TpDBusPropertiesMixinClass dbus_props_class
;
111 } SipeTLSCertificateClass
;
113 typedef struct _SipeTLSCertificate
{
116 const struct sipe_tls_info
*tls_info
;
119 } SipeTLSCertificate
;
122 * TLS Certificate class - type macros
124 static GType
sipe_tls_certificate_get_type(void) G_GNUC_CONST
;
125 #define SIPE_TYPE_TLS_CERTIFICATE \
126 (sipe_tls_certificate_get_type())
127 #define SIPE_TLS_CERTIFICATE(obj) \
128 (G_TYPE_CHECK_INSTANCE_CAST((obj), SIPE_TYPE_TLS_CERTIFICATE, \
133 * TLS Manager class - type definition
135 static void channel_manager_iface_init(gpointer
, gpointer
);
136 G_DEFINE_TYPE_WITH_CODE(SipeTLSManager
,
139 G_IMPLEMENT_INTERFACE(TP_TYPE_CHANNEL_MANAGER
,
140 channel_manager_iface_init
);
144 * TLS Channel class - type definition
146 G_DEFINE_TYPE_WITH_CODE(SipeTLSChannel
,
148 TP_TYPE_BASE_CHANNEL
,
149 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
154 * TLS Certificate class - type definition
156 static void tls_certificate_iface_init(gpointer
, gpointer
);
157 G_DEFINE_TYPE_WITH_CODE (SipeTLSCertificate
,
158 sipe_tls_certificate
,
160 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE
,
161 tls_certificate_iface_init
);
162 G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_DBUS_PROPERTIES
,
163 tp_dbus_properties_mixin_iface_init
);
167 * TLS Manager class - instance methods
169 static void sipe_tls_manager_constructed(GObject
*object
)
171 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
172 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
177 self
->channels
= NULL
;
180 static void sipe_tls_manager_dispose(GObject
*object
)
182 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
183 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
185 tp_clear_object(&self
->connection
);
191 static void sipe_tls_manager_finalize(GObject
*object
)
193 SipeTLSManager
*self
= SIPE_TLS_MANAGER(object
);
194 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_manager_parent_class
)->constructed
;
195 GSList
*entry
= self
->channels
;
199 GSList
*next
= entry
->next
;
200 /* removes entry from list */
201 tp_base_channel_close(entry
->data
);
205 tp_clear_object(&self
->connection
);
213 * TLS Manager class - type implementation
215 static void sipe_tls_manager_class_init(SipeTLSManagerClass
*klass
)
217 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
219 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::class_init");
221 object_class
->constructed
= sipe_tls_manager_constructed
;
222 object_class
->dispose
= sipe_tls_manager_dispose
;
223 object_class
->finalize
= sipe_tls_manager_finalize
;
226 static void sipe_tls_manager_init(SIPE_UNUSED_PARAMETER SipeTLSManager
*self
)
228 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::init");
232 * TLS Manager class - interface implementation
236 static void foreach_channel(TpChannelManager
*manager
,
237 TpExportableChannelFunc func
,
240 SipeTLSManager
*self
= SIPE_TLS_MANAGER(manager
);
243 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSManager::foreach_channel");
245 for (entry
= self
->channels
; entry
; entry
= entry
->next
)
246 func(entry
->data
, user_data
);
249 static void channel_manager_iface_init(gpointer g_iface
,
250 SIPE_UNUSED_PARAMETER gpointer iface_data
)
252 TpChannelManagerIface
*iface
= g_iface
;
254 #define IMPLEMENT(x, y) iface->x = y
255 IMPLEMENT(foreach_channel
, foreach_channel
);
256 /* These channels are not requestable. */
257 IMPLEMENT(type_foreach_channel_class
, NULL
);
258 IMPLEMENT(create_channel
, NULL
);
259 IMPLEMENT(request_channel
, NULL
);
260 IMPLEMENT(ensure_channel
, NULL
);
264 /* create new TLS manager object */
265 SipeTLSManager
*sipe_telepathy_tls_new(TpBaseConnection
*connection
)
267 SipeTLSManager
*self
= g_object_new(SIPE_TYPE_TLS_MANAGER
, NULL
);
268 self
->connection
= g_object_ref(connection
);
272 static void channel_closed_cb(SipeTLSChannel
*channel
,
273 SipeTLSManager
*self
)
275 SIPE_DEBUG_INFO("channel_closed_cb: %p", channel
);
277 self
->channels
= g_slist_remove(self
->channels
, channel
);
278 tp_channel_manager_emit_channel_closed_for_object(self
,
279 TP_EXPORTABLE_CHANNEL(channel
));
280 g_object_unref(channel
);
283 static void manager_new_channel(SipeTLSManager
*self
,
284 SipeTLSChannel
*channel
)
286 self
->channels
= g_slist_prepend(self
->channels
,
287 g_object_ref(channel
));
289 g_signal_connect(channel
,
291 G_CALLBACK(channel_closed_cb
),
294 /* emit NewChannel on the ChannelManager iface */
295 tp_channel_manager_emit_new_channel(self
,
296 TP_EXPORTABLE_CHANNEL(channel
),
301 * TLS Channel class - instance methods
304 CHANNEL_PROP_SERVER_CERTIFICATE
= 1,
305 CHANNEL_PROP_HOSTNAME
,
306 CHANNEL_PROP_REFERENCE_IDENTITIES
,
310 static void channel_get_property(GObject
*object
,
315 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
317 switch (property_id
) {
318 case CHANNEL_PROP_SERVER_CERTIFICATE
:
319 g_value_set_boxed(value
, self
->tls_info
->cert_path
);
321 case CHANNEL_PROP_HOSTNAME
:
322 g_value_set_string(value
, self
->tls_info
->hostname
);
324 case CHANNEL_PROP_REFERENCE_IDENTITIES
:
325 g_value_set_boxed(value
, self
->tls_info
->reference_identities
);
328 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, property_id
, pspec
);
333 static void channel_fill_immutable_properties(TpBaseChannel
*channel
,
334 GHashTable
*properties
)
336 TP_BASE_CHANNEL_CLASS(sipe_tls_channel_parent_class
)->fill_immutable_properties(channel
,
338 tp_dbus_properties_mixin_fill_properties_hash(G_OBJECT(channel
),
340 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ServerCertificate",
341 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "Hostname",
342 TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
, "ReferenceIdentities",
346 static gchar
*channel_get_object_path_suffix(TpBaseChannel
*base
)
348 return(g_strdup_printf("TLSChannel_%p", base
));
351 static void sipe_tls_channel_constructed(GObject
*object
)
353 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->constructed
;
359 static void sipe_tls_channel_finalize(GObject
*object
)
361 SipeTLSChannel
*self
= SIPE_TLS_CHANNEL(object
);
363 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::finalize");
366 g_simple_async_result_set_error(self
->result
,
369 "The TLS channel is being destroyed");
370 g_simple_async_result_complete_in_idle(self
->result
);
371 g_clear_object(&self
->result
);
374 G_OBJECT_CLASS(sipe_tls_channel_parent_class
)->finalize(object
);
378 * TLS Channel class - type implementation
380 static void sipe_tls_channel_class_init(SipeTLSChannelClass
*klass
)
382 static TpDBusPropertiesMixinPropImpl props
[] = {
384 .name
= "ServerCertificate",
385 .getter_data
= "server-certificate",
390 .getter_data
= "hostname",
394 .name
= "ReferenceIdentities",
395 .getter_data
= "reference-identities",
402 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
403 TpBaseChannelClass
*base_class
= TP_BASE_CHANNEL_CLASS(klass
);
406 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::class_init");
408 object_class
->constructed
= sipe_tls_channel_constructed
;
409 object_class
->finalize
= sipe_tls_channel_finalize
;
410 object_class
->get_property
= channel_get_property
;
412 base_class
->channel_type
= TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION
;
413 base_class
->target_handle_type
= TP_HANDLE_TYPE_NONE
;
414 base_class
->fill_immutable_properties
= channel_fill_immutable_properties
;
415 base_class
->get_object_path_suffix
= channel_get_object_path_suffix
;
416 base_class
->interfaces
= NULL
;
417 base_class
->close
= tp_base_channel_destroyed
;
419 ps
= g_param_spec_boxed("server-certificate",
420 "Server certificate path",
421 "The object path of the server certificate.",
422 DBUS_TYPE_G_OBJECT_PATH
,
423 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
424 g_object_class_install_property(object_class
,
425 CHANNEL_PROP_SERVER_CERTIFICATE
,
428 ps
= g_param_spec_string("hostname",
429 "The hostname to be verified",
430 "The hostname which should be certified by the server certificate.",
432 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
433 g_object_class_install_property(object_class
,
434 CHANNEL_PROP_HOSTNAME
,
437 ps
= g_param_spec_boxed("reference-identities",
438 "The various identities to check the certificate against",
439 "The server certificate identity should match one of these identities.",
441 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
442 g_object_class_install_property(object_class
,
443 CHANNEL_PROP_REFERENCE_IDENTITIES
,
446 tp_dbus_properties_mixin_implement_interface(object_class
,
447 TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION
,
448 tp_dbus_properties_mixin_getter_gobject_properties
,
453 static void sipe_tls_channel_init(SIPE_UNUSED_PARAMETER SipeTLSChannel
*self
)
455 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSChannel::init");
458 static void certificate_accepted_cb(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*certificate
,
459 SipeTLSChannel
*self
)
461 g_simple_async_result_complete(self
->result
);
462 g_clear_object(&self
->result
);
463 tp_base_channel_close(TP_BASE_CHANNEL(self
));
466 static void certificate_rejected_cb(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*certificate
,
467 SIPE_UNUSED_PARAMETER GPtrArray
*rejections
,
468 SipeTLSChannel
*self
)
470 static GQuark quark
= 0;
473 quark
= g_quark_from_static_string("server-tls-error");
475 g_simple_async_result_set_error(self
->result
,
478 "TLS certificate rejected");
479 g_simple_async_result_complete(self
->result
);
480 g_clear_object(&self
->result
);
481 tp_base_channel_close(TP_BASE_CHANNEL(self
));
484 static void channel_new_certificate(GObject
*connection
,
485 struct sipe_tls_info
*tls_info
,
486 SipeTLSChannel
*self
,
487 GAsyncReadyCallback callback
,
490 struct sipe_backend_private
*telepathy_private
= sipe_telepathy_connection_private(connection
);
492 self
->tls_info
= tls_info
;
493 self
->result
= g_simple_async_result_new(G_OBJECT(self
),
496 channel_new_certificate
);
498 g_signal_connect(tls_info
->certificate
,
500 G_CALLBACK(certificate_accepted_cb
),
503 g_signal_connect(tls_info
->certificate
,
505 G_CALLBACK(certificate_rejected_cb
),
508 manager_new_channel(telepathy_private
->tls_manager
, self
);
514 * TLS Certificate class - instance methods
517 CERTIFICATE_PROP_OBJECT_PATH
= 1,
518 CERTIFICATE_PROP_STATE
,
519 CERTIFICATE_PROP_TYPE
,
520 CERTIFICATE_PROP_CHAIN_DATA
,
521 CERTIFICATE_LAST_PROP
524 static void certificate_get_property(GObject
*object
,
529 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(object
);
531 switch (property_id
) {
532 case CERTIFICATE_PROP_OBJECT_PATH
:
533 g_value_set_string(value
, self
->tls_info
->cert_path
);
535 case CERTIFICATE_PROP_STATE
:
536 g_value_set_uint(value
, self
->state
);
538 case CERTIFICATE_PROP_TYPE
:
539 g_value_set_string(value
, "x509");
541 case CERTIFICATE_PROP_CHAIN_DATA
:
542 g_value_set_boxed(value
, self
->tls_info
->cert_data
);
545 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, property_id
, pspec
);
550 static void sipe_tls_certificate_constructed(GObject
*object
)
552 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(object
);
553 void (*chain_up
)(GObject
*) = G_OBJECT_CLASS(sipe_tls_certificate_parent_class
)->constructed
;
558 self
->state
= SIPE_TLS_CERTIFICATE_PENDING
;
561 static void sipe_tls_certificate_finalize(GObject
*object
)
563 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::finalize");
565 G_OBJECT_CLASS(sipe_tls_certificate_parent_class
)->finalize(object
);
569 * TLS Certificate class - type implementation
571 static void sipe_tls_certificate_class_init(SipeTLSCertificateClass
*klass
)
573 static TpDBusPropertiesMixinPropImpl props
[] = {
576 .getter_data
= "state",
580 .name
= "CertificateType",
581 .getter_data
= "certificate-type",
585 .name
= "CertificateChainData",
586 .getter_data
= "certificate-chain-data",
593 static TpDBusPropertiesMixinIfaceImpl prop_interfaces
[] = {
595 .name
= TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE
,
596 .getter
= tp_dbus_properties_mixin_getter_gobject_properties
,
604 GObjectClass
*object_class
= G_OBJECT_CLASS(klass
);
607 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::class_init");
609 klass
->dbus_props_class
.interfaces
= prop_interfaces
;
611 object_class
->constructed
= sipe_tls_certificate_constructed
;
612 object_class
->finalize
= sipe_tls_certificate_finalize
;
613 object_class
->get_property
= certificate_get_property
;
615 ps
= g_param_spec_string("object-path",
617 "The D-Bus object path used for this object on the bus.",
619 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
620 g_object_class_install_property(object_class
,
621 CERTIFICATE_PROP_OBJECT_PATH
,
624 ps
= g_param_spec_uint("state",
625 "State of this certificate",
626 "The state of this TLS certificate.",
627 SIPE_TLS_CERTIFICATE_PENDING
,
628 SIPE_TLS_CERTIFICATE_ACCEPTED
,
629 SIPE_TLS_CERTIFICATE_PENDING
,
630 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
631 g_object_class_install_property(object_class
,
632 CERTIFICATE_PROP_STATE
,
635 ps
= g_param_spec_string("certificate-type",
636 "The certificate type",
637 "The type of this certificate.",
639 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
640 g_object_class_install_property(object_class
,
641 CERTIFICATE_PROP_TYPE
,
644 ps
= g_param_spec_boxed("certificate-chain-data",
645 "The certificate chain data",
646 "The raw DER-encoded trust chain of this certificate.",
647 TP_ARRAY_TYPE_UCHAR_ARRAY_LIST
,
648 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
649 g_object_class_install_property(object_class
,
650 CERTIFICATE_PROP_CHAIN_DATA
, ps
);
652 tp_dbus_properties_mixin_class_init(object_class
,
653 G_STRUCT_OFFSET(SipeTLSCertificateClass
, dbus_props_class
));
656 static void sipe_tls_certificate_init(SIPE_UNUSED_PARAMETER SipeTLSCertificate
*self
)
658 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::init");
662 * TLS Certificate class - interface implementation
664 static void tls_certificate_accept(TpSvcAuthenticationTLSCertificate
*certificate
,
665 DBusGMethodInvocation
*context
)
667 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(certificate
);
669 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::accept");
671 if (self
->state
!= SIPE_TLS_CERTIFICATE_PENDING
) {
674 TP_ERROR_INVALID_ARGUMENT
,
675 "Calling Accept() on a certificate with state != PENDING "
676 "doesn't make sense."
679 dbus_g_method_return_error(context
, &error
);
683 self
->state
= SIPE_TLS_CERTIFICATE_ACCEPTED
;
684 tp_svc_authentication_tls_certificate_emit_accepted(self
);
686 tp_svc_authentication_tls_certificate_return_from_accept(context
);
689 static void tls_certificate_reject(TpSvcAuthenticationTLSCertificate
*certificate
,
690 const GPtrArray
*rejections
,
691 DBusGMethodInvocation
*context
)
693 SipeTLSCertificate
*self
= SIPE_TLS_CERTIFICATE(certificate
);
695 SIPE_DEBUG_INFO_NOFORMAT("SipeTLSCertificate::reject");
697 if (self
->state
!= SIPE_TLS_CERTIFICATE_PENDING
) {
700 TP_ERROR_INVALID_ARGUMENT
,
701 "Calling Reject() on a certificate with state != PENDING "
702 "doesn't make sense."
705 dbus_g_method_return_error(context
, &error
);
709 self
->state
= SIPE_TLS_CERTIFICATE_REJECTED
;
711 tp_svc_authentication_tls_certificate_emit_rejected(self
, rejections
);
713 tp_svc_authentication_tls_certificate_return_from_reject(context
);
716 static void tls_certificate_iface_init(gpointer g_iface
,
717 SIPE_UNUSED_PARAMETER gpointer iface_data
)
719 TpSvcAuthenticationTLSCertificateClass
*klass
= g_iface
;
721 #define IMPLEMENT(x) \
722 tp_svc_authentication_tls_certificate_implement_##x( \
723 klass, tls_certificate_##x)
729 static void append_certificate_der(GPtrArray
*certificates
,
732 GArray
*array
= g_array_sized_new(FALSE
,
736 array
= g_array_append_vals(array
, der
->data
, der
->len
);
737 g_byte_array_unref(der
);
739 g_ptr_array_add(certificates
, array
);
742 struct sipe_tls_info
*sipe_telepathy_tls_info_new(const gchar
*hostname
,
743 GTlsCertificate
*certificate
)
745 struct sipe_tls_info
*tls_info
= NULL
;
746 GByteArray
*der
= NULL
;
748 g_object_get(certificate
, "certificate", &der
, NULL
);
750 GPtrArray
*identities
= g_ptr_array_new();
752 tls_info
= g_new0(struct sipe_tls_info
, 1);
753 tls_info
->hostname
= g_strdup(hostname
);
755 /* build GStrv of identies */
756 g_ptr_array_add(identities
, g_strdup(hostname
));
757 g_ptr_array_add(identities
, NULL
);
758 tls_info
->reference_identities
= (GStrv
) g_ptr_array_free(identities
,
761 tls_info
->cert_data
= g_ptr_array_new_full(1,
762 (GDestroyNotify
) g_array_unref
);
764 append_certificate_der(tls_info
->cert_data
, der
);
766 /* will be unref'd in loop */
767 g_object_ref(certificate
);
768 while (certificate
) {
769 GTlsCertificate
*issuer
= NULL
;
771 g_object_get(certificate
, "issuer", &issuer
, NULL
);
772 g_object_unref(certificate
);
774 /* add issuer certificate */
776 g_object_get(certificate
, "certificate", &der
, NULL
);
779 append_certificate_der(tls_info
->cert_data
, der
);
782 /* walk up the chain */
783 certificate
= issuer
;
790 void sipe_telepathy_tls_info_free(struct sipe_tls_info
*tls_info
)
792 g_object_unref(tls_info
->certificate
);
793 g_free(tls_info
->hostname
);
794 g_free(tls_info
->cert_path
);
795 g_ptr_array_unref(tls_info
->cert_data
);
796 g_strfreev(tls_info
->reference_identities
);
800 /* create new tls certificate object */
801 void sipe_telepathy_tls_verify_async(GObject
*connection
,
802 struct sipe_tls_info
*tls_info
,
803 GAsyncReadyCallback callback
,
806 /* property "connection" required by TpBaseChannel */
807 SipeTLSChannel
*channel
= g_object_new(SIPE_TYPE_TLS_CHANNEL
,
808 "connection", connection
,
810 TpBaseChannel
*base
= TP_BASE_CHANNEL(channel
);
811 SipeTLSCertificate
*certificate
= g_object_new(SIPE_TYPE_TLS_CERTIFICATE
,
813 TpDBusDaemon
*daemon
= tp_dbus_daemon_dup(NULL
);
815 tls_info
->certificate
= certificate
;
816 certificate
->tls_info
= tls_info
;
818 tp_base_channel_register(base
);
819 tls_info
->cert_path
= g_strdup_printf("%s/TLSCertificateObject",
820 tp_base_channel_get_object_path(base
));
822 /* register the certificate on the bus */
823 tp_dbus_daemon_register_object(daemon
,
826 g_object_unref(daemon
);
828 channel_new_certificate(connection
,