chiark / gitweb /
bus: fake client side creds in the proxy to the caller's creds
[elogind.git] / src / libsystemd-bus / test-bus-marshal.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <byteswap.h>
25
26 #ifdef HAVE_GLIB
27 #include <gio/gio.h>
28 #endif
29
30 #ifdef HAVE_DBUS
31 #include <dbus/dbus.h>
32 #endif
33
34 #include "log.h"
35 #include "util.h"
36
37 #include "sd-bus.h"
38 #include "bus-message.h"
39 #include "bus-util.h"
40 #include "bus-dump.h"
41
42 static void test_bus_label_escape_one(const char *a, const char *b) {
43         _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
44
45         assert_se(t = sd_bus_label_escape(a));
46         assert_se(streq(t, b));
47
48         assert_se(x = sd_bus_label_unescape(t));
49         assert_se(streq(a, x));
50
51         assert_se(y = sd_bus_label_unescape(b));
52         assert_se(streq(a, y));
53 }
54
55 static void test_bus_label_escape(void) {
56         test_bus_label_escape_one("foo123bar", "foo123bar");
57         test_bus_label_escape_one("foo.bar", "foo_2ebar");
58         test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
59         test_bus_label_escape_one("", "_");
60         test_bus_label_escape_one("_", "_5f");
61         test_bus_label_escape_one("1", "_31");
62         test_bus_label_escape_one(":1", "_3a1");
63 }
64
65 int main(int argc, char *argv[]) {
66         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
67         int r, boolean;
68         const char *x, *x2, *y, *z, *a, *b, *c, *d;
69         uint8_t u, v;
70         void *buffer = NULL;
71         size_t sz;
72         char *h;
73         const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
74         char *s;
75         _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
76         _cleanup_fclose_ FILE *ms = NULL;
77         size_t first_size = 0, second_size = 0, third_size = 0;
78
79         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &m);
80         assert_se(r >= 0);
81
82         r = sd_bus_message_append(m, "s", "a string");
83         assert_se(r >= 0);
84
85         r = sd_bus_message_append(m, "s", NULL);
86         assert_se(r >= 0);
87
88         r = sd_bus_message_append(m, "as", 2, "string #1", "string #2");
89         assert_se(r >= 0);
90
91         r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
92         assert_se(r >= 0);
93
94         r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
95         assert_se(r >= 0);
96
97         r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
98         assert_se(r >= 0);
99
100         r = sd_bus_message_open_container(m, 'a', "s");
101         assert_se(r >= 0);
102
103         r = sd_bus_message_append_basic(m, 's', "foobar");
104         assert_se(r >= 0);
105
106         r = sd_bus_message_append_basic(m, 's', "waldo");
107         assert_se(r >= 0);
108
109         r = sd_bus_message_close_container(m);
110         assert_se(r >= 0);
111
112         r = sd_bus_message_append_string_space(m, 5, &s);
113         assert_se(r >= 0);
114         strcpy(s, "hallo");
115
116         r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
117         assert_se(r >= 0);
118
119         r = sd_bus_message_append_array(m, 'u', NULL, 0);
120         assert_se(r >= 0);
121
122         r = bus_message_seal(m, 4711, 0);
123         assert_se(r >= 0);
124
125         bus_message_dump(m, stdout, true);
126
127         ms = open_memstream(&first, &first_size);
128         bus_message_dump(m, ms, false);
129         fflush(ms);
130         assert_se(!ferror(ms));
131
132         r = bus_message_get_blob(m, &buffer, &sz);
133         assert_se(r >= 0);
134
135         h = hexmem(buffer, sz);
136         assert_se(h);
137
138         log_info("message size = %lu, contents =\n%s", (unsigned long) sz, h);
139         free(h);
140
141 #ifdef HAVE_GLIB
142         {
143                 GDBusMessage *g;
144                 char *p;
145
146 #if !defined(GLIB_VERSION_2_36)
147                 g_type_init();
148 #endif
149
150                 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
151                 p = g_dbus_message_print(g, 0);
152                 log_info("%s", p);
153                 g_free(p);
154                 g_object_unref(g);
155         }
156 #endif
157
158 #ifdef HAVE_DBUS
159         {
160                 DBusMessage *w;
161                 DBusError error;
162
163                 dbus_error_init(&error);
164
165                 w = dbus_message_demarshal(buffer, sz, &error);
166                 if (!w)
167                         log_error("%s", error.message);
168                 else
169                         dbus_message_unref(w);
170         }
171 #endif
172
173         m = sd_bus_message_unref(m);
174
175         r = bus_message_from_malloc(NULL, buffer, sz, NULL, 0, NULL, NULL, &m);
176         assert_se(r >= 0);
177
178         bus_message_dump(m, stdout, true);
179
180         fclose(ms);
181         ms = open_memstream(&second, &second_size);
182         bus_message_dump(m, ms, false);
183         fflush(ms);
184         assert_se(!ferror(ms));
185         assert_se(first_size == second_size);
186         assert_se(memcmp(first, second, first_size) == 0);
187
188         assert_se(sd_bus_message_rewind(m, true) >= 0);
189
190         r = sd_bus_message_read(m, "ssas", &x, &x2, 2, &y, &z);
191         assert_se(r > 0);
192         assert_se(streq(x, "a string"));
193         assert_se(streq(x2, ""));
194         assert_se(streq(y, "string #1"));
195         assert_se(streq(z, "string #2"));
196
197         r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
198         assert_se(r > 0);
199         assert_se(streq(x, "foobar"));
200         assert_se(streq(y, "foo"));
201         assert_se(streq(z, "bar"));
202         assert_se(streq(a, "waldo"));
203         assert_se(streq(b, "piep"));
204         assert_se(streq(c, "pap"));
205         assert_se(streq(d, "after"));
206
207         r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
208         assert_se(r > 0);
209         assert_se(u == 3);
210         assert_se(streq(x, "foo"));
211         assert_se(v == 5);
212         assert_se(streq(y, "waldo"));
213
214         r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
215         assert_se(r > 0);
216         assert_se(boolean);
217         assert_se(streq(x, "aaa"));
218         assert_se(streq(y, "1"));
219         assert_se(streq(a, "bbb"));
220         assert_se(streq(b, "2"));
221         assert_se(streq(c, "ccc"));
222         assert_se(streq(d, "3"));
223
224         assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
225
226         r = sd_bus_message_read(m, "as", 2, &x, &y);
227         assert_se(r > 0);
228         assert_se(streq(x, "foobar"));
229         assert_se(streq(y, "waldo"));
230
231         r = sd_bus_message_read_basic(m, 's', &s);
232         assert_se(r > 0);
233         assert_se(streq(s, "hallo"));
234
235         r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
236         assert_se(r > 0);
237         assert_se(sz == sizeof(integer_array));
238         assert_se(memcmp(integer_array, return_array, sz) == 0);
239
240         r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
241         assert_se(r > 0);
242         assert_se(sz == 0);
243
244         r = sd_bus_message_peek_type(m, NULL, NULL);
245         assert_se(r == 0);
246
247         r = sd_bus_message_new_method_call(NULL, "foobar.waldo", "/", "foobar.waldo", "Piep", &copy);
248         assert_se(r >= 0);
249
250         r = sd_bus_message_rewind(m, true);
251         assert_se(r >= 0);
252
253         r = sd_bus_message_copy(copy, m, true);
254         assert_se(r >= 0);
255
256         r = bus_message_seal(copy, 4712, 0);
257         assert_se(r >= 0);
258
259         fclose(ms);
260         ms = open_memstream(&third, &third_size);
261         bus_message_dump(copy, ms, false);
262         fflush(ms);
263         assert_se(!ferror(ms));
264
265         printf("<%.*s>", (int) first_size, first);
266         printf("<%.*s>", (int) third_size, third);
267
268         assert_se(first_size == third_size);
269         assert_se(memcmp(first, third, third_size) == 0);
270
271         r = sd_bus_message_rewind(m, true);
272         assert_se(r >= 0);
273
274         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
275
276         r = sd_bus_message_skip(m, "ssas");
277         assert_se(r > 0);
278
279         assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
280
281         r = sd_bus_message_skip(m, "sass");
282         assert_se(r >= 0);
283
284         assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
285
286         r = sd_bus_message_skip(m, "a{yv}");
287         assert_se(r >= 0);
288
289         assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
290
291         r = sd_bus_message_read(m, "b", &boolean);
292         assert_se(r > 0);
293         assert_se(boolean);
294
295         r = sd_bus_message_enter_container(m, 0, NULL);
296         assert_se(r > 0);
297
298         r = sd_bus_message_read(m, "(ss)", &x, &y);
299         assert_se(r > 0);
300
301         r = sd_bus_message_read(m, "(ss)", &a, &b);
302         assert_se(r > 0);
303
304         r = sd_bus_message_read(m, "(ss)", &c, &d);
305         assert_se(r > 0);
306
307         r = sd_bus_message_read(m, "(ss)", &x, &y);
308         assert_se(r == 0);
309
310         r = sd_bus_message_exit_container(m);
311         assert_se(r >= 0);
312
313         assert_se(streq(x, "aaa"));
314         assert_se(streq(y, "1"));
315         assert_se(streq(a, "bbb"));
316         assert_se(streq(b, "2"));
317         assert_se(streq(c, "ccc"));
318         assert_se(streq(d, "3"));
319
320         test_bus_label_escape();
321
322         return 0;
323 }