nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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 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 <string.h>
24  
25 #include "gdbusauthmechanismexternal.h"
26 #include "gcredentials.h"
27 #include "gdbuserror.h"
28 #include "gioenumtypes.h"
29  
30 #include "glibintl.h"
31  
32 struct _GDBusAuthMechanismExternalPrivate
33 {
34 gboolean is_client;
35 gboolean is_server;
36 GDBusAuthMechanismState state;
37 };
38  
39 static gint mechanism_get_priority (void);
40 static const gchar *mechanism_get_name (void);
41  
42 static gboolean mechanism_is_supported (GDBusAuthMechanism *mechanism);
43 static gchar *mechanism_encode_data (GDBusAuthMechanism *mechanism,
44 const gchar *data,
45 gsize data_len,
46 gsize *out_data_len);
47 static gchar *mechanism_decode_data (GDBusAuthMechanism *mechanism,
48 const gchar *data,
49 gsize data_len,
50 gsize *out_data_len);
51 static GDBusAuthMechanismState mechanism_server_get_state (GDBusAuthMechanism *mechanism);
52 static void mechanism_server_initiate (GDBusAuthMechanism *mechanism,
53 const gchar *initial_response,
54 gsize initial_response_len);
55 static void mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
56 const gchar *data,
57 gsize data_len);
58 static gchar *mechanism_server_data_send (GDBusAuthMechanism *mechanism,
59 gsize *out_data_len);
60 static gchar *mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism);
61 static void mechanism_server_shutdown (GDBusAuthMechanism *mechanism);
62 static GDBusAuthMechanismState mechanism_client_get_state (GDBusAuthMechanism *mechanism);
63 static gchar *mechanism_client_initiate (GDBusAuthMechanism *mechanism,
64 gsize *out_initial_response_len);
65 static void mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
66 const gchar *data,
67 gsize data_len);
68 static gchar *mechanism_client_data_send (GDBusAuthMechanism *mechanism,
69 gsize *out_data_len);
70 static void mechanism_client_shutdown (GDBusAuthMechanism *mechanism);
71  
72 /* ---------------------------------------------------------------------------------------------------- */
73  
74 G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuthMechanismExternal, _g_dbus_auth_mechanism_external, G_TYPE_DBUS_AUTH_MECHANISM)
75  
76 /* ---------------------------------------------------------------------------------------------------- */
77  
78 static void
79 _g_dbus_auth_mechanism_external_finalize (GObject *object)
80 {
81 //GDBusAuthMechanismExternal *mechanism = G_DBUS_AUTH_MECHANISM_EXTERNAL (object);
82  
83 if (G_OBJECT_CLASS (_g_dbus_auth_mechanism_external_parent_class)->finalize != NULL)
84 G_OBJECT_CLASS (_g_dbus_auth_mechanism_external_parent_class)->finalize (object);
85 }
86  
87 static void
88 _g_dbus_auth_mechanism_external_class_init (GDBusAuthMechanismExternalClass *klass)
89 {
90 GObjectClass *gobject_class;
91 GDBusAuthMechanismClass *mechanism_class;
92  
93 gobject_class = G_OBJECT_CLASS (klass);
94 gobject_class->finalize = _g_dbus_auth_mechanism_external_finalize;
95  
96 mechanism_class = G_DBUS_AUTH_MECHANISM_CLASS (klass);
97 mechanism_class->get_name = mechanism_get_name;
98 mechanism_class->get_priority = mechanism_get_priority;
99 mechanism_class->is_supported = mechanism_is_supported;
100 mechanism_class->encode_data = mechanism_encode_data;
101 mechanism_class->decode_data = mechanism_decode_data;
102 mechanism_class->server_get_state = mechanism_server_get_state;
103 mechanism_class->server_initiate = mechanism_server_initiate;
104 mechanism_class->server_data_receive = mechanism_server_data_receive;
105 mechanism_class->server_data_send = mechanism_server_data_send;
106 mechanism_class->server_get_reject_reason = mechanism_server_get_reject_reason;
107 mechanism_class->server_shutdown = mechanism_server_shutdown;
108 mechanism_class->client_get_state = mechanism_client_get_state;
109 mechanism_class->client_initiate = mechanism_client_initiate;
110 mechanism_class->client_data_receive = mechanism_client_data_receive;
111 mechanism_class->client_data_send = mechanism_client_data_send;
112 mechanism_class->client_shutdown = mechanism_client_shutdown;
113 }
114  
115 static void
116 _g_dbus_auth_mechanism_external_init (GDBusAuthMechanismExternal *mechanism)
117 {
118 mechanism->priv = _g_dbus_auth_mechanism_external_get_instance_private (mechanism);
119 }
120  
121 /* ---------------------------------------------------------------------------------------------------- */
122  
123 static gboolean
124 mechanism_is_supported (GDBusAuthMechanism *mechanism)
125 {
126 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), FALSE);
127 /* This mechanism is only available if credentials has been exchanged */
128 if (_g_dbus_auth_mechanism_get_credentials (mechanism) != NULL)
129 return TRUE;
130 else
131 return FALSE;
132 }
133  
134 static gint
135 mechanism_get_priority (void)
136 {
137 /* We prefer EXTERNAL to most other mechanism (DBUS_COOKIE_SHA1 and ANONYMOUS) */
138 return 100;
139 }
140  
141 static const gchar *
142 mechanism_get_name (void)
143 {
144 return "EXTERNAL";
145 }
146  
147 static gchar *
148 mechanism_encode_data (GDBusAuthMechanism *mechanism,
149 const gchar *data,
150 gsize data_len,
151 gsize *out_data_len)
152 {
153 return NULL;
154 }
155  
156  
157 static gchar *
158 mechanism_decode_data (GDBusAuthMechanism *mechanism,
159 const gchar *data,
160 gsize data_len,
161 gsize *out_data_len)
162 {
163 return NULL;
164 }
165  
166 /* ---------------------------------------------------------------------------------------------------- */
167  
168 static GDBusAuthMechanismState
169 mechanism_server_get_state (GDBusAuthMechanism *mechanism)
170 {
171 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
172  
173 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
174 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, G_DBUS_AUTH_MECHANISM_STATE_INVALID);
175  
176 return m->priv->state;
177 }
178  
179 static gboolean
180 data_matches_credentials (const gchar *data,
181 GCredentials *credentials)
182 {
183 gboolean match;
184  
185 match = FALSE;
186  
187 if (credentials == NULL)
188 goto out;
189  
190 if (data == NULL || strlen (data) == 0)
191 goto out;
192  
193 #if defined(G_OS_UNIX)
194 {
195 gint64 alleged_uid;
196 gchar *endp;
197  
198 /* on UNIX, this is the uid as a string in base 10 */
199 alleged_uid = g_ascii_strtoll (data, &endp, 10);
200 if (*endp == '\0')
201 {
202 if (g_credentials_get_unix_user (credentials, NULL) == alleged_uid)
203 {
204 match = TRUE;
205 }
206 }
207 }
208 #else
209 /* TODO: Dont know how to compare credentials on this OS. Please implement. */
210 #endif
211  
212 out:
213 return match;
214 }
215  
216 static void
217 mechanism_server_initiate (GDBusAuthMechanism *mechanism,
218 const gchar *initial_response,
219 gsize initial_response_len)
220 {
221 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
222  
223 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
224 g_return_if_fail (!m->priv->is_server && !m->priv->is_client);
225  
226 m->priv->is_server = TRUE;
227  
228 if (initial_response != NULL)
229 {
230 if (data_matches_credentials (initial_response, _g_dbus_auth_mechanism_get_credentials (mechanism)))
231 {
232 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
233 }
234 else
235 {
236 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
237 }
238 }
239 else
240 {
241 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA;
242 }
243 }
244  
245 static void
246 mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
247 const gchar *data,
248 gsize data_len)
249 {
250 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
251  
252 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
253 g_return_if_fail (m->priv->is_server && !m->priv->is_client);
254 g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
255  
256 if (data_matches_credentials (data, _g_dbus_auth_mechanism_get_credentials (mechanism)))
257 {
258 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
259 }
260 else
261 {
262 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
263 }
264 }
265  
266 static gchar *
267 mechanism_server_data_send (GDBusAuthMechanism *mechanism,
268 gsize *out_data_len)
269 {
270 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
271  
272 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
273 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
274 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
275  
276 /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */
277 g_assert_not_reached ();
278  
279 return NULL;
280 }
281  
282 static gchar *
283 mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism)
284 {
285 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
286  
287 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
288 g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
289 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL);
290  
291 /* can never end up here because we are never in the REJECTED state */
292 g_assert_not_reached ();
293  
294 return NULL;
295 }
296  
297 static void
298 mechanism_server_shutdown (GDBusAuthMechanism *mechanism)
299 {
300 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
301  
302 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
303 g_return_if_fail (m->priv->is_server && !m->priv->is_client);
304  
305 m->priv->is_server = FALSE;
306 }
307  
308 /* ---------------------------------------------------------------------------------------------------- */
309  
310 static GDBusAuthMechanismState
311 mechanism_client_get_state (GDBusAuthMechanism *mechanism)
312 {
313 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
314  
315 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), G_DBUS_AUTH_MECHANISM_STATE_INVALID);
316 g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, G_DBUS_AUTH_MECHANISM_STATE_INVALID);
317  
318 return m->priv->state;
319 }
320  
321 static gchar *
322 mechanism_client_initiate (GDBusAuthMechanism *mechanism,
323 gsize *out_initial_response_len)
324 {
325 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
326 gchar *initial_response = NULL;
327 GCredentials *credentials;
328  
329 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
330 g_return_val_if_fail (!m->priv->is_server && !m->priv->is_client, NULL);
331  
332 m->priv->is_client = TRUE;
333 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED;
334  
335 *out_initial_response_len = -1;
336  
337 credentials = _g_dbus_auth_mechanism_get_credentials (mechanism);
338 g_assert (credentials != NULL);
339  
340 /* return the uid */
341 #if defined(G_OS_UNIX)
342 initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) g_credentials_get_unix_user (credentials, NULL));
343 #elif defined(G_OS_WIN32)
344 #ifdef __GNUC__
345 #warning Dont know how to send credentials on this OS. The EXTERNAL D-Bus authentication mechanism will not work.
346 #endif
347 m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
348 #endif
349 return initial_response;
350 }
351  
352 static void
353 mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
354 const gchar *data,
355 gsize data_len)
356 {
357 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
358  
359 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
360 g_return_if_fail (m->priv->is_client && !m->priv->is_server);
361 g_return_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA);
362  
363 /* can never end up here because we are never in the WAITING_FOR_DATA state */
364 g_assert_not_reached ();
365 }
366  
367 static gchar *
368 mechanism_client_data_send (GDBusAuthMechanism *mechanism,
369 gsize *out_data_len)
370 {
371 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
372  
373 g_return_val_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism), NULL);
374 g_return_val_if_fail (m->priv->is_client && !m->priv->is_server, NULL);
375 g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND, NULL);
376  
377 /* can never end up here because we are never in the HAVE_DATA_TO_SEND state */
378 g_assert_not_reached ();
379  
380 return NULL;
381 }
382  
383 static void
384 mechanism_client_shutdown (GDBusAuthMechanism *mechanism)
385 {
386 GDBusAuthMechanismExternal *m = G_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism);
387  
388 g_return_if_fail (G_IS_DBUS_AUTH_MECHANISM_EXTERNAL (mechanism));
389 g_return_if_fail (m->priv->is_client && !m->priv->is_server);
390  
391 m->priv->is_client = FALSE;
392 }
393  
394 /* ---------------------------------------------------------------------------------------------------- */