From c5d839c2b07eb0e18a1081e06d7055af20014723 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 28 Apr 2013 16:38:58 +0200 Subject: 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 --- src/server-tls-channel.c | 308 +++++++++++++++++++++++++ src/server-tls-channel.h | 71 ++++++ src/server-tls-manager.c | 585 +++++++++++++++++++++++++++++++++++++++++++++++ src/server-tls-manager.h | 74 ++++++ src/tls-certificate.c | 344 ++++++++++++++++++++++++++++ src/tls-certificate.h | 66 ++++++ 6 files changed, 1448 insertions(+) create mode 100644 src/server-tls-channel.c create mode 100644 src/server-tls-channel.h create mode 100644 src/server-tls-manager.c create mode 100644 src/server-tls-manager.h create mode 100644 src/tls-certificate.c create mode 100644 src/tls-certificate.h diff --git a/src/server-tls-channel.c b/src/server-tls-channel.c new file mode 100644 index 0000000..552b315 --- /dev/null +++ b/src/server-tls-channel.c @@ -0,0 +1,308 @@ +/* + * server-tls-channel.c - Source for IdleServerTLSChannel + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "server-tls-channel.h" + +#include +#include + +#include + +#define DEBUG_FLAG IDLE_DEBUG_TLS +#include "debug.h" +#include "connection.h" +#include "tls-certificate.h" + +G_DEFINE_TYPE_WITH_CODE (IdleServerTLSChannel, idle_server_tls_channel, + TP_TYPE_BASE_CHANNEL, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_SERVER_TLS_CONNECTION, + NULL)); + +static void idle_server_tls_channel_close (TpBaseChannel *base); + +enum { + /* server TLS channel iface */ + PROP_SERVER_CERTIFICATE = 1, + PROP_HOSTNAME, + PROP_REFERENCE_IDENTITIES, + + /* not exported */ + PROP_TLS_SESSION, + + NUM_PROPERTIES +}; + +struct _IdleServerTLSChannelPrivate { + WockyTLSSession *tls_session; + + IdleTLSCertificate *server_cert; + gchar *server_cert_path; + gchar *hostname; + GStrv reference_identities; + + gboolean dispose_has_run; +}; + +static void +idle_server_tls_channel_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object); + + switch (property_id) + { + case PROP_SERVER_CERTIFICATE: + g_value_set_boxed (value, self->priv->server_cert_path); + break; + case PROP_HOSTNAME: + g_value_set_string (value, self->priv->hostname); + break; + case PROP_REFERENCE_IDENTITIES: + g_value_set_boxed (value, self->priv->reference_identities); + break; + case PROP_TLS_SESSION: + g_value_set_object (value, self->priv->tls_session); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +idle_server_tls_channel_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object); + + switch (property_id) + { + case PROP_TLS_SESSION: + self->priv->tls_session = g_value_dup_object (value); + break; + case PROP_HOSTNAME: + self->priv->hostname = g_value_dup_string (value); + break; + case PROP_REFERENCE_IDENTITIES: + self->priv->reference_identities = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +idle_server_tls_channel_finalize (GObject *object) +{ + IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object); + + DEBUG ("Finalize TLS channel"); + + g_free (self->priv->server_cert_path); + g_free (self->priv->hostname); + g_strfreev (self->priv->reference_identities); + + G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->finalize (object); +} + +static void +idle_server_tls_channel_dispose (GObject *object) +{ + IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object); + + if (self->priv->dispose_has_run) + return; + + DEBUG ("Dispose TLS channel"); + + self->priv->dispose_has_run = TRUE; + + tp_clear_object (&self->priv->server_cert); + tp_clear_object (&self->priv->tls_session); + + G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->dispose (object); +} + +static const gchar * +cert_type_to_str (WockyTLSCertType type) +{ + const gchar *retval = NULL; + + switch (type) + { + case WOCKY_TLS_CERT_TYPE_X509: + retval = "x509"; + break; + case WOCKY_TLS_CERT_TYPE_OPENPGP: + retval = "pgp"; + break; + default: + break; + } + + return retval; +} + +static void +idle_server_tls_channel_constructed (GObject *object) +{ + IdleServerTLSChannel *self = IDLE_SERVER_TLS_CHANNEL (object); + TpBaseChannel *base = TP_BASE_CHANNEL (self); + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); + void (*chain_up) (GObject *) = + G_OBJECT_CLASS (idle_server_tls_channel_parent_class)->constructed; + WockyTLSCertType cert_type; + const gchar *path; + gchar *cert_object_path; + GPtrArray *certificates; + + if (chain_up != NULL) + chain_up (object); + + tp_base_channel_register (base); + + /* create the TLS certificate object */ + path = tp_base_channel_get_object_path (base); + cert_object_path = g_strdup_printf ("%s/TLSCertificateObject", path); + certificates = wocky_tls_session_get_peers_certificate ( + self->priv->tls_session, &cert_type); + + self->priv->server_cert = g_object_new (IDLE_TYPE_TLS_CERTIFICATE, + "object-path", cert_object_path, + "certificate-chain-data", certificates, + "certificate-type", cert_type_to_str (cert_type), + "dbus-daemon", IDLE_CONNECTION (base_conn)->daemon, + NULL); + self->priv->server_cert_path = cert_object_path; + + DEBUG ("Server TLS channel constructed at %s", path); +} + +static void +idle_server_tls_channel_fill_immutable_properties ( + TpBaseChannel *chan, + GHashTable *properties) +{ + TP_BASE_CHANNEL_CLASS (idle_server_tls_channel_parent_class) + ->fill_immutable_properties (chan, properties); + + tp_dbus_properties_mixin_fill_properties_hash ( + G_OBJECT (chan), properties, + TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "ServerCertificate", + TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "Hostname", + TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION, "ReferenceIdentities", + NULL); +} + +static gchar * +idle_server_tls_channel_get_object_path_suffix (TpBaseChannel *base) +{ + static guint count = 0; + + return g_strdup_printf ("ServerTLSChannel%u", ++count); +} + +static void +idle_server_tls_channel_init (IdleServerTLSChannel *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IDLE_TYPE_SERVER_TLS_CHANNEL, IdleServerTLSChannelPrivate); +} + +static void +idle_server_tls_channel_class_init (IdleServerTLSChannelClass *klass) +{ + static TpDBusPropertiesMixinPropImpl server_tls_props[] = { + { "ServerCertificate", "server-certificate", NULL }, + { "Hostname", "hostname", NULL }, + { "ReferenceIdentities", "reference-identities", NULL }, + { NULL } + }; + + GObjectClass *oclass = G_OBJECT_CLASS (klass); + TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (IdleServerTLSChannelPrivate)); + + oclass->get_property = idle_server_tls_channel_get_property; + oclass->set_property = idle_server_tls_channel_set_property; + oclass->dispose = idle_server_tls_channel_dispose; + oclass->finalize = idle_server_tls_channel_finalize; + oclass->constructed = idle_server_tls_channel_constructed; + + base_class->channel_type = TP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION; + base_class->target_handle_type = TP_HANDLE_TYPE_NONE; + base_class->fill_immutable_properties = + idle_server_tls_channel_fill_immutable_properties; + base_class->get_object_path_suffix = + idle_server_tls_channel_get_object_path_suffix; + base_class->close = idle_server_tls_channel_close; + + pspec = g_param_spec_boxed ("server-certificate", "Server certificate path", + "The object path of the server certificate.", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_SERVER_CERTIFICATE, pspec); + + pspec = g_param_spec_string ("hostname", "The hostname to be verified", + "The hostname which should be certified by the server certificate.", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_HOSTNAME, pspec); + + pspec = g_param_spec_boxed ("reference-identities", + "The various identities to check the certificate against", + "The server certificate identity should match one of these identities.", + G_TYPE_STRV, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_REFERENCE_IDENTITIES, pspec); + + pspec = g_param_spec_object ("tls-session", "The WockyTLSSession", + "The WockyTLSSession object containing the TLS information", + WOCKY_TYPE_TLS_SESSION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_TLS_SESSION, pspec); + + tp_dbus_properties_mixin_implement_interface (oclass, + TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION, + tp_dbus_properties_mixin_getter_gobject_properties, NULL, + server_tls_props); +} + +static void +idle_server_tls_channel_close (TpBaseChannel *base) +{ + DEBUG ("Close() called on the TLS channel %p", base); + tp_base_channel_destroyed (base); +} + +IdleTLSCertificate * +idle_server_tls_channel_get_certificate (IdleServerTLSChannel *self) +{ + return self->priv->server_cert; +} diff --git a/src/server-tls-channel.h b/src/server-tls-channel.h new file mode 100644 index 0000000..47b8474 --- /dev/null +++ b/src/server-tls-channel.h @@ -0,0 +1,71 @@ +/* + * server-tls-channel.h - Header for IdleServerTLSChannel + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __IDLE_SERVER_TLS_CHANNEL_H__ +#define __IDLE_SERVER_TLS_CHANNEL_H__ + +#include + +#include + +#include + +#include "tls-certificate.h" + +G_BEGIN_DECLS + +typedef struct _IdleServerTLSChannelPrivate IdleServerTLSChannelPrivate; +typedef struct _IdleServerTLSChannelClass IdleServerTLSChannelClass; +typedef struct _IdleServerTLSChannel IdleServerTLSChannel; + +struct _IdleServerTLSChannelClass { + TpBaseChannelClass base_class; +}; + +struct _IdleServerTLSChannel { + TpBaseChannel parent; + + IdleServerTLSChannelPrivate *priv; +}; + +GType idle_server_tls_channel_get_type (void); + +#define IDLE_TYPE_SERVER_TLS_CHANNEL \ + (idle_server_tls_channel_get_type ()) +#define IDLE_SERVER_TLS_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_SERVER_TLS_CHANNEL, \ + IdleServerTLSChannel)) +#define IDLE_SERVER_TLS_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_SERVER_TLS_CHANNEL, \ + IdleServerTLSChannelClass)) +#define IDLE_IS_SERVER_TLS_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_SERVER_TLS_CHANNEL)) +#define IDLE_IS_SERVER_TLS_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_SERVER_TLS_CHANNEL)) +#define IDLE_SERVER_TLS_CHANNEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_SERVER_TLS_CHANNEL,\ + IdleServerTLSChannelClass)) + +IdleTLSCertificate * idle_server_tls_channel_get_certificate ( + IdleServerTLSChannel *self); + +G_END_DECLS + +#endif /* #ifndef __IDLE_SERVER_TLS_CHANNEL_H__*/ diff --git a/src/server-tls-manager.c b/src/server-tls-manager.c new file mode 100644 index 0000000..e32c991 --- /dev/null +++ b/src/server-tls-manager.c @@ -0,0 +1,585 @@ +/* + * server-tls-manager.c - Source for IdleServerTLSManager + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "server-tls-manager.h" + +#include +#include + +#define DEBUG_FLAG IDLE_DEBUG_TLS +#include "debug.h" +#include "gabble/caps-channel-manager.h" +#include "connection.h" +#include "server-tls-channel.h" +#include "util.h" + +#include "extensions/extensions.h" + +#include + +static void channel_manager_iface_init (gpointer, gpointer); + +G_DEFINE_TYPE_WITH_CODE (IdleServerTLSManager, idle_server_tls_manager, + WOCKY_TYPE_TLS_HANDLER, + G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER, + channel_manager_iface_init); + G_IMPLEMENT_INTERFACE (IDLE_TYPE_CAPS_CHANNEL_MANAGER, + NULL)); + +enum { + PROP_CONNECTION = 1, + PROP_INTERACTIVE_TLS, + NUM_PROPERTIES +}; + +struct _IdleServerTLSManagerPrivate { + /* Properties */ + IdleConnection *connection; + gboolean interactive_tls; + + /* Current operation data */ + gchar *peername; + GStrv reference_identities; + WockyTLSSession *tls_session; + IdleServerTLSChannel *channel; + GSimpleAsyncResult *async_result; + + /* List of owned TpBaseChannel not yet closed by the client */ + GList *completed_channels; + + gboolean dispose_has_run; +}; + +#define chainup ((WockyTLSHandlerClass *) \ + idle_server_tls_manager_parent_class) + +static void +idle_server_tls_manager_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object); + + switch (property_id) + { + case PROP_CONNECTION: + g_value_set_object (value, self->priv->connection); + break; + case PROP_INTERACTIVE_TLS: + g_value_set_boolean (value, self->priv->interactive_tls); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +idle_server_tls_manager_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object); + + switch (property_id) + { + case PROP_CONNECTION: + self->priv->connection = g_value_dup_object (value); + break; + case PROP_INTERACTIVE_TLS: + self->priv->interactive_tls = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +close_all (IdleServerTLSManager *self) +{ + GList *l; + + if (self->priv->channel != NULL) + tp_base_channel_close (TP_BASE_CHANNEL (self->priv->channel)); + + l = self->priv->completed_channels; + while (l != NULL) + { + /* use a temporary variable as the ::closed callback will delete + * the link from the list. */ + GList *next = l->next; + + tp_base_channel_close (l->data); + + l = next; + } +} + +static void +connection_status_changed_cb (IdleConnection *conn, + guint status, + guint reason, + gpointer user_data) +{ + IdleServerTLSManager *self = user_data; + + DEBUG ("Connection status changed, now %d", status); + + if (status == TP_CONNECTION_STATUS_DISCONNECTED) + { + close_all (self); + tp_clear_object (&self->priv->connection); + } +} + +static void +complete_verify (IdleServerTLSManager *self) +{ + /* Move channel to a list until a client Close() it */ + if (self->priv->channel != NULL) + { + self->priv->completed_channels = g_list_prepend ( + self->priv->completed_channels, + g_object_ref (self->priv->channel)); + } + + g_simple_async_result_complete (self->priv->async_result); + + /* Reset to initial state */ + tp_clear_pointer (&self->priv->peername, g_free); + tp_clear_pointer (&self->priv->reference_identities, g_strfreev); + g_clear_object (&self->priv->tls_session); + g_clear_object (&self->priv->channel); + g_clear_object (&self->priv->async_result); +} + +static void +verify_fallback_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + IdleServerTLSManager *self = (IdleServerTLSManager *) source; + GError *error = NULL; + + if (!chainup->verify_finish_func (WOCKY_TLS_HANDLER (self), result, &error)) + g_simple_async_result_take_error (self->priv->async_result, error); + + complete_verify (self); +} + +static void +server_tls_channel_closed_cb (IdleServerTLSChannel *channel, + gpointer user_data) +{ + IdleServerTLSManager *self = user_data; + + DEBUG ("Server TLS channel closed."); + + if (channel == self->priv->channel) + { + /* fallback to the old-style non interactive TLS verification */ + DEBUG ("Channel closed, but unhandled, falling back..."); + + chainup->verify_async_func (WOCKY_TLS_HANDLER (self), + self->priv->tls_session, self->priv->peername, + self->priv->reference_identities, verify_fallback_cb, NULL); + + self->priv->channel = NULL; + } + else + { + GList *l; + + l = g_list_find (self->priv->completed_channels, channel); + g_assert (l != NULL); + + self->priv->completed_channels = g_list_delete_link ( + self->priv->completed_channels, l); + } + + tp_channel_manager_emit_channel_closed_for_object (self, + TP_EXPORTABLE_CHANNEL (channel)); + g_object_unref (channel); +} + +GQuark +idle_server_tls_error_quark (void) +{ + static GQuark quark = 0; + + if (!quark) + quark = g_quark_from_static_string ("server-tls-error"); + + return quark; +} + +static void +tls_certificate_accepted_cb (IdleTLSCertificate *certificate, + gpointer user_data) +{ + IdleServerTLSManager *self = user_data; + + DEBUG ("TLS certificate accepted"); + + complete_verify (self); +} + +static void +tls_certificate_rejected_cb (IdleTLSCertificate *certificate, + GPtrArray *rejections, + gpointer user_data) +{ + IdleServerTLSManager *self = user_data; + + DEBUG ("TLS certificate rejected with rejections %p, length %u.", + rejections, rejections->len); + + g_simple_async_result_set_error (self->priv->async_result, + IDLE_SERVER_TLS_ERROR, 0, "TLS certificate rejected"); + + complete_verify (self); +} + +static void +extend_string_ptr_array (GPtrArray *array, + GStrv new_elements) +{ + gint i; + + if (new_elements != NULL) + { + for (i = 0; new_elements[i] != NULL; i++) + { + if (!tp_str_empty (new_elements[i])) + g_ptr_array_add (array, g_strdup (new_elements[i])); + } + } +} + +static void +fill_reference_identities (IdleServerTLSManager *self, + const gchar *peername, + GStrv original_extra_identities) +{ + GPtrArray *identities; + gchar *connect_server = NULL; + gchar *explicit_server = NULL; + GStrv extra_certificate_identities = NULL; + + g_return_if_fail (self->priv->reference_identities == NULL); + + g_object_get (self->priv->connection, + "connect-server", &connect_server, + "explicit-server", &explicit_server, + "extra-certificate-identities", &extra_certificate_identities, + NULL); + + identities = g_ptr_array_new (); + + /* The peer name, i.e, the domain part of the JID */ + g_ptr_array_add (identities, g_strdup (peername)); + + /* The extra identities that the caller of verify_async() passed */ + extend_string_ptr_array (identities, original_extra_identities); + + /* The explicitly overridden server (if in use) */ + if (!tp_str_empty (explicit_server) && + !tp_strdiff (connect_server, explicit_server)) + { + g_ptr_array_add (identities, g_strdup (explicit_server)); + } + + /* Extra identities added to the account as a result of user choices */ + extend_string_ptr_array (identities, extra_certificate_identities); + + /* Null terminate, since this is a gchar** */ + g_ptr_array_add (identities, NULL); + + self->priv->reference_identities = (GStrv) g_ptr_array_free (identities, + FALSE); + + g_strfreev (extra_certificate_identities); + g_free (explicit_server); + g_free (connect_server); +} + +static void +idle_server_tls_manager_verify_async (WockyTLSHandler *handler, + WockyTLSSession *tls_session, + const gchar *peername, + GStrv extra_identities, + GAsyncReadyCallback callback, + gpointer user_data) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (handler); + IdleTLSCertificate *certificate; + GSimpleAsyncResult *result; + + g_return_if_fail (self->priv->async_result == NULL); + + DEBUG ("verify_async() called on the IdleServerTLSManager."); + + result = g_simple_async_result_new (G_OBJECT (self), + callback, user_data, idle_server_tls_manager_verify_async); + + if (self->priv->connection == NULL) + { + DEBUG ("connection already went away; failing immediately"); + g_simple_async_result_set_error (result, TP_ERROR, TP_ERROR_CANCELLED, + "The Telepathy connection has already been disconnected"); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + return; + } + + self->priv->async_result = result; + + fill_reference_identities (self, peername, extra_identities); + + if (!self->priv->interactive_tls) + { + DEBUG ("ignore-ssl-errors is set, fallback to non-interactive " + "verification."); + + chainup->verify_async_func (WOCKY_TLS_HANDLER (self), tls_session, + peername, self->priv->reference_identities, verify_fallback_cb, NULL); + + return; + } + + self->priv->tls_session = g_object_ref (tls_session); + self->priv->peername = g_strdup (peername); + + self->priv->channel = g_object_new (IDLE_TYPE_SERVER_TLS_CHANNEL, + "connection", self->priv->connection, + "tls-session", tls_session, + "hostname", peername, + "reference-identities", self->priv->reference_identities, + NULL); + + g_signal_connect (self->priv->channel, "closed", + G_CALLBACK (server_tls_channel_closed_cb), self); + + certificate = idle_server_tls_channel_get_certificate (self->priv->channel); + + g_signal_connect (certificate, "accepted", + G_CALLBACK (tls_certificate_accepted_cb), self); + g_signal_connect (certificate, "rejected", + G_CALLBACK (tls_certificate_rejected_cb), self); + + /* emit NewChannel on the ChannelManager iface */ + tp_channel_manager_emit_new_channel (self, + (TpExportableChannel *) self->priv->channel, NULL); +} + +static gboolean +idle_server_tls_manager_verify_finish (WockyTLSHandler *self, + GAsyncResult *result, + GError **error) +{ + wocky_implement_finish_void (self, idle_server_tls_manager_verify_async); +} + +static void +idle_server_tls_manager_init (IdleServerTLSManager *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IDLE_TYPE_SERVER_TLS_MANAGER, IdleServerTLSManagerPrivate); +} + +static void +idle_server_tls_manager_dispose (GObject *object) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object); + + DEBUG ("%p", self); + + if (self->priv->dispose_has_run) + return; + + self->priv->dispose_has_run = TRUE; + + tp_clear_object (&self->priv->tls_session); + tp_clear_object (&self->priv->connection); + + G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->dispose (object); +} + +static void +idle_server_tls_manager_finalize (GObject *object) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object); + + DEBUG ("%p", self); + + close_all (self); + + g_free (self->priv->peername); + g_strfreev (self->priv->reference_identities); + + G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->finalize (object); +} + +static void +idle_server_tls_manager_constructed (GObject *object) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (object); + void (*chain_up) (GObject *) = + G_OBJECT_CLASS (idle_server_tls_manager_parent_class)->constructed; + + if (chain_up != NULL) + chain_up (object); + + DEBUG ("Server TLS Manager constructed"); + + idle_signal_connect_weak (self->priv->connection, "status-changed", + G_CALLBACK (connection_status_changed_cb), object); +} + +static void +idle_server_tls_manager_class_init (IdleServerTLSManagerClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + WockyTLSHandlerClass *hclass = WOCKY_TLS_HANDLER_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (IdleServerTLSManagerPrivate)); + + oclass->dispose = idle_server_tls_manager_dispose; + oclass->finalize = idle_server_tls_manager_finalize; + oclass->constructed = idle_server_tls_manager_constructed; + oclass->set_property = idle_server_tls_manager_set_property; + oclass->get_property = idle_server_tls_manager_get_property; + + hclass->verify_async_func = idle_server_tls_manager_verify_async; + hclass->verify_finish_func = idle_server_tls_manager_verify_finish; + + pspec = g_param_spec_object ("connection", "IdleConnection object", + "Idle connection object that owns this manager.", + IDLE_TYPE_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_CONNECTION, pspec); + + pspec = g_param_spec_boolean ("interactive-tls", "Interactive TLS setting", + "Whether interactive TLS certificate verification is enabled.", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_INTERACTIVE_TLS, pspec); +} + +static void +idle_server_tls_manager_foreach_channel (TpChannelManager *manager, + TpExportableChannelFunc func, + gpointer user_data) +{ + IdleServerTLSManager *self = IDLE_SERVER_TLS_MANAGER (manager); + GList *l; + + if (self->priv->channel != NULL) + func (TP_EXPORTABLE_CHANNEL (self->priv->channel), user_data); + + for (l = self->priv->completed_channels; l != NULL; l = l->next) + { + func (l->data, user_data); + } +} + +static void +channel_manager_iface_init (gpointer g_iface, + gpointer iface_data) +{ + TpChannelManagerIface *iface = g_iface; + + iface->foreach_channel = idle_server_tls_manager_foreach_channel; + + /* these channels are not requestable. */ + iface->ensure_channel = NULL; + iface->create_channel = NULL; + iface->request_channel = NULL; + iface->foreach_channel_class = NULL; +} + +static TpConnectionStatusReason +cert_reject_reason_to_conn_reason (TpTLSCertificateRejectReason tls_reason) +{ + #define EASY_CASE(x) \ + case TP_TLS_CERTIFICATE_REJECT_REASON_ ## x: \ + return TP_CONNECTION_STATUS_REASON_CERT_ ## x; + + switch (tls_reason) + { + EASY_CASE (UNTRUSTED); + EASY_CASE (EXPIRED); + EASY_CASE (NOT_ACTIVATED); + EASY_CASE (FINGERPRINT_MISMATCH); + EASY_CASE (HOSTNAME_MISMATCH); + EASY_CASE (SELF_SIGNED); + EASY_CASE (REVOKED); + EASY_CASE (INSECURE); + EASY_CASE (LIMIT_EXCEEDED); + + case TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN: + default: + return TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR; + } + + #undef EASY_CASE +} + +void +idle_server_tls_manager_get_rejection_details (IdleServerTLSManager *self, + gchar **dbus_error, + GHashTable **details, + TpConnectionStatusReason *reason) +{ + IdleTLSCertificate *certificate; + GPtrArray *rejections; + GValueArray *rejection; + TpTLSCertificateRejectReason tls_reason; + + /* We probably want the rejection details of last completed operation */ + g_return_if_fail (self->priv->completed_channels != NULL); + + certificate = idle_server_tls_channel_get_certificate ( + self->priv->completed_channels->data); + g_object_get (certificate, + "rejections", &rejections, + NULL); + + /* we return 'Invalid_Argument' if Reject() is called with zero + * reasons, so if this fails something bad happened. + */ + g_assert (rejections->len >= 1); + + rejection = g_ptr_array_index (rejections, 0); + + tls_reason = g_value_get_uint (g_value_array_get_nth (rejection, 0)); + *dbus_error = g_value_dup_string (g_value_array_get_nth (rejection, 1)); + *details = g_value_dup_boxed (g_value_array_get_nth (rejection, 2)); + + *reason = cert_reject_reason_to_conn_reason (tls_reason); + + tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST, + &rejections); +} diff --git a/src/server-tls-manager.h b/src/server-tls-manager.h new file mode 100644 index 0000000..a584e9f --- /dev/null +++ b/src/server-tls-manager.h @@ -0,0 +1,74 @@ +/* + * server-tls-manager.h - Header for IdleServerTLSManager + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __IDLE_SERVER_TLS_MANAGER_H__ +#define __IDLE_SERVER_TLS_MANAGER_H__ + +#include +#include +#include + +#include "extensions/extensions.h" + +G_BEGIN_DECLS + +typedef struct _IdleServerTLSManager IdleServerTLSManager; +typedef struct _IdleServerTLSManagerClass IdleServerTLSManagerClass; +typedef struct _IdleServerTLSManagerPrivate IdleServerTLSManagerPrivate; + +struct _IdleServerTLSManagerClass { + WockyTLSHandlerClass parent_class; +}; + +struct _IdleServerTLSManager { + WockyTLSHandler parent; + IdleServerTLSManagerPrivate *priv; +}; + +GType idle_server_tls_manager_get_type (void); + +#define IDLE_TYPE_SERVER_TLS_MANAGER \ + (idle_server_tls_manager_get_type ()) +#define IDLE_SERVER_TLS_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_SERVER_TLS_MANAGER, \ + IdleServerTLSManager)) +#define IDLE_SERVER_TLS_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_SERVER_TLS_MANAGER, \ + IdleServerTLSManagerClass)) +#define IDLE_IS_SERVER_TLS_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_SERVER_TLS_MANAGER)) +#define IDLE_IS_SERVER_TLS_MANAGER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_SERVER_TLS_MANAGER)) +#define IDLE_SERVER_TLS_MANAGER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_SERVER_TLS_MANAGER, \ + IdleServerTLSManagerClass)) + +#define IDLE_SERVER_TLS_ERROR idle_server_tls_error_quark () +GQuark idle_server_tls_error_quark (void); + +void idle_server_tls_manager_get_rejection_details ( + IdleServerTLSManager *self, + gchar **dbus_error, + GHashTable **details, + TpConnectionStatusReason *reason); + +G_END_DECLS + +#endif /* #ifndef __IDLE_SERVER_TLS_MANAGER_H__ */ diff --git a/src/tls-certificate.c b/src/tls-certificate.c new file mode 100644 index 0000000..a0abfa6 --- /dev/null +++ b/src/tls-certificate.c @@ -0,0 +1,344 @@ +/* + * tls-certificate.c - Source for IdleTLSCertificate + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "tls-certificate.h" + +#include +#include + +#define DEBUG_FLAG IDLE_DEBUG_TLS +#include "debug.h" + +static void +tls_certificate_iface_init (gpointer g_iface, gpointer iface_data); + +G_DEFINE_TYPE_WITH_CODE (IdleTLSCertificate, + idle_tls_certificate, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE, + tls_certificate_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, + tp_dbus_properties_mixin_iface_init);) + +struct _IdleTLSCertificatePrivate { + gchar *object_path; + + gchar *cert_type; + TpTLSCertificateState cert_state; + + GPtrArray *rejections; + GPtrArray *cert_data; + + TpDBusDaemon *daemon; + + gboolean dispose_has_run; +}; + +enum { + PROP_OBJECT_PATH = 1, + PROP_STATE, + PROP_REJECTIONS, + PROP_CERTIFICATE_TYPE, + PROP_CERTIFICATE_CHAIN_DATA, + + /* not exported */ + PROP_DBUS_DAEMON, + + NUM_PROPERTIES +}; + +static void +idle_tls_certificate_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object); + + switch (property_id) + { + case PROP_OBJECT_PATH: + g_value_set_string (value, self->priv->object_path); + break; + case PROP_STATE: + g_value_set_uint (value, self->priv->cert_state); + break; + case PROP_REJECTIONS: + g_value_set_boxed (value, self->priv->rejections); + break; + case PROP_CERTIFICATE_TYPE: + g_value_set_string (value, self->priv->cert_type); + break; + case PROP_CERTIFICATE_CHAIN_DATA: + g_value_set_boxed (value, self->priv->cert_data); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +idle_tls_certificate_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object); + + switch (property_id) + { + case PROP_OBJECT_PATH: + self->priv->object_path = g_value_dup_string (value); + break; + case PROP_CERTIFICATE_TYPE: + self->priv->cert_type = g_value_dup_string (value); + break; + case PROP_CERTIFICATE_CHAIN_DATA: + self->priv->cert_data = g_value_dup_boxed (value); + break; + case PROP_DBUS_DAEMON: + self->priv->daemon = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, value); + break; + } +} + +static void +idle_tls_certificate_finalize (GObject *object) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object); + + tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST, + &self->priv->rejections); + + g_free (self->priv->object_path); + g_free (self->priv->cert_type); + g_ptr_array_unref (self->priv->cert_data); + + G_OBJECT_CLASS (idle_tls_certificate_parent_class)->finalize (object); +} + +static void +idle_tls_certificate_dispose (GObject *object) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object); + + if (self->priv->dispose_has_run) + return; + + self->priv->dispose_has_run = TRUE; + + tp_clear_object (&self->priv->daemon); + + G_OBJECT_CLASS (idle_tls_certificate_parent_class)->dispose (object); +} + +static void +idle_tls_certificate_constructed (GObject *object) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (object); + void (*chain_up) (GObject *) = + G_OBJECT_CLASS (idle_tls_certificate_parent_class)->constructed; + + if (chain_up != NULL) + chain_up (object); + + /* register the certificate on the bus */ + tp_dbus_daemon_register_object (self->priv->daemon, + self->priv->object_path, self); +} + +static void +idle_tls_certificate_init (IdleTLSCertificate *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IDLE_TYPE_TLS_CERTIFICATE, IdleTLSCertificatePrivate); + self->priv->rejections = g_ptr_array_new (); +} + +static void +idle_tls_certificate_class_init (IdleTLSCertificateClass *klass) +{ + static TpDBusPropertiesMixinPropImpl object_props[] = { + { "State", "state", NULL }, + { "Rejections", "rejections", NULL }, + { "CertificateType", "certificate-type", NULL }, + { "CertificateChainData", "certificate-chain-data", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { + { TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + object_props, + }, + { NULL } + }; + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GParamSpec *pspec; + + g_type_class_add_private (klass, sizeof (IdleTLSCertificatePrivate)); + + oclass->finalize = idle_tls_certificate_finalize; + oclass->dispose = idle_tls_certificate_dispose; + oclass->set_property = idle_tls_certificate_set_property; + oclass->get_property = idle_tls_certificate_get_property; + oclass->constructed = idle_tls_certificate_constructed; + + pspec = g_param_spec_string ("object-path", + "D-Bus object path", + "The D-Bus object path used for this object on the bus.", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_OBJECT_PATH, pspec); + + pspec = g_param_spec_uint ("state", + "State of this certificate", + "The state of this TLS certificate.", + 0, NUM_TP_TLS_CERTIFICATE_STATES - 1, + TP_TLS_CERTIFICATE_STATE_PENDING, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_STATE, pspec); + + pspec = g_param_spec_boxed ("rejections", + "The reject reasons", + "The reasons why this TLS certificate has been rejected", + TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_REJECTIONS, pspec); + + pspec = g_param_spec_string ("certificate-type", + "The certificate type", + "The type of this certificate.", + NULL, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_CERTIFICATE_TYPE, pspec); + + pspec = g_param_spec_boxed ("certificate-chain-data", + "The certificate chain data", + "The raw PEM-encoded trust chain of this certificate.", + TP_ARRAY_TYPE_UCHAR_ARRAY_LIST, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_CERTIFICATE_CHAIN_DATA, pspec); + + pspec = g_param_spec_object ("dbus-daemon", + "The DBus daemon connection", + "The connection to the DBus daemon owning the CM", + TP_TYPE_DBUS_DAEMON, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (oclass, PROP_DBUS_DAEMON, pspec); + + klass->dbus_props_class.interfaces = prop_interfaces; + tp_dbus_properties_mixin_class_init (oclass, + G_STRUCT_OFFSET (IdleTLSCertificateClass, dbus_props_class)); +} + +static void +idle_tls_certificate_accept (TpSvcAuthenticationTLSCertificate *cert, + DBusGMethodInvocation *context) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (cert); + + DEBUG ("Accept() called on the TLS certificate; current state %u", + self->priv->cert_state); + + if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING) + { + GError error = + { TP_ERROR, + TP_ERROR_INVALID_ARGUMENT, + "Calling Accept() on a certificate with state != PENDING " + "doesn't make sense." + }; + + dbus_g_method_return_error (context, &error); + return; + } + + self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_ACCEPTED; + tp_svc_authentication_tls_certificate_emit_accepted (self); + + tp_svc_authentication_tls_certificate_return_from_accept (context); +} + +static void +idle_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *cert, + const GPtrArray *rejections, + DBusGMethodInvocation *context) +{ + IdleTLSCertificate *self = IDLE_TLS_CERTIFICATE (cert); + + DEBUG ("Reject() called on the TLS certificate with rejections %p, " + "length %u; current state %u", rejections, rejections->len, + self->priv->cert_state); + + if (rejections->len < 1) + { + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Calling Reject() with a zero-length rejection list." }; + + dbus_g_method_return_error (context, &error); + return; + } + + if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING) + { + GError error = + { TP_ERROR, + TP_ERROR_INVALID_ARGUMENT, + "Calling Reject() on a certificate with state != PENDING " + "doesn't make sense." + }; + + dbus_g_method_return_error (context, &error); + return; + } + + tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST, + &self->priv->rejections); + + self->priv->rejections = + g_boxed_copy (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST, + rejections); + self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_REJECTED; + + tp_svc_authentication_tls_certificate_emit_rejected ( + self, self->priv->rejections); + + tp_svc_authentication_tls_certificate_return_from_reject (context); +} + +static void +tls_certificate_iface_init (gpointer g_iface, + gpointer iface_data) +{ + TpSvcAuthenticationTLSCertificateClass *klass = g_iface; + +#define IMPLEMENT(x) \ + tp_svc_authentication_tls_certificate_implement_##x ( \ + klass, idle_tls_certificate_##x) + IMPLEMENT (accept); + IMPLEMENT (reject); +#undef IMPLEMENT +} diff --git a/src/tls-certificate.h b/src/tls-certificate.h new file mode 100644 index 0000000..52ea684 --- /dev/null +++ b/src/tls-certificate.h @@ -0,0 +1,66 @@ +/* + * tls-certificate.h - Header for IdleTLSCertificate + * Copyright (C) 2010 Collabora Ltd. + * @author Cosimo Cecchi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __IDLE_TLS_CERTIFICATE_H__ +#define __IDLE_TLS_CERTIFICATE_H__ + +#include + +#include + +G_BEGIN_DECLS + +typedef struct _IdleTLSCertificate IdleTLSCertificate; +typedef struct _IdleTLSCertificateClass IdleTLSCertificateClass; +typedef struct _IdleTLSCertificatePrivate IdleTLSCertificatePrivate; + +struct _IdleTLSCertificateClass { + GObjectClass parent_class; + + TpDBusPropertiesMixinClass dbus_props_class; +}; + +struct _IdleTLSCertificate { + GObject parent; + + IdleTLSCertificatePrivate *priv; +}; + +GType idle_tls_certificate_get_type (void); + +#define IDLE_TYPE_TLS_CERTIFICATE \ + (idle_tls_certificate_get_type ()) +#define IDLE_TLS_CERTIFICATE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), IDLE_TYPE_TLS_CERTIFICATE, \ + IdleTLSCertificate)) +#define IDLE_TLS_CERTIFICATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), IDLE_TYPE_TLS_CERTIFICATE, \ + IdleTLSCertificateClass)) +#define IDLE_IS_TLS_CERTIFICATE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), IDLE_TYPE_TLS_CERTIFICATE)) +#define IDLE_IS_TLS_CERTIFICATE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), IDLE_TYPE_TLS_CERTIFICATE)) +#define IDLE_TLS_CERTIFICATE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), IDLE_TYPE_TLS_CERTIFICATE, \ + IdleTLSCertificateClass)) + +G_END_DECLS + +#endif /* #ifndef __IDLE_TLS_CERTIFICATE_H__*/ -- cgit v1.2.3