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>
36 #include <sys/types.h>
39 #include "test-utils.h"
45 DBusServer *normal_server;
46 DBusServer *anon_allowed_server;
47 DBusServer *anon_only_server;
48 DBusServer *anon_mech_only_server;
49 DBusServer *anon_disallowed_server;
50 DBusServer *permissive_server;
51 DBusServer *unhappy_server;
52 DBusServer *same_uid_server;
53 DBusServer *same_uid_or_anon_server;
56 static void oom (void) G_GNUC_NORETURN;
60 g_error ("out of memory");
65 assert_no_error (const DBusError *e)
67 if (G_UNLIKELY (dbus_error_is_set (e)))
68 g_error ("expected success but got error: %s: %s", e->name, e->message);
71 static DBusHandlerResult
72 server_message_cb (DBusConnection *conn,
76 if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
78 dbus_connection_unref (conn);
80 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
83 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
85 DBusMessage *reply = dbus_message_new_method_return (message);
86 const char *hello = "Hello, world!";
90 if (dbus_connection_get_unix_user (conn, &uid))
92 g_message ("message from uid %lu", uid);
94 else if (dbus_connection_get_windows_user (conn, &sid))
99 g_message ("message from sid \"%s\"", sid);
102 else if (dbus_connection_get_is_anonymous (conn))
104 g_message ("message from Anonymous");
108 g_message ("message from ... someone?");
114 if (!dbus_message_append_args (reply,
115 DBUS_TYPE_STRING, &hello,
119 if (!dbus_connection_send (conn, reply, NULL))
122 dbus_message_unref (reply);
124 return DBUS_HANDLER_RESULT_HANDLED;
127 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
131 permissive_unix_func (DBusConnection *conn,
135 g_message ("accepting Unix user %lu", uid);
140 permissive_win_func (DBusConnection *conn,
144 g_message ("accepting Windows user \"%s\"", sid);
149 broken_unix_func (DBusConnection *conn,
153 g_error ("libdbus called the Unix user function for an ANONYMOUS-only "
159 broken_win_func (DBusConnection *conn,
163 g_error ("libdbus called the Windows user function for an ANONYMOUS-only "
169 unhappy_unix_func (DBusConnection *conn,
173 g_message ("rejecting Unix user %lu", uid);
178 unhappy_win_func (DBusConnection *conn,
182 g_message ("rejecting Windows user \"%s\"", sid);
187 same_uid_unix_func (DBusConnection *conn,
191 g_message ("checking whether Unix user %lu owns this process", uid);
192 /* I'd use _dbus_unix_user_is_process_owner(), but it's private... */
194 return (geteuid () == uid);
201 same_uid_win_func (DBusConnection *conn,
205 g_message ("checking whether Windows user \"%s\" owns this process", sid);
206 g_message ("Stub implementation consistent with dbus-sysdeps-util-win: "
212 new_conn_cb (DBusServer *server,
213 DBusConnection *conn,
218 dbus_connection_ref (conn);
219 test_connection_setup (f->ctx, conn);
221 if (!dbus_connection_add_filter (conn, server_message_cb, f, NULL))
224 if (server == f->normal_server)
227 else if (server == f->anon_allowed_server)
229 dbus_connection_set_allow_anonymous (conn, TRUE);
231 else if (server == f->anon_only_server)
233 dbus_connection_set_allow_anonymous (conn, TRUE);
235 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
237 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
240 else if (server == f->anon_mech_only_server)
242 dbus_connection_set_allow_anonymous (conn, TRUE);
244 /* should never get called */
245 dbus_connection_set_unix_user_function (conn, broken_unix_func,
247 dbus_connection_set_windows_user_function (conn, broken_win_func,
250 else if (server == f->anon_disallowed_server)
252 dbus_connection_set_allow_anonymous (conn, FALSE);
254 /* should never get called */
255 dbus_connection_set_unix_user_function (conn, broken_unix_func,
257 dbus_connection_set_windows_user_function (conn, broken_win_func,
260 else if (server == f->permissive_server)
262 dbus_connection_set_unix_user_function (conn, permissive_unix_func,
264 dbus_connection_set_windows_user_function (conn, permissive_win_func,
267 else if (server == f->unhappy_server)
269 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
271 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
274 else if (server == f->same_uid_server)
276 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
278 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
281 else if (server == f->same_uid_or_anon_server)
283 dbus_connection_set_allow_anonymous (conn, TRUE);
285 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
287 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
292 g_assert_not_reached ();
298 const gchar *listen_addr)
300 const char *only_anon[] = { "ANONYMOUS", NULL };
303 f->normal_server = dbus_server_listen (listen_addr, &f->e);
304 assert_no_error (&f->e);
305 g_assert (f->normal_server != NULL);
306 dbus_server_set_new_connection_function (f->normal_server,
307 new_conn_cb, f, NULL);
308 test_server_setup (f->ctx, f->normal_server);
309 connect_addr = dbus_server_get_address (f->normal_server);
310 g_message ("Normal server:\n%s", connect_addr);
311 dbus_free (connect_addr);
313 f->anon_allowed_server = dbus_server_listen (listen_addr, &f->e);
314 assert_no_error (&f->e);
315 g_assert (f->anon_allowed_server != NULL);
316 dbus_server_set_new_connection_function (f->anon_allowed_server,
317 new_conn_cb, f, NULL);
318 test_server_setup (f->ctx, f->anon_allowed_server);
319 connect_addr = dbus_server_get_address (f->anon_allowed_server);
320 g_message ("Anonymous-allowed server:\n%s", connect_addr);
321 dbus_free (connect_addr);
323 f->anon_only_server = dbus_server_listen (listen_addr, &f->e);
324 assert_no_error (&f->e);
325 g_assert (f->anon_only_server != NULL);
326 dbus_server_set_new_connection_function (f->anon_only_server,
327 new_conn_cb, f, NULL);
328 test_server_setup (f->ctx, f->anon_only_server);
329 connect_addr = dbus_server_get_address (f->anon_only_server);
330 g_message ("Anonymous-only server:\n%s", connect_addr);
331 dbus_free (connect_addr);
333 f->anon_mech_only_server = dbus_server_listen (listen_addr, &f->e);
334 assert_no_error (&f->e);
335 g_assert (f->anon_mech_only_server != NULL);
336 dbus_server_set_auth_mechanisms (f->anon_mech_only_server, only_anon);
337 dbus_server_set_new_connection_function (f->anon_mech_only_server,
338 new_conn_cb, f, NULL);
339 test_server_setup (f->ctx, f->anon_mech_only_server);
340 connect_addr = dbus_server_get_address (f->anon_mech_only_server);
341 g_message ("Anon mech only server:\n%s", connect_addr);
342 dbus_free (connect_addr);
344 f->anon_disallowed_server = dbus_server_listen (listen_addr, &f->e);
345 assert_no_error (&f->e);
346 g_assert (f->anon_disallowed_server != NULL);
347 dbus_server_set_auth_mechanisms (f->anon_disallowed_server, only_anon);
348 dbus_server_set_new_connection_function (f->anon_disallowed_server,
349 new_conn_cb, f, NULL);
350 test_server_setup (f->ctx, f->anon_disallowed_server);
351 connect_addr = dbus_server_get_address (f->anon_disallowed_server);
352 g_message ("Anonymous-disallowed server:\n%s", connect_addr);
353 dbus_free (connect_addr);
355 f->permissive_server = dbus_server_listen (listen_addr, &f->e);
356 assert_no_error (&f->e);
357 g_assert (f->permissive_server != NULL);
358 dbus_server_set_new_connection_function (f->permissive_server,
359 new_conn_cb, f, NULL);
360 test_server_setup (f->ctx, f->permissive_server);
361 connect_addr = dbus_server_get_address (f->permissive_server);
362 g_message ("Permissive server:\n%s", connect_addr);
363 dbus_free (connect_addr);
365 f->unhappy_server = dbus_server_listen (listen_addr, &f->e);
366 assert_no_error (&f->e);
367 g_assert (f->unhappy_server != NULL);
368 dbus_server_set_new_connection_function (f->unhappy_server,
369 new_conn_cb, f, NULL);
370 test_server_setup (f->ctx, f->unhappy_server);
371 connect_addr = dbus_server_get_address (f->unhappy_server);
372 g_message ("Unhappy server:\n%s", connect_addr);
373 dbus_free (connect_addr);
375 f->same_uid_server = dbus_server_listen (listen_addr, &f->e);
376 assert_no_error (&f->e);
377 g_assert (f->same_uid_server != NULL);
378 dbus_server_set_new_connection_function (f->same_uid_server,
379 new_conn_cb, f, NULL);
380 test_server_setup (f->ctx, f->same_uid_server);
381 connect_addr = dbus_server_get_address (f->same_uid_server);
382 g_message ("Same-UID server:\n%s", connect_addr);
383 dbus_free (connect_addr);
385 f->same_uid_or_anon_server = dbus_server_listen (listen_addr, &f->e);
386 assert_no_error (&f->e);
387 g_assert (f->same_uid_or_anon_server != NULL);
388 dbus_server_set_new_connection_function (f->same_uid_or_anon_server,
389 new_conn_cb, f, NULL);
390 test_server_setup (f->ctx, f->same_uid_or_anon_server);
391 connect_addr = dbus_server_get_address (f->same_uid_or_anon_server);
392 g_message ("Same-UID-or-anon server:\n%s", connect_addr);
393 dbus_free (connect_addr);
400 Fixture f = { DBUS_ERROR_INIT, test_main_context_get () };
405 setup (&f, "tcp:host=127.0.0.1");
408 test_main_context_iterate (f.ctx, TRUE);