Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <pthread.h>
4 : : #include <stdlib.h>
5 : :
6 : : #include "sd-bus.h"
7 : :
8 : : #include "bus-internal.h"
9 : : #include "bus-util.h"
10 : : #include "log.h"
11 : : #include "macro.h"
12 : : #include "memory-util.h"
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 : :
24 : 28 : static void *server(void *p) {
25 : 28 : struct context *c = p;
26 : 28 : sd_bus *bus = NULL;
27 : : sd_id128_t id;
28 : 28 : bool quit = false;
29 : : int r;
30 : :
31 [ - + ]: 28 : assert_se(sd_id128_randomize(&id) >= 0);
32 : :
33 [ - + ]: 28 : assert_se(sd_bus_new(&bus) >= 0);
34 [ - + ]: 28 : assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
35 [ - + ]: 28 : assert_se(sd_bus_set_server(bus, 1, id) >= 0);
36 [ - + ]: 28 : assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
37 [ - + ]: 28 : assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
38 [ - + ]: 28 : assert_se(sd_bus_start(bus) >= 0);
39 : :
40 [ + + ]: 144 : while (!quit) {
41 [ + + + + : 212 : _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
+ + ]
42 : :
43 : 120 : r = sd_bus_process(bus, &m);
44 [ + + ]: 120 : if (r < 0) {
45 [ + - ]: 4 : log_error_errno(r, "Failed to process requests: %m");
46 : 4 : goto fail;
47 : : }
48 : :
49 [ + + ]: 116 : if (r == 0) {
50 : 27 : r = sd_bus_wait(bus, (uint64_t) -1);
51 [ - + ]: 27 : if (r < 0) {
52 [ # # ]: 0 : log_error_errno(r, "Failed to wait: %m");
53 : 0 : goto fail;
54 : : }
55 : :
56 : 27 : continue;
57 : : }
58 : :
59 [ + + ]: 89 : if (!m)
60 : 61 : continue;
61 : :
62 [ + - ]: 28 : log_info("Got message! member=%s", strna(sd_bus_message_get_member(m)));
63 : :
64 [ + + ]: 28 : if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
65 : :
66 [ + + + + : 24 : assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
- + ]
67 : : (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
68 : :
69 : 24 : r = sd_bus_message_new_method_return(m, &reply);
70 [ - + ]: 24 : if (r < 0) {
71 [ # # ]: 0 : log_error_errno(r, "Failed to allocate return: %m");
72 : 0 : goto fail;
73 : : }
74 : :
75 : 24 : quit = true;
76 : :
77 [ - + ]: 4 : } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
78 : 0 : r = sd_bus_message_new_method_error(
79 : : m,
80 : : &reply,
81 : 0 : &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
82 [ # # ]: 0 : if (r < 0) {
83 [ # # ]: 0 : log_error_errno(r, "Failed to allocate return: %m");
84 : 0 : goto fail;
85 : : }
86 : : }
87 : :
88 [ + + ]: 28 : if (reply) {
89 : 24 : r = sd_bus_send(bus, reply, NULL);
90 [ - + ]: 24 : if (r < 0) {
91 [ # # ]: 0 : log_error_errno(r, "Failed to send reply: %m");
92 : 0 : goto fail;
93 : : }
94 : : }
95 : : }
96 : :
97 : 24 : r = 0;
98 : :
99 : 28 : fail:
100 [ + - ]: 28 : if (bus) {
101 : 28 : sd_bus_flush(bus);
102 : 28 : sd_bus_unref(bus);
103 : : }
104 : :
105 : 28 : return INT_TO_PTR(r);
106 : : }
107 : :
108 : 28 : static int client(struct context *c) {
109 : 28 : _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
110 : 28 : _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
111 : 28 : sd_bus_error error = SD_BUS_ERROR_NULL;
112 : : int r;
113 : :
114 [ - + ]: 28 : assert_se(sd_bus_new(&bus) >= 0);
115 [ - + ]: 28 : assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
116 [ - + ]: 28 : assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
117 [ - + ]: 28 : assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
118 [ - + ]: 28 : assert_se(sd_bus_start(bus) >= 0);
119 : :
120 : 28 : r = sd_bus_message_new_method_call(
121 : : bus,
122 : : &m,
123 : : "org.freedesktop.systemd.test",
124 : : "/",
125 : : "org.freedesktop.systemd.test",
126 : : "Exit");
127 [ - + ]: 28 : if (r < 0)
128 [ # # ]: 0 : return log_error_errno(r, "Failed to allocate method call: %m");
129 : :
130 : 28 : r = sd_bus_call(bus, m, 0, &error, &reply);
131 [ + + ]: 28 : if (r < 0)
132 [ + - ]: 4 : return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r));
133 : :
134 : 24 : return 0;
135 : : }
136 : :
137 : 28 : static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds,
138 : : bool client_anonymous_auth, bool server_anonymous_auth) {
139 : :
140 : : struct context c;
141 : : pthread_t s;
142 : : void *p;
143 : : int r, q;
144 : :
145 [ + - ]: 28 : zero(c);
146 : :
147 [ - + ]: 28 : assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
148 : :
149 : 28 : c.client_negotiate_unix_fds = client_negotiate_unix_fds;
150 : 28 : c.server_negotiate_unix_fds = server_negotiate_unix_fds;
151 : 28 : c.client_anonymous_auth = client_anonymous_auth;
152 : 28 : c.server_anonymous_auth = server_anonymous_auth;
153 : :
154 : 28 : r = pthread_create(&s, NULL, server, &c);
155 [ - + ]: 28 : if (r != 0)
156 : 0 : return -r;
157 : :
158 : 28 : r = client(&c);
159 : :
160 : 28 : q = pthread_join(s, &p);
161 [ - + ]: 28 : if (q != 0)
162 : 0 : return -q;
163 : :
164 [ + + ]: 28 : if (r < 0)
165 : 4 : return r;
166 : :
167 [ - + ]: 24 : if (PTR_TO_INT(p) < 0)
168 : 0 : return PTR_TO_INT(p);
169 : :
170 : 24 : return 0;
171 : : }
172 : :
173 : 4 : int main(int argc, char *argv[]) {
174 : : int r;
175 : :
176 : 4 : r = test_one(true, true, false, false);
177 [ - + ]: 4 : assert_se(r >= 0);
178 : :
179 : 4 : r = test_one(true, false, false, false);
180 [ - + ]: 4 : assert_se(r >= 0);
181 : :
182 : 4 : r = test_one(false, true, false, false);
183 [ - + ]: 4 : assert_se(r >= 0);
184 : :
185 : 4 : r = test_one(false, false, false, false);
186 [ - + ]: 4 : assert_se(r >= 0);
187 : :
188 : 4 : r = test_one(true, true, true, true);
189 [ - + ]: 4 : assert_se(r >= 0);
190 : :
191 : 4 : r = test_one(true, true, false, true);
192 [ - + ]: 4 : assert_se(r >= 0);
193 : :
194 : 4 : r = test_one(true, true, true, false);
195 [ - + ]: 4 : assert_se(r == -EPERM);
196 : :
197 : 4 : return EXIT_SUCCESS;
198 : : }
|