1 /* GDBus - GLib D-Bus Library
2 *
3 * Copyright (C) 2008-2010 Red Hat, Inc.
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
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: David Zeuthen <davidz@redhat.com>
19 */
20
21 #include "config.h"
22
23 #include "gdbusauthmechanismanon.h"
24 #include "gdbuserror.h"
25 #include "gioenumtypes.h"
26
27 #include "glibintl.h"
28
29 struct _GDBusAuthMechanismAnonPrivate
30 {
31 gboolean is_client;
32 gboolean is_server;
33 GDBusAuthMechanismState state;
34 };
35
36 static gint mechanism_get_priority (void);
37 static const gchar *mechanism_get_name (void);
38
39 static gboolean mechanism_is_supported (GDBusAuthMechanism *mechanism);
40 static gchar *mechanism_encode_data (GDBusAuthMechanism *mechanism,
41 const gchar *data,
42 gsize data_len,
43 gsize *out_data_len);
44 static gchar *mechanism_decode_data (GDBusAuthMechanism *mechanism,
45 const gchar *data,
46 gsize data_len,
47 gsize *out_data_len);
48 static GDBusAuthMechanismState mechanism_server_get_state (GDBusAuthMechanism *mechanism);
49 static void mechanism_server_initiate (GDBusAuthMechanism *mechanism,
50 const gchar *initial_response,
51 gsize initial_response_len);
52 static void mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
53 const gchar *data,
54 gsize data_len);
55 static gchar *mechanism_server_data_send (GDBusAuthMechanism *mechanism,
56 gsize *out_data_len);
57 static gchar *mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism);
58 static void mechanism_server_shutdown (GDBusAuthMechanism *mechanism);
59 static GDBusAuthMechanismState mechanism_client_get_state (GDBusAuthMechanism *mechanism);
60 static gchar *mechanism_client_initiate (GDBusAuthMechanism *mechanism,
61 gsize *out_initial_response_len);
62 static void mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
63 const gchar *data,
64 gsize data_len);
65 static gchar *mechanism_client_data_send (GDBusAuthMechanism *mechanism,
66 gsize *out_data_len);
67 static void mechanism_client_shutdown (GDBusAuthMechanism *mechanism);
68
69 /* ---------------------------------------------------------------------------------------------------- */
70
G_DEFINE_TYPE_WITH_PRIVATE(GDBusAuthMechanismAnon,_g_dbus_auth_mechanism_anon,G_TYPE_DBUS_AUTH_MECHANISM)71 G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuthMechanismAnon, _g_dbus_auth_mechanism_anon, G_TYPE_DBUS_AUTH_MECHANISM)
72
73 /* ---------------------------------------------------------------------------------------------------- */
74
75 static void
76 _g_dbus_auth_mechanism_anon_finalize (GObject *object)
77 {
78 //GDBusAuthMechanismAnon *mechanism = G_DBUS_AUTH_MECHANISM_ANON (object);
79
80 if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_anon_parent_class)->finalize != NULL)
81 G_OBJECT_CLASS (_g_dbus_auth_mechanism_anon_parent_class)->finalize (object);
82 }
83
84 static void
_g_dbus_auth_mechanism_anon_class_init(GDBusAuthMechanismAnonClass * klass)85 _g_dbus_auth_mechanism_anon_class_init (GDBusAuthMechanismAnonClass *klass)
86 {
87 GObjectClass *gobject_class;
88 GDBusAuthMechanismClass *mechanism_class;
89
90 gobject_class = G_OBJECT_CLASS (klass);
91 gobject_class->finalize = _g_dbus_auth_mechanism_anon_finalize;
92
93 mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass);
94 mechanism_class->get_priority = mechanism_get_priority;
95 mechanism_class->get_name = mechanism_get_name;
96 mechanism_class->is_supported = mechanism_is_supported;
97 mechanism_class->encode_data = mechanism_encode_data;
98 mechanism_class->decode_data = mechanism_decode_data;
99 mechanism_class->server_get_state = mechanism_server_get_state;
100 mechanism_class->server_initiate = mechanism_server_initiate;
101 mechanism_class->server_data_receive = mechanism_server_data_receive;
102 mechanism_class->server_data_send = mechanism_server_data_send;
103 mechanism_class->server_get_reject_reason = mechanism_server_get_reject_reason;
104 mechanism_class->server_shutdown = mechanism_server_shutdown;
105 mechanism_class->client_get_state = mechanism_client_get_state;
106 mechanism_class->client_initiate = mechanism_client_initiate;
107 mechanism_class->client_data_receive = mechanism_client_data_receive;
108 mechanism_class->client_data_send = mechanism_client_data_send;
109 mechanism_class->client_shutdown = mechanism_client_shutdown;
110 }
111
112 static void
_g_dbus_auth_mechanism_anon_init(GDBusAuthMechanismAnon * mechanism)113 _g_dbus_auth_mechanism_anon_init (GDBusAuthMechanismAnon *mechanism)
114 {
115 mechanism->priv = _g_dbus_auth_mechanism_anon_get_instance_private (mechanism);
116 }
117
118 /* ---------------------------------------------------------------------------------------------------- */
119
120
121 static gint
mechanism_get_priority(void)122 mechanism_get_priority (void)
123 {
124 /* We prefer ANONYMOUS to most other mechanism (such as DBUS_COOKIE_SHA1) but not to EXTERNAL */
125 return 50;
126 }
127
128
129 static const gchar *
mechanism_get_name(void)130 mechanism_get_name (void)
131 {
132 return "ANONYMOUS";
133 }
134
135 static gboolean
mechanism_is_supported(GDBusAuthMechanism * mechanism)136 mechanism_is_supported (GDBusAuthMechanism *mechanism)
137 {
138 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), FALSE);
139 return TRUE;
140 }
141
142 static gchar *
mechanism_encode_data(GDBusAuthMechanism * mechanism,const gchar * data,gsize data_len,gsize * out_data_len)143 mechanism_encode_data (GDBusAuthMechanism *mechanism,
144 const gchar *data,
145 gsize data_len,
146 gsize *out_data_len)
147 {
148 return NULL;
149 }
150
151
152 static gchar *
mechanism_decode_data(GDBusAuthMechanism * mechanism,const gchar * data,gsize data_len,gsize * out_data_len)153 mechanism_decode_data (GDBusAuthMechanism *mechanism,
154 const gchar *data,
155 gsize data_len,
156 gsize *out_data_len)
157 {
158 return NULL;
159 }
160
161 /* ---------------------------------------------------------------------------------------------------- */
162
163 static GDBusAuthMechanismState
mechanism_server_get_state(GDBusAuthMechanism * mechanism)164 mechanism_server_get_state (GDBusAuthMechanism *mechanism)
165 {
166 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
167
168 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
169 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID);
170
171 return m->priv->state;
172 }
173
174 static void
mechanism_server_initiate(GDBusAuthMechanism * mechanism,const gchar * initial_response,gsize initial_response_len)175 mechanism_server_initiate (GDBusAuthMechanism *mechanism,
176 const gchar *initial_response,
177 gsize initial_response_len)
178 {
179 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
180
181 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
182 g_return_if_fail (!m->priv->is_server && !m->priv->is_client);
183
184 //g_debug ("ANONYMOUS: initial_response was '%s'", initial_response);
185
186 m->priv->is_server = TRUE;
187 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
188 }
189
190 static void
mechanism_server_data_receive(GDBusAuthMechanism * mechanism,const gchar * data,gsize data_len)191 mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
192 const gchar *data,
193 gsize data_len)
194 {
195 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
196
197 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
198 g_return_if_fail (m->priv->is_server && !m->priv->is_client);
199 g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
200
201 /* can never end up here because we are never in the WAITING_FOR_DATA state */
202 g_assert_not_reached ();
203 }
204
205 static gchar *
mechanism_server_data_send(GDBusAuthMechanism * mechanism,gsize * out_data_len)206 mechanism_server_data_send (GDBusAuthMechanism *mechanism,
207 gsize *out_data_len)
208 {
209 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
210
211 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL);
212 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
213 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
214
215 /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */
216 g_assert_not_reached ();
217
218 return NULL;
219 }
220
221 static gchar *
mechanism_server_get_reject_reason(GDBusAuthMechanism * mechanism)222 mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism)
223 {
224 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
225
226 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL);
227 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
228 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL);
229
230 /* can never end up here because we are never in the REJECTED state */
231 g_assert_not_reached ();
232
233 return NULL;
234 }
235
236 static void
mechanism_server_shutdown(GDBusAuthMechanism * mechanism)237 mechanism_server_shutdown (GDBusAuthMechanism *mechanism)
238 {
239 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
240
241 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
242 g_return_if_fail (m->priv->is_server && !m->priv->is_client);
243
244 m->priv->is_server = FALSE;
245 }
246
247 /* ---------------------------------------------------------------------------------------------------- */
248
249 static GDBusAuthMechanismState
mechanism_client_get_state(GDBusAuthMechanism * mechanism)250 mechanism_client_get_state (GDBusAuthMechanism *mechanism)
251 {
252 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
253
254 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
255 g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID);
256
257 return m->priv->state;
258 }
259
260 static gchar *
mechanism_client_initiate(GDBusAuthMechanism * mechanism,gsize * out_initial_response_len)261 mechanism_client_initiate (GDBusAuthMechanism *mechanism,
262 gsize *out_initial_response_len)
263 {
264 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
265 gchar *result;
266
267 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL);
268 g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL);
269
270 m->priv->is_client = TRUE;
271 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
272
273 /* just return our library name and version */
274 result = g_strdup ("GDBus 0.1");
275 *out_initial_response_len = strlen (result);
276
277 return result;
278 }
279
280 static void
mechanism_client_data_receive(GDBusAuthMechanism * mechanism,const gchar * data,gsize data_len)281 mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
282 const gchar *data,
283 gsize data_len)
284 {
285 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
286
287 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
288 g_return_if_fail (m->priv->is_client && !m->priv->is_server);
289 g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
290
291 /* can never end up here because we are never in the WAITING_FOR_DATA state */
292 g_assert_not_reached ();
293 }
294
295 static gchar *
mechanism_client_data_send(GDBusAuthMechanism * mechanism,gsize * out_data_len)296 mechanism_client_data_send (GDBusAuthMechanism *mechanism,
297 gsize *out_data_len)
298 {
299 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
300
301 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism), NULL);
302 g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL);
303 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
304
305 /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */
306 g_assert_not_reached ();
307
308 return NULL;
309 }
310
311 static void
mechanism_client_shutdown(GDBusAuthMechanism * mechanism)312 mechanism_client_shutdown (GDBusAuthMechanism *mechanism)
313 {
314 GDBusAuthMechanismAnon *m = G_DBUS_AUTH_MECHANISM_ANON (mechanism);
315
316 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_ANON (mechanism));
317 g_return_if_fail (m->priv->is_client && !m->priv->is_server);
318
319 m->priv->is_client = FALSE;
320 }
321
322 /* ---------------------------------------------------------------------------------------------------- */
323