1 /* Simple sanity-check for authentication and authorization.
3 * Copyright © 2010-2011 Nokia Corporation
4 * Copyright © 2012 Collabora Ltd.
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction,
9 * including without limitation the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 #include <dbus/dbus.h>
35 #include <sys/types.h>
38 #include "test-utils.h"
44 DBusServer *normal_server;
45 DBusServer *anon_allowed_server;
46 DBusServer *anon_only_server;
47 DBusServer *anon_mech_only_server;
48 DBusServer *anon_disallowed_server;
49 DBusServer *permissive_server;
50 DBusServer *unhappy_server;
51 DBusServer *same_uid_server;
52 DBusServer *same_uid_or_anon_server;
55 static void oom (void) G_GNUC_NORETURN;
59 g_error ("out of memory");
63 assert_no_error (const DBusError *e)
65 if (G_UNLIKELY (dbus_error_is_set (e)))
66 g_error ("expected success but got error: %s: %s", e->name, e->message);
69 static DBusHandlerResult
70 server_message_cb (DBusConnection *conn,
74 if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
76 dbus_connection_unref (conn);
78 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
81 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
83 DBusMessage *reply = dbus_message_new_method_return (message);
84 const char *hello = "Hello, world!";
88 if (dbus_connection_get_unix_user (conn, &uid))
90 g_message ("message from uid %lu", uid);
92 else if (dbus_connection_get_windows_user (conn, &sid))
97 g_message ("message from sid \"%s\"", sid);
100 else if (dbus_connection_get_is_anonymous (conn))
102 g_message ("message from Anonymous");
106 g_message ("message from ... someone?");
112 if (!dbus_message_append_args (reply,
113 DBUS_TYPE_STRING, &hello,
117 if (!dbus_connection_send (conn, reply, NULL))
120 dbus_message_unref (reply);
122 return DBUS_HANDLER_RESULT_HANDLED;
125 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
129 permissive_unix_func (DBusConnection *conn,
133 g_message ("accepting Unix user %lu", uid);
138 permissive_win_func (DBusConnection *conn,
142 g_message ("accepting Windows user \"%s\"", sid);
147 broken_unix_func (DBusConnection *conn,
151 g_error ("libdbus called the Unix user function for an ANONYMOUS-only "
157 broken_win_func (DBusConnection *conn,
161 g_error ("libdbus called the Windows user function for an ANONYMOUS-only "
167 unhappy_unix_func (DBusConnection *conn,
171 g_message ("rejecting Unix user %lu", uid);
176 unhappy_win_func (DBusConnection *conn,
180 g_message ("rejecting Windows user \"%s\"", sid);
185 same_uid_unix_func (DBusConnection *conn,
189 g_message ("checking whether Unix user %lu owns this process", uid);
190 /* I'd use _dbus_unix_user_is_process_owner(), but it's private... */
192 return (geteuid () == uid);
199 same_uid_win_func (DBusConnection *conn,
203 g_message ("checking whether Windows user \"%s\" owns this process", sid);
204 g_message ("Stub implementation consistent with dbus-sysdeps-util-win: "
210 new_conn_cb (DBusServer *server,
211 DBusConnection *conn,
216 dbus_connection_ref (conn);
217 test_connection_setup (f->ctx, conn);
219 if (!dbus_connection_add_filter (conn, server_message_cb, f, NULL))
222 if (server == f->normal_server)
225 else if (server == f->anon_allowed_server)
227 dbus_connection_set_allow_anonymous (conn, TRUE);
229 else if (server == f->anon_only_server)
231 dbus_connection_set_allow_anonymous (conn, TRUE);
233 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
235 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
238 else if (server == f->anon_mech_only_server)
240 dbus_connection_set_allow_anonymous (conn, TRUE);
242 /* should never get called */
243 dbus_connection_set_unix_user_function (conn, broken_unix_func,
245 dbus_connection_set_windows_user_function (conn, broken_win_func,
248 else if (server == f->anon_disallowed_server)
250 dbus_connection_set_allow_anonymous (conn, FALSE);
252 /* should never get called */
253 dbus_connection_set_unix_user_function (conn, broken_unix_func,
255 dbus_connection_set_windows_user_function (conn, broken_win_func,
258 else if (server == f->permissive_server)
260 dbus_connection_set_unix_user_function (conn, permissive_unix_func,
262 dbus_connection_set_windows_user_function (conn, permissive_win_func,
265 else if (server == f->unhappy_server)
267 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
269 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
272 else if (server == f->same_uid_server)
274 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
276 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
279 else if (server == f->same_uid_or_anon_server)
281 dbus_connection_set_allow_anonymous (conn, TRUE);
283 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
285 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
290 g_assert_not_reached ();
296 const gchar *listen_addr)
298 const char *only_anon[] = { "ANONYMOUS", NULL };
301 f->normal_server = dbus_server_listen (listen_addr, &f->e);
302 assert_no_error (&f->e);
303 g_assert (f->normal_server != NULL);
304 dbus_server_set_new_connection_function (f->normal_server,
305 new_conn_cb, f, NULL);
306 test_server_setup (f->ctx, f->normal_server);
307 connect_addr = dbus_server_get_address (f->normal_server);
308 g_message ("Normal server:\n%s", connect_addr);
309 dbus_free (connect_addr);
311 f->anon_allowed_server = dbus_server_listen (listen_addr, &f->e);
312 assert_no_error (&f->e);
313 g_assert (f->anon_allowed_server != NULL);
314 dbus_server_set_new_connection_function (f->anon_allowed_server,
315 new_conn_cb, f, NULL);
316 test_server_setup (f->ctx, f->anon_allowed_server);
317 connect_addr = dbus_server_get_address (f->anon_allowed_server);
318 g_message ("Anonymous-allowed server:\n%s", connect_addr);
319 dbus_free (connect_addr);
321 f->anon_only_server = dbus_server_listen (listen_addr, &f->e);
322 assert_no_error (&f->e);
323 g_assert (f->anon_only_server != NULL);
324 dbus_server_set_new_connection_function (f->anon_only_server,
325 new_conn_cb, f, NULL);
326 test_server_setup (f->ctx, f->anon_only_server);
327 connect_addr = dbus_server_get_address (f->anon_only_server);
328 g_message ("Anonymous-only server:\n%s", connect_addr);
329 dbus_free (connect_addr);
331 f->anon_mech_only_server = dbus_server_listen (listen_addr, &f->e);
332 assert_no_error (&f->e);
333 g_assert (f->anon_mech_only_server != NULL);
334 dbus_server_set_auth_mechanisms (f->anon_mech_only_server, only_anon);
335 dbus_server_set_new_connection_function (f->anon_mech_only_server,
336 new_conn_cb, f, NULL);
337 test_server_setup (f->ctx, f->anon_mech_only_server);
338 connect_addr = dbus_server_get_address (f->anon_mech_only_server);
339 g_message ("Anon mech only server:\n%s", connect_addr);
340 dbus_free (connect_addr);
342 f->anon_disallowed_server = dbus_server_listen (listen_addr, &f->e);
343 assert_no_error (&f->e);
344 g_assert (f->anon_disallowed_server != NULL);
345 dbus_server_set_auth_mechanisms (f->anon_disallowed_server, only_anon);
346 dbus_server_set_new_connection_function (f->anon_disallowed_server,
347 new_conn_cb, f, NULL);
348 test_server_setup (f->ctx, f->anon_disallowed_server);
349 connect_addr = dbus_server_get_address (f->anon_disallowed_server);
350 g_message ("Anonymous-disallowed server:\n%s", connect_addr);
351 dbus_free (connect_addr);
353 f->permissive_server = dbus_server_listen (listen_addr, &f->e);
354 assert_no_error (&f->e);
355 g_assert (f->permissive_server != NULL);
356 dbus_server_set_new_connection_function (f->permissive_server,
357 new_conn_cb, f, NULL);
358 test_server_setup (f->ctx, f->permissive_server);
359 connect_addr = dbus_server_get_address (f->permissive_server);
360 g_message ("Permissive server:\n%s", connect_addr);
361 dbus_free (connect_addr);
363 f->unhappy_server = dbus_server_listen (listen_addr, &f->e);
364 assert_no_error (&f->e);
365 g_assert (f->unhappy_server != NULL);
366 dbus_server_set_new_connection_function (f->unhappy_server,
367 new_conn_cb, f, NULL);
368 test_server_setup (f->ctx, f->unhappy_server);
369 connect_addr = dbus_server_get_address (f->unhappy_server);
370 g_message ("Unhappy server:\n%s", connect_addr);
371 dbus_free (connect_addr);
373 f->same_uid_server = dbus_server_listen (listen_addr, &f->e);
374 assert_no_error (&f->e);
375 g_assert (f->same_uid_server != NULL);
376 dbus_server_set_new_connection_function (f->same_uid_server,
377 new_conn_cb, f, NULL);
378 test_server_setup (f->ctx, f->same_uid_server);
379 connect_addr = dbus_server_get_address (f->same_uid_server);
380 g_message ("Same-UID server:\n%s", connect_addr);
381 dbus_free (connect_addr);
383 f->same_uid_or_anon_server = dbus_server_listen (listen_addr, &f->e);
384 assert_no_error (&f->e);
385 g_assert (f->same_uid_or_anon_server != NULL);
386 dbus_server_set_new_connection_function (f->same_uid_or_anon_server,
387 new_conn_cb, f, NULL);
388 test_server_setup (f->ctx, f->same_uid_or_anon_server);
389 connect_addr = dbus_server_get_address (f->same_uid_or_anon_server);
390 g_message ("Same-UID-or-anon server:\n%s", connect_addr);
391 dbus_free (connect_addr);
398 Fixture f = { DBUS_ERROR_INIT, test_main_context_get () };
403 setup (&f, "tcp:host=127.0.0.1");
406 test_main_context_iterate (f.ctx, TRUE);