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>
32 #include <dbus/dbus-glib-lowlevel.h>
36 #include <sys/types.h>
42 DBusServer *normal_server;
43 DBusServer *anon_allowed_server;
44 DBusServer *anon_only_server;
45 DBusServer *anon_mech_only_server;
46 DBusServer *anon_disallowed_server;
47 DBusServer *permissive_server;
48 DBusServer *unhappy_server;
49 DBusServer *same_uid_server;
50 DBusServer *same_uid_or_anon_server;
53 static void oom (void) G_GNUC_NORETURN;
57 g_error ("out of memory");
61 assert_no_error (const DBusError *e)
63 if (G_UNLIKELY (dbus_error_is_set (e)))
64 g_error ("expected success but got error: %s: %s", e->name, e->message);
67 static DBusHandlerResult
68 server_message_cb (DBusConnection *conn,
72 if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
74 dbus_connection_unref (conn);
76 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
79 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
81 DBusMessage *reply = dbus_message_new_method_return (message);
82 const char *hello = "Hello, world!";
86 if (dbus_connection_get_unix_user (conn, &uid))
88 g_message ("message from uid %lu", uid);
90 else if (dbus_connection_get_windows_user (conn, &sid))
95 g_message ("message from sid \"%s\"", sid);
98 else if (dbus_connection_get_is_anonymous (conn))
100 g_message ("message from Anonymous");
104 g_message ("message from ... someone?");
110 if (!dbus_message_append_args (reply,
111 DBUS_TYPE_STRING, &hello,
115 if (!dbus_connection_send (conn, reply, NULL))
118 dbus_message_unref (reply);
120 return DBUS_HANDLER_RESULT_HANDLED;
123 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
127 permissive_unix_func (DBusConnection *conn,
131 g_message ("accepting Unix user %lu", uid);
136 permissive_win_func (DBusConnection *conn,
140 g_message ("accepting Windows user \"%s\"", sid);
145 broken_unix_func (DBusConnection *conn,
149 g_error ("libdbus called the Unix user function for an ANONYMOUS-only "
155 broken_win_func (DBusConnection *conn,
159 g_error ("libdbus called the Windows user function for an ANONYMOUS-only "
165 unhappy_unix_func (DBusConnection *conn,
169 g_message ("rejecting Unix user %lu", uid);
174 unhappy_win_func (DBusConnection *conn,
178 g_message ("rejecting Windows user \"%s\"", sid);
183 same_uid_unix_func (DBusConnection *conn,
187 g_message ("checking whether Unix user %lu owns this process", uid);
188 /* I'd use _dbus_unix_user_is_process_owner(), but it's private... */
190 return (geteuid () == uid);
197 same_uid_win_func (DBusConnection *conn,
201 g_message ("checking whether Windows user \"%s\" owns this process", sid);
202 g_message ("Stub implementation consistent with dbus-sysdeps-util-win: "
208 new_conn_cb (DBusServer *server,
209 DBusConnection *conn,
214 dbus_connection_ref (conn);
215 dbus_connection_setup_with_g_main (conn, NULL);
217 if (!dbus_connection_add_filter (conn, server_message_cb, f, NULL))
220 if (server == f->normal_server)
223 else if (server == f->anon_allowed_server)
225 dbus_connection_set_allow_anonymous (conn, TRUE);
227 else if (server == f->anon_only_server)
229 dbus_connection_set_allow_anonymous (conn, TRUE);
231 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
233 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
236 else if (server == f->anon_mech_only_server)
238 dbus_connection_set_allow_anonymous (conn, TRUE);
240 /* should never get called */
241 dbus_connection_set_unix_user_function (conn, broken_unix_func,
243 dbus_connection_set_windows_user_function (conn, broken_win_func,
246 else if (server == f->anon_disallowed_server)
248 dbus_connection_set_allow_anonymous (conn, FALSE);
250 /* should never get called */
251 dbus_connection_set_unix_user_function (conn, broken_unix_func,
253 dbus_connection_set_windows_user_function (conn, broken_win_func,
256 else if (server == f->permissive_server)
258 dbus_connection_set_unix_user_function (conn, permissive_unix_func,
260 dbus_connection_set_windows_user_function (conn, permissive_win_func,
263 else if (server == f->unhappy_server)
265 dbus_connection_set_unix_user_function (conn, unhappy_unix_func,
267 dbus_connection_set_windows_user_function (conn, unhappy_win_func,
270 else if (server == f->same_uid_server)
272 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
274 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
277 else if (server == f->same_uid_or_anon_server)
279 dbus_connection_set_allow_anonymous (conn, TRUE);
281 dbus_connection_set_unix_user_function (conn, same_uid_unix_func,
283 dbus_connection_set_windows_user_function (conn, same_uid_win_func,
288 g_assert_not_reached ();
294 const gchar *listen_addr)
296 const char *only_anon[] = { "ANONYMOUS", NULL };
299 f->normal_server = dbus_server_listen (listen_addr, &f->e);
300 assert_no_error (&f->e);
301 g_assert (f->normal_server != NULL);
302 dbus_server_set_new_connection_function (f->normal_server,
303 new_conn_cb, f, NULL);
304 dbus_server_setup_with_g_main (f->normal_server, NULL);
305 connect_addr = dbus_server_get_address (f->normal_server);
306 g_message ("Normal server:\n%s", connect_addr);
307 dbus_free (connect_addr);
309 f->anon_allowed_server = dbus_server_listen (listen_addr, &f->e);
310 assert_no_error (&f->e);
311 g_assert (f->anon_allowed_server != NULL);
312 dbus_server_set_new_connection_function (f->anon_allowed_server,
313 new_conn_cb, f, NULL);
314 dbus_server_setup_with_g_main (f->anon_allowed_server, NULL);
315 connect_addr = dbus_server_get_address (f->anon_allowed_server);
316 g_message ("Anonymous-allowed server:\n%s", connect_addr);
317 dbus_free (connect_addr);
319 f->anon_only_server = dbus_server_listen (listen_addr, &f->e);
320 assert_no_error (&f->e);
321 g_assert (f->anon_only_server != NULL);
322 dbus_server_set_new_connection_function (f->anon_only_server,
323 new_conn_cb, f, NULL);
324 dbus_server_setup_with_g_main (f->anon_only_server, NULL);
325 connect_addr = dbus_server_get_address (f->anon_only_server);
326 g_message ("Anonymous-only server:\n%s", connect_addr);
327 dbus_free (connect_addr);
329 f->anon_mech_only_server = dbus_server_listen (listen_addr, &f->e);
330 assert_no_error (&f->e);
331 g_assert (f->anon_mech_only_server != NULL);
332 dbus_server_set_auth_mechanisms (f->anon_mech_only_server, only_anon);
333 dbus_server_set_new_connection_function (f->anon_mech_only_server,
334 new_conn_cb, f, NULL);
335 dbus_server_setup_with_g_main (f->anon_mech_only_server, NULL);
336 connect_addr = dbus_server_get_address (f->anon_mech_only_server);
337 g_message ("Anon mech only server:\n%s", connect_addr);
338 dbus_free (connect_addr);
340 f->anon_disallowed_server = dbus_server_listen (listen_addr, &f->e);
341 assert_no_error (&f->e);
342 g_assert (f->anon_disallowed_server != NULL);
343 dbus_server_set_auth_mechanisms (f->anon_disallowed_server, only_anon);
344 dbus_server_set_new_connection_function (f->anon_disallowed_server,
345 new_conn_cb, f, NULL);
346 dbus_server_setup_with_g_main (f->anon_disallowed_server, NULL);
347 connect_addr = dbus_server_get_address (f->anon_disallowed_server);
348 g_message ("Anonymous-disallowed server:\n%s", connect_addr);
349 dbus_free (connect_addr);
351 f->permissive_server = dbus_server_listen (listen_addr, &f->e);
352 assert_no_error (&f->e);
353 g_assert (f->permissive_server != NULL);
354 dbus_server_set_new_connection_function (f->permissive_server,
355 new_conn_cb, f, NULL);
356 dbus_server_setup_with_g_main (f->permissive_server, NULL);
357 connect_addr = dbus_server_get_address (f->permissive_server);
358 g_message ("Permissive server:\n%s", connect_addr);
359 dbus_free (connect_addr);
361 f->unhappy_server = dbus_server_listen (listen_addr, &f->e);
362 assert_no_error (&f->e);
363 g_assert (f->unhappy_server != NULL);
364 dbus_server_set_new_connection_function (f->unhappy_server,
365 new_conn_cb, f, NULL);
366 dbus_server_setup_with_g_main (f->unhappy_server, NULL);
367 connect_addr = dbus_server_get_address (f->unhappy_server);
368 g_message ("Unhappy server:\n%s", connect_addr);
369 dbus_free (connect_addr);
371 f->same_uid_server = dbus_server_listen (listen_addr, &f->e);
372 assert_no_error (&f->e);
373 g_assert (f->same_uid_server != NULL);
374 dbus_server_set_new_connection_function (f->same_uid_server,
375 new_conn_cb, f, NULL);
376 dbus_server_setup_with_g_main (f->same_uid_server, NULL);
377 connect_addr = dbus_server_get_address (f->same_uid_server);
378 g_message ("Same-UID server:\n%s", connect_addr);
379 dbus_free (connect_addr);
381 f->same_uid_or_anon_server = dbus_server_listen (listen_addr, &f->e);
382 assert_no_error (&f->e);
383 g_assert (f->same_uid_or_anon_server != NULL);
384 dbus_server_set_new_connection_function (f->same_uid_or_anon_server,
385 new_conn_cb, f, NULL);
386 dbus_server_setup_with_g_main (f->same_uid_or_anon_server, NULL);
387 connect_addr = dbus_server_get_address (f->same_uid_or_anon_server);
388 g_message ("Same-UID-or-anon server:\n%s", connect_addr);
389 dbus_free (connect_addr);
396 Fixture f = { DBUS_ERROR_INIT };
401 setup (&f, "tcp:host=127.0.0.1");
404 g_main_context_iteration (NULL, TRUE);