]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
11c4c249 | 2 | |
11c4c249 | 3 | #include <pthread.h> |
5cdf13c7 | 4 | #include <sys/socket.h> |
11c4c249 LP |
5 | |
6 | #include "sd-bus.h" | |
07630cea | 7 | |
5cdf13c7 | 8 | #include "bus-error.h" |
07630cea | 9 | #include "log.h" |
0a970718 | 10 | #include "memory-util.h" |
6969a671 | 11 | #include "string-util.h" |
965040d8 | 12 | #include "tests.h" |
11c4c249 LP |
13 | |
14 | struct context { | |
15 | int fds[2]; | |
16 | ||
17 | bool client_negotiate_unix_fds; | |
18 | bool server_negotiate_unix_fds; | |
19 | ||
20 | bool client_anonymous_auth; | |
21 | bool server_anonymous_auth; | |
22 | }; | |
23 | ||
70b16765 | 24 | static int _server(struct context *c) { |
f7794e42 | 25 | _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; |
11c4c249 LP |
26 | sd_id128_t id; |
27 | bool quit = false; | |
28 | int r; | |
29 | ||
30 | assert_se(sd_id128_randomize(&id) >= 0); | |
31 | ||
32 | assert_se(sd_bus_new(&bus) >= 0); | |
e82c9509 | 33 | assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0); |
11c4c249 | 34 | assert_se(sd_bus_set_server(bus, 1, id) >= 0); |
11c4c249 | 35 | assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0); |
264ad849 | 36 | assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0); |
11c4c249 LP |
37 | assert_se(sd_bus_start(bus) >= 0); |
38 | ||
39 | while (!quit) { | |
4afd3348 | 40 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; |
11c4c249 LP |
41 | |
42 | r = sd_bus_process(bus, &m); | |
70b16765 ZJS |
43 | if (r < 0) |
44 | return log_error_errno(r, "Failed to process requests: %m"); | |
11c4c249 LP |
45 | |
46 | if (r == 0) { | |
f5fbe71d | 47 | r = sd_bus_wait(bus, UINT64_MAX); |
70b16765 ZJS |
48 | if (r < 0) |
49 | return log_error_errno(r, "Failed to wait: %m"); | |
11c4c249 LP |
50 | continue; |
51 | } | |
52 | ||
53 | if (!m) | |
54 | continue; | |
55 | ||
56 | log_info("Got message! member=%s", strna(sd_bus_message_get_member(m))); | |
57 | ||
58 | if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) { | |
59 | ||
dcd6361e ZJS |
60 | assert_se((sd_bus_can_send(bus, 'h') >= 1) == |
61 | (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds)); | |
11c4c249 | 62 | |
df2d202e | 63 | r = sd_bus_message_new_method_return(m, &reply); |
70b16765 ZJS |
64 | if (r < 0) |
65 | return log_error_errno(r, "Failed to allocate return: %m"); | |
11c4c249 LP |
66 | |
67 | quit = true; | |
68 | ||
69 | } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { | |
c784c5ce | 70 | r = sd_bus_message_new_method_error( |
df2d202e | 71 | m, |
151b9b96 LP |
72 | &reply, |
73 | &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); | |
70b16765 ZJS |
74 | if (r < 0) |
75 | return log_error_errno(r, "Failed to allocate return: %m"); | |
11c4c249 LP |
76 | } |
77 | ||
78 | if (reply) { | |
79 | r = sd_bus_send(bus, reply, NULL); | |
70b16765 ZJS |
80 | if (r < 0) |
81 | return log_error_errno(r, "Failed to send reply: %m"); | |
11c4c249 LP |
82 | } |
83 | } | |
84 | ||
70b16765 ZJS |
85 | return 0; |
86 | } | |
11c4c249 | 87 | |
70b16765 ZJS |
88 | static void* server(void *p) { |
89 | return INT_TO_PTR(_server(p)); | |
11c4c249 LP |
90 | } |
91 | ||
92 | static int client(struct context *c) { | |
4afd3348 LP |
93 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; |
94 | _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; | |
7e284b05 | 95 | _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; |
11c4c249 LP |
96 | int r; |
97 | ||
98 | assert_se(sd_bus_new(&bus) >= 0); | |
e82c9509 | 99 | assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0); |
264ad849 | 100 | assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0); |
11c4c249 LP |
101 | assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0); |
102 | assert_se(sd_bus_start(bus) >= 0); | |
103 | ||
104 | r = sd_bus_message_new_method_call( | |
105 | bus, | |
151b9b96 | 106 | &m, |
11c4c249 LP |
107 | "org.freedesktop.systemd.test", |
108 | "/", | |
109 | "org.freedesktop.systemd.test", | |
151b9b96 | 110 | "Exit"); |
f647962d MS |
111 | if (r < 0) |
112 | return log_error_errno(r, "Failed to allocate method call: %m"); | |
11c4c249 | 113 | |
c49b30a2 | 114 | r = sd_bus_call(bus, m, 0, &error, &reply); |
4ae25393 | 115 | if (r < 0) |
2a03b9ed | 116 | return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r)); |
11c4c249 LP |
117 | |
118 | return 0; | |
119 | } | |
120 | ||
121 | static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds, | |
122 | bool client_anonymous_auth, bool server_anonymous_auth) { | |
123 | ||
124 | struct context c; | |
125 | pthread_t s; | |
126 | void *p; | |
127 | int r, q; | |
128 | ||
129 | zero(c); | |
130 | ||
131 | assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0); | |
132 | ||
133 | c.client_negotiate_unix_fds = client_negotiate_unix_fds; | |
134 | c.server_negotiate_unix_fds = server_negotiate_unix_fds; | |
135 | c.client_anonymous_auth = client_anonymous_auth; | |
136 | c.server_anonymous_auth = server_anonymous_auth; | |
137 | ||
138 | r = pthread_create(&s, NULL, server, &c); | |
139 | if (r != 0) | |
140 | return -r; | |
141 | ||
142 | r = client(&c); | |
143 | ||
144 | q = pthread_join(s, &p); | |
145 | if (q != 0) | |
146 | return -q; | |
147 | ||
148 | if (r < 0) | |
149 | return r; | |
150 | ||
151 | if (PTR_TO_INT(p) < 0) | |
152 | return PTR_TO_INT(p); | |
153 | ||
154 | return 0; | |
155 | } | |
156 | ||
157 | int main(int argc, char *argv[]) { | |
158 | int r; | |
159 | ||
965040d8 YW |
160 | test_setup_logging(LOG_DEBUG); |
161 | ||
11c4c249 LP |
162 | r = test_one(true, true, false, false); |
163 | assert_se(r >= 0); | |
164 | ||
165 | r = test_one(true, false, false, false); | |
166 | assert_se(r >= 0); | |
167 | ||
168 | r = test_one(false, true, false, false); | |
169 | assert_se(r >= 0); | |
170 | ||
171 | r = test_one(false, false, false, false); | |
172 | assert_se(r >= 0); | |
173 | ||
174 | r = test_one(true, true, true, true); | |
175 | assert_se(r >= 0); | |
176 | ||
177 | r = test_one(true, true, false, true); | |
178 | assert_se(r >= 0); | |
179 | ||
180 | r = test_one(true, true, true, false); | |
181 | assert_se(r == -EPERM); | |
182 | ||
183 | return EXIT_SUCCESS; | |
184 | } |