nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GLib testing framework examples and tests |
2 | * |
||
3 | * Copyright (C) 2008-2013 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 <locale.h> |
||
22 | #include <gio/gio.h> |
||
23 | |||
24 | #include <string.h> |
||
25 | #include <unistd.h> |
||
26 | |||
27 | #include "gdbus-tests.h" |
||
28 | |||
29 | #ifdef G_OS_UNIX |
||
30 | #include <gio/gunixconnection.h> |
||
31 | #include <gio/gnetworkingprivate.h> |
||
32 | #include <gio/gunixsocketaddress.h> |
||
33 | #include <gio/gunixfdlist.h> |
||
34 | #endif |
||
35 | |||
36 | /* ---------------------------------------------------------------------------------------------------- */ |
||
37 | |||
38 | static gboolean |
||
39 | server_on_allow_mechanism (GDBusAuthObserver *observer, |
||
40 | const gchar *mechanism, |
||
41 | gpointer user_data) |
||
42 | { |
||
43 | const gchar *allowed_mechanism = user_data; |
||
44 | if (allowed_mechanism == NULL || g_strcmp0 (mechanism, allowed_mechanism) == 0) |
||
45 | return TRUE; |
||
46 | else |
||
47 | return FALSE; |
||
48 | } |
||
49 | |||
50 | /* pass NULL to allow any mechanism */ |
||
51 | static GDBusServer * |
||
52 | server_new_for_mechanism (const gchar *allowed_mechanism) |
||
53 | { |
||
54 | gchar *addr; |
||
55 | gchar *guid; |
||
56 | GDBusServer *server; |
||
57 | GDBusAuthObserver *auth_observer; |
||
58 | GError *error; |
||
59 | GDBusServerFlags flags; |
||
60 | |||
61 | guid = g_dbus_generate_guid (); |
||
62 | |||
63 | #ifdef G_OS_UNIX |
||
64 | if (g_unix_socket_address_abstract_names_supported ()) |
||
65 | { |
||
66 | addr = g_strdup ("unix:tmpdir=/tmp/gdbus-test-"); |
||
67 | } |
||
68 | else |
||
69 | { |
||
70 | gchar *tmpdir; |
||
71 | tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); |
||
72 | addr = g_strdup_printf ("unix:tmpdir=%s", tmpdir); |
||
73 | g_free (tmpdir); |
||
74 | } |
||
75 | #else |
||
76 | addr = g_strdup ("nonce-tcp:"); |
||
77 | #endif |
||
78 | |||
79 | auth_observer = g_dbus_auth_observer_new (); |
||
80 | |||
81 | flags = G_DBUS_SERVER_FLAGS_NONE; |
||
82 | if (g_strcmp0 (allowed_mechanism, "ANONYMOUS") == 0) |
||
83 | flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; |
||
84 | |||
85 | error = NULL; |
||
86 | server = g_dbus_server_new_sync (addr, |
||
87 | flags, |
||
88 | guid, |
||
89 | auth_observer, |
||
90 | NULL, /* cancellable */ |
||
91 | &error); |
||
92 | g_assert_no_error (error); |
||
93 | g_assert (server != NULL); |
||
94 | |||
95 | g_signal_connect (auth_observer, |
||
96 | "allow-mechanism", |
||
97 | G_CALLBACK (server_on_allow_mechanism), |
||
98 | (gpointer) allowed_mechanism); |
||
99 | |||
100 | g_free (addr); |
||
101 | g_free (guid); |
||
102 | g_object_unref (auth_observer); |
||
103 | |||
104 | return server; |
||
105 | } |
||
106 | |||
107 | /* ---------------------------------------------------------------------------------------------------- */ |
||
108 | |||
109 | static gboolean |
||
110 | test_auth_on_new_connection (GDBusServer *server, |
||
111 | GDBusConnection *connection, |
||
112 | gpointer user_data) |
||
113 | { |
||
114 | GMainLoop *loop = user_data; |
||
115 | g_main_loop_quit (loop); |
||
116 | return FALSE; |
||
117 | } |
||
118 | |||
119 | static gboolean |
||
120 | test_auth_on_timeout (gpointer user_data) |
||
121 | { |
||
122 | g_error ("Timeout waiting for client"); |
||
123 | g_assert_not_reached (); |
||
124 | return FALSE; |
||
125 | } |
||
126 | |||
127 | |||
128 | typedef struct |
||
129 | { |
||
130 | const gchar *address; |
||
131 | const gchar *allowed_client_mechanism; |
||
132 | const gchar *allowed_server_mechanism; |
||
133 | } TestAuthData; |
||
134 | |||
135 | static gpointer |
||
136 | test_auth_client_thread_func (gpointer user_data) |
||
137 | { |
||
138 | TestAuthData *data = user_data; |
||
139 | GDBusConnection *c = NULL; |
||
140 | GError *error = NULL; |
||
141 | GDBusAuthObserver *auth_observer = NULL; |
||
142 | |||
143 | auth_observer = g_dbus_auth_observer_new (); |
||
144 | |||
145 | g_signal_connect (auth_observer, |
||
146 | "allow-mechanism", |
||
147 | G_CALLBACK (server_on_allow_mechanism), |
||
148 | (gpointer) data->allowed_client_mechanism); |
||
149 | |||
150 | c = g_dbus_connection_new_for_address_sync (data->address, |
||
151 | G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, |
||
152 | auth_observer, |
||
153 | NULL, /* GCancellable */ |
||
154 | &error); |
||
155 | g_assert_no_error (error); |
||
156 | g_assert (c != NULL); |
||
157 | g_clear_object (&c); |
||
158 | g_clear_object (&auth_observer); |
||
159 | return NULL; |
||
160 | } |
||
161 | |||
162 | static void |
||
163 | test_auth_mechanism (const gchar *allowed_client_mechanism, |
||
164 | const gchar *allowed_server_mechanism) |
||
165 | { |
||
166 | GDBusServer *server; |
||
167 | GMainLoop *loop; |
||
168 | GThread *client_thread; |
||
169 | TestAuthData data; |
||
170 | |||
171 | server = server_new_for_mechanism (allowed_server_mechanism); |
||
172 | |||
173 | loop = g_main_loop_new (NULL, FALSE); |
||
174 | |||
175 | g_signal_connect (server, |
||
176 | "new-connection", |
||
177 | G_CALLBACK (test_auth_on_new_connection), |
||
178 | loop); |
||
179 | |||
180 | g_timeout_add_seconds (5, test_auth_on_timeout, NULL); |
||
181 | |||
182 | data.allowed_client_mechanism = allowed_client_mechanism; |
||
183 | data.allowed_server_mechanism = allowed_server_mechanism; |
||
184 | data.address = g_dbus_server_get_client_address (server); |
||
185 | |||
186 | /* run the D-Bus client in a thread */ |
||
187 | client_thread = g_thread_new ("gdbus-client-thread", |
||
188 | test_auth_client_thread_func, |
||
189 | &data); |
||
190 | |||
191 | g_dbus_server_start (server); |
||
192 | |||
193 | g_main_loop_run (loop); |
||
194 | |||
195 | g_dbus_server_stop (server); |
||
196 | |||
197 | g_thread_join (client_thread); |
||
198 | |||
199 | while (g_main_context_iteration (NULL, FALSE)); |
||
200 | g_main_loop_unref (loop); |
||
201 | |||
202 | g_object_unref (server); |
||
203 | } |
||
204 | |||
205 | /* ---------------------------------------------------------------------------------------------------- */ |
||
206 | |||
207 | static void |
||
208 | auth_client_external (void) |
||
209 | { |
||
210 | test_auth_mechanism ("EXTERNAL", NULL); |
||
211 | } |
||
212 | |||
213 | static void |
||
214 | auth_client_dbus_cookie_sha1 (void) |
||
215 | { |
||
216 | test_auth_mechanism ("DBUS_COOKIE_SHA1", NULL); |
||
217 | } |
||
218 | |||
219 | static void |
||
220 | auth_server_anonymous (void) |
||
221 | { |
||
222 | test_auth_mechanism (NULL, "ANONYMOUS"); |
||
223 | } |
||
224 | |||
225 | static void |
||
226 | auth_server_external (void) |
||
227 | { |
||
228 | test_auth_mechanism (NULL, "EXTERNAL"); |
||
229 | } |
||
230 | |||
231 | static void |
||
232 | auth_server_dbus_cookie_sha1 (void) |
||
233 | { |
||
234 | test_auth_mechanism (NULL, "DBUS_COOKIE_SHA1"); |
||
235 | } |
||
236 | |||
237 | /* ---------------------------------------------------------------------------------------------------- */ |
||
238 | |||
239 | static gchar *temp_dbus_keyrings_dir = NULL; |
||
240 | |||
241 | static void |
||
242 | temp_dbus_keyrings_setup (void) |
||
243 | { |
||
244 | GError *error = NULL; |
||
245 | |||
246 | g_assert (temp_dbus_keyrings_dir == NULL); |
||
247 | temp_dbus_keyrings_dir = g_dir_make_tmp ("gdbus-test-dbus-keyrings-XXXXXX", &error); |
||
248 | g_assert_no_error (error); |
||
249 | g_assert (temp_dbus_keyrings_dir != NULL); |
||
250 | g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR", temp_dbus_keyrings_dir, TRUE); |
||
251 | g_setenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION", "1", TRUE); |
||
252 | } |
||
253 | |||
254 | static void |
||
255 | temp_dbus_keyrings_teardown (void) |
||
256 | { |
||
257 | GDir *dir; |
||
258 | GError *error = NULL; |
||
259 | const gchar *name; |
||
260 | |||
261 | g_assert (temp_dbus_keyrings_dir != NULL); |
||
262 | |||
263 | dir = g_dir_open (temp_dbus_keyrings_dir, 0, &error); |
||
264 | g_assert_no_error (error); |
||
265 | g_assert (dir != NULL); |
||
266 | while ((name = g_dir_read_name (dir)) != NULL) |
||
267 | { |
||
268 | gchar *path = g_build_filename (temp_dbus_keyrings_dir, name, NULL); |
||
269 | g_assert (unlink (path) == 0); |
||
270 | g_free (path); |
||
271 | } |
||
272 | g_dir_close (dir); |
||
273 | g_assert (rmdir (temp_dbus_keyrings_dir) == 0); |
||
274 | |||
275 | g_free (temp_dbus_keyrings_dir); |
||
276 | temp_dbus_keyrings_dir = NULL; |
||
277 | g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR"); |
||
278 | g_unsetenv ("G_DBUS_COOKIE_SHA1_KEYRING_DIR_IGNORE_PERMISSION"); |
||
279 | } |
||
280 | |||
281 | /* ---------------------------------------------------------------------------------------------------- */ |
||
282 | |||
283 | int |
||
284 | main (int argc, |
||
285 | char *argv[]) |
||
286 | { |
||
287 | gint ret; |
||
288 | |||
289 | setlocale (LC_ALL, "C"); |
||
290 | |||
291 | temp_dbus_keyrings_setup (); |
||
292 | |||
293 | g_test_init (&argc, &argv, NULL); |
||
294 | |||
295 | g_test_add_func ("/gdbus/auth/client/EXTERNAL", auth_client_external); |
||
296 | g_test_add_func ("/gdbus/auth/client/DBUS_COOKIE_SHA1", auth_client_dbus_cookie_sha1); |
||
297 | g_test_add_func ("/gdbus/auth/server/ANONYMOUS", auth_server_anonymous); |
||
298 | g_test_add_func ("/gdbus/auth/server/EXTERNAL", auth_server_external); |
||
299 | g_test_add_func ("/gdbus/auth/server/DBUS_COOKIE_SHA1", auth_server_dbus_cookie_sha1); |
||
300 | |||
301 | /* TODO: we currently don't have tests for |
||
302 | * |
||
303 | * - DBUS_COOKIE_SHA1 timeouts (and clock changes etc) |
||
304 | * - interoperability with libdbus-1 implementations of authentication methods (both client and server) |
||
305 | */ |
||
306 | |||
307 | ret = g_test_run(); |
||
308 | |||
309 | temp_dbus_keyrings_teardown (); |
||
310 | |||
311 | return ret; |
||
312 | } |
||
313 |