]> git.0d.be Git - empathy.git/blob - libempathy/empathy-auth-factory.c
Unref the handler after the signal.
[empathy.git] / libempathy / empathy-auth-factory.c
1 /*
2  * empathy-auth-factory.c - Source for EmpathyAuthFactory
3  * Copyright (C) 2010 Collabora Ltd.
4  * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "empathy-auth-factory.h"
22
23 #include <telepathy-glib/interfaces.h>
24 #include <telepathy-glib/simple-handler.h>
25
26 #define DEBUG_FLAG EMPATHY_DEBUG_TLS
27 #include "empathy-debug.h"
28 #include "empathy-server-tls-handler.h"
29 #include "empathy-utils.h"
30
31 #include "extensions/extensions.h"
32
33 G_DEFINE_TYPE (EmpathyAuthFactory, empathy_auth_factory, G_TYPE_OBJECT);
34
35 typedef struct {
36   TpBaseClient *handler;
37 } EmpathyAuthFactoryPriv;
38
39 enum {
40   NEW_SERVER_TLS_HANDLER,
41   LAST_SIGNAL,
42 };
43
44 static guint signals[LAST_SIGNAL] = { 0, };
45
46 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAuthFactory)
47
48 static EmpathyAuthFactory *auth_factory_singleton = NULL;
49
50 static void
51 server_tls_handler_ready_cb (GObject *source,
52     GAsyncResult *res,
53     gpointer user_data)
54 {
55   EmpathyAuthFactory *self = user_data;
56   GError *error = NULL;
57   EmpathyServerTLSHandler *handler;
58
59   handler = empathy_server_tls_handler_new_finish (res, &error);
60
61   if (error != NULL)
62     {
63       DEBUG ("Failed to create a server TLS handler; error %s",
64           error->message);
65       g_error_free (error);
66     }
67   else
68     {
69       g_signal_emit (self, signals[NEW_SERVER_TLS_HANDLER], 0,
70           handler);
71       g_object_unref (handler);
72     }
73 }
74
75 static void
76 handle_channels_cb (TpSimpleHandler *handler,
77     TpAccount *account,
78     TpConnection *connection,
79     GList *channels,
80     GList *requests_satisfied,
81     gint64 user_action_time,
82     TpHandleChannelsContext *context,
83     gpointer user_data)
84 {
85   TpChannel *channel;
86   EmpathyAuthFactory *self = user_data;
87
88   DEBUG ("Handle TLS carrier channels.");
89
90   /* there can't be more than one ServerTLSConnection channels
91    * at the same time, for the same connection/account.
92    */
93   g_assert (g_list_length (channels) == 1);
94
95   channel = channels->data;
96
97   if (tp_proxy_get_invalidated (channel) != NULL)
98     goto out;
99
100   if (tp_channel_get_channel_type_id (channel) !=
101       EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION)
102     goto out;
103
104   /* create a handler */
105   empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb,
106       self);
107
108  out:
109   tp_handle_channels_context_accept (context);
110 }
111
112 static GObject *
113 empathy_auth_factory_constructor (GType type,
114     guint n_params,
115     GObjectConstructParam *params)
116 {
117   GObject *retval;
118
119   if (auth_factory_singleton != NULL)
120     {
121       retval = g_object_ref (auth_factory_singleton);
122     }
123   else
124     {
125       retval = G_OBJECT_CLASS (empathy_auth_factory_parent_class)->constructor
126         (type, n_params, params);
127
128       auth_factory_singleton = EMPATHY_AUTH_FACTORY (retval);
129       g_object_add_weak_pointer (retval, (gpointer *) &auth_factory_singleton);
130     }
131
132   return retval;
133 }
134
135 static void
136 empathy_auth_factory_init (EmpathyAuthFactory *self)
137 {
138   EmpathyAuthFactoryPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
139       EMPATHY_TYPE_AUTH_FACTORY, EmpathyAuthFactoryPriv);
140   TpDBusDaemon *bus;
141   GError *error = NULL;
142
143   self->priv = priv;
144
145   bus = tp_dbus_daemon_dup (&error);
146   if (error != NULL)
147     {
148       g_critical ("Failed to get TpDBusDaemon: %s", error->message);
149       g_error_free (error);
150       return;
151     }
152
153   priv->handler = tp_simple_handler_new (bus, FALSE, FALSE, "Empathy.Auth",
154       FALSE, handle_channels_cb, self, NULL);
155
156   tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
157           TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
158           EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION,
159           TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
160           TP_HANDLE_TYPE_NONE, NULL));
161
162   g_object_unref (bus);
163 }
164
165 static void
166 empathy_auth_factory_finalize (GObject *object)
167 {
168   EmpathyAuthFactoryPriv *priv = GET_PRIV (object);
169
170   if (priv->handler != NULL)
171     g_object_unref (priv->handler);
172
173   G_OBJECT_CLASS (empathy_auth_factory_parent_class)->finalize (object);
174 }
175
176 static void
177 empathy_auth_factory_class_init (EmpathyAuthFactoryClass *klass)
178 {
179   GObjectClass *oclass = G_OBJECT_CLASS (klass);
180
181   oclass->constructor = empathy_auth_factory_constructor;
182   oclass->finalize = empathy_auth_factory_finalize;
183
184   g_type_class_add_private (klass, sizeof (EmpathyAuthFactoryPriv));
185
186   signals[NEW_SERVER_TLS_HANDLER] =
187     g_signal_new ("new-server-tls-handler",
188       G_TYPE_FROM_CLASS (klass),
189       G_SIGNAL_RUN_LAST, 0,
190       NULL, NULL,
191       g_cclosure_marshal_VOID__OBJECT,
192       G_TYPE_NONE,
193       1, EMPATHY_TYPE_SERVER_TLS_HANDLER);
194 }
195
196 EmpathyAuthFactory *
197 empathy_auth_factory_dup_singleton (void)
198 {
199   return g_object_new (EMPATHY_TYPE_AUTH_FACTORY, NULL);
200 }
201
202 gboolean
203 empathy_auth_factory_register (EmpathyAuthFactory *self,
204     GError **error)
205 {
206   EmpathyAuthFactoryPriv *priv = GET_PRIV (self);
207
208   return tp_base_client_register (priv->handler, error);
209 }