Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */
2 :
3 : #include <endian.h>
4 : #include <poll.h>
5 : #include <stdlib.h>
6 : #include <unistd.h>
7 :
8 : #include "sd-bus.h"
9 : #include "sd-daemon.h"
10 :
11 : #include "alloc-util.h"
12 : #include "bus-internal.h"
13 : #include "bus-message.h"
14 : #include "bus-socket.h"
15 : #include "fd-util.h"
16 : #include "format-util.h"
17 : #include "fs-util.h"
18 : #include "hexdecoct.h"
19 : #include "io-util.h"
20 : #include "macro.h"
21 : #include "memory-util.h"
22 : #include "missing.h"
23 : #include "path-util.h"
24 : #include "process-util.h"
25 : #include "rlimit-util.h"
26 : #include "selinux-util.h"
27 : #include "signal-util.h"
28 : #include "stdio-util.h"
29 : #include "string-util.h"
30 : #include "user-util.h"
31 : #include "utf8.h"
32 :
33 : #define SNDBUF_SIZE (8*1024*1024)
34 :
35 185 : static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
36 :
37 314 : while (size > 0) {
38 129 : struct iovec *i = iov + *idx;
39 :
40 129 : if (i->iov_len > size) {
41 0 : i->iov_base = (uint8_t*) i->iov_base + size;
42 0 : i->iov_len -= size;
43 0 : return;
44 : }
45 :
46 129 : size -= i->iov_len;
47 :
48 129 : *i = IOVEC_MAKE(NULL, 0);
49 :
50 129 : (*idx)++;
51 : }
52 : }
53 :
54 190 : static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
55 190 : assert(m);
56 190 : assert(p);
57 190 : assert(sz > 0);
58 :
59 190 : m->iovec[m->n_iovec++] = IOVEC_MAKE((void*) p, sz);
60 :
61 190 : return 0;
62 : }
63 :
64 134 : static int bus_message_setup_iovec(sd_bus_message *m) {
65 : struct bus_body_part *part;
66 : unsigned n, i;
67 : int r;
68 :
69 134 : assert(m);
70 134 : assert(m->sealed);
71 :
72 134 : if (m->n_iovec > 0)
73 0 : return 0;
74 :
75 134 : assert(!m->iovec);
76 :
77 134 : n = 1 + m->n_body_parts;
78 134 : if (n < ELEMENTSOF(m->iovec_fixed))
79 78 : m->iovec = m->iovec_fixed;
80 : else {
81 56 : m->iovec = new(struct iovec, n);
82 56 : if (!m->iovec) {
83 0 : r = -ENOMEM;
84 0 : goto fail;
85 : }
86 : }
87 :
88 134 : r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
89 134 : if (r < 0)
90 0 : goto fail;
91 :
92 190 : MESSAGE_FOREACH_PART(part, i, m) {
93 56 : r = bus_body_part_map(part);
94 56 : if (r < 0)
95 0 : goto fail;
96 :
97 56 : r = append_iovec(m, part->data, part->size);
98 56 : if (r < 0)
99 0 : goto fail;
100 : }
101 :
102 134 : assert(n == m->n_iovec);
103 :
104 134 : return 0;
105 :
106 0 : fail:
107 0 : m->poisoned = true;
108 0 : return r;
109 : }
110 :
111 175 : bool bus_socket_auth_needs_write(sd_bus *b) {
112 :
113 : unsigned i;
114 :
115 175 : if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
116 76 : return false;
117 :
118 166 : for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
119 131 : struct iovec *j = b->auth_iovec + i;
120 :
121 131 : if (j->iov_len > 0)
122 64 : return true;
123 : }
124 :
125 35 : return false;
126 : }
127 :
128 117 : static int bus_socket_write_auth(sd_bus *b) {
129 : ssize_t k;
130 :
131 117 : assert(b);
132 117 : assert(b->state == BUS_AUTHENTICATING);
133 :
134 117 : if (!bus_socket_auth_needs_write(b))
135 66 : return 0;
136 :
137 51 : if (b->prefer_writev)
138 0 : k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
139 : else {
140 : struct msghdr mh;
141 51 : zero(mh);
142 :
143 51 : mh.msg_iov = b->auth_iovec + b->auth_index;
144 51 : mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
145 :
146 51 : k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
147 51 : if (k < 0 && errno == ENOTSOCK) {
148 0 : b->prefer_writev = true;
149 0 : k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
150 : }
151 : }
152 :
153 51 : if (k < 0)
154 0 : return errno == EAGAIN ? 0 : -errno;
155 :
156 51 : iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
157 51 : return 1;
158 : }
159 :
160 87 : static int bus_socket_auth_verify_client(sd_bus *b) {
161 : char *d, *e, *f, *start;
162 : sd_id128_t peer;
163 : int r;
164 :
165 87 : assert(b);
166 :
167 : /*
168 : * We expect three response lines:
169 : * "DATA\r\n"
170 : * "OK <server-id>\r\n"
171 : * "AGREE_UNIX_FD\r\n" (optional)
172 : */
173 :
174 87 : d = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2);
175 87 : if (!d)
176 52 : return 0;
177 :
178 35 : e = memmem(d + 2, b->rbuffer_size - (d - (char*) b->rbuffer) - 2, "\r\n", 2);
179 35 : if (!e)
180 0 : return 0;
181 :
182 35 : if (b->accept_fd) {
183 33 : f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
184 33 : if (!f)
185 0 : return 0;
186 :
187 33 : start = f + 2;
188 : } else {
189 2 : f = NULL;
190 2 : start = e + 2;
191 : }
192 :
193 : /* Nice! We got all the lines we need. First check the DATA line. */
194 :
195 35 : if (d - (char*) b->rbuffer == 4) {
196 34 : if (memcmp(b->rbuffer, "DATA", 4))
197 0 : return -EPERM;
198 1 : } else if (d - (char*) b->rbuffer == 3 + 32) {
199 : /*
200 : * Old versions of the server-side implementation of `sd-bus` replied with "OK <id>" to
201 : * "AUTH" requests from a client, even if the "AUTH" line did not contain inlined
202 : * arguments. Therefore, we also accept "OK <id>" here, even though it is technically the
203 : * wrong reply. We ignore the "<id>" parameter, though, since it has no real value.
204 : */
205 0 : if (memcmp(b->rbuffer, "OK ", 3))
206 0 : return -EPERM;
207 : } else
208 1 : return -EPERM;
209 :
210 : /* Now check the OK line. */
211 :
212 34 : if (e - d != 2 + 3 + 32)
213 0 : return -EPERM;
214 :
215 34 : if (memcmp(d + 2, "OK ", 3))
216 0 : return -EPERM;
217 :
218 34 : b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
219 :
220 578 : for (unsigned i = 0; i < 32; i += 2) {
221 : int x, y;
222 :
223 544 : x = unhexchar(d[2 + 3 + i]);
224 544 : y = unhexchar(d[2 + 3 + i + 1]);
225 :
226 544 : if (x < 0 || y < 0)
227 0 : return -EINVAL;
228 :
229 544 : peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
230 : }
231 :
232 34 : if (!sd_id128_is_null(b->server_id) &&
233 0 : !sd_id128_equal(b->server_id, peer))
234 0 : return -EPERM;
235 :
236 34 : b->server_id = peer;
237 :
238 : /* And possibly check the third line, too */
239 :
240 34 : if (f)
241 32 : b->can_fds =
242 63 : (f - e == STRLEN("\r\nAGREE_UNIX_FD")) &&
243 31 : memcmp(e + 2, "AGREE_UNIX_FD",
244 : STRLEN("AGREE_UNIX_FD")) == 0;
245 :
246 34 : b->rbuffer_size -= (start - (char*) b->rbuffer);
247 34 : memmove(b->rbuffer, start, b->rbuffer_size);
248 :
249 34 : r = bus_start_running(b);
250 34 : if (r < 0)
251 0 : return r;
252 :
253 34 : return 1;
254 : }
255 :
256 91 : static bool line_equals(const char *s, size_t m, const char *line) {
257 : size_t l;
258 :
259 91 : l = strlen(line);
260 91 : if (l != m)
261 61 : return false;
262 :
263 30 : return memcmp(s, line, l) == 0;
264 : }
265 :
266 204 : static bool line_begins(const char *s, size_t m, const char *word) {
267 : const char *p;
268 :
269 204 : p = memory_startswith(s, m, word);
270 204 : return p && (p == (s + m) || *p == ' ');
271 : }
272 :
273 3 : static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
274 3 : _cleanup_free_ char *token = NULL;
275 : size_t len;
276 : int r;
277 :
278 3 : if (!b->anonymous_auth)
279 1 : return 0;
280 :
281 2 : if (l <= 0)
282 1 : return 1;
283 :
284 1 : assert(p[0] == ' ');
285 1 : p++; l--;
286 :
287 1 : if (l % 2 != 0)
288 0 : return 0;
289 :
290 1 : r = unhexmem(p, l, (void **) &token, &len);
291 1 : if (r < 0)
292 0 : return 0;
293 :
294 1 : if (memchr(token, 0, len))
295 0 : return 0;
296 :
297 1 : return !!utf8_is_valid(token);
298 : }
299 :
300 18 : static int verify_external_token(sd_bus *b, const char *p, size_t l) {
301 18 : _cleanup_free_ char *token = NULL;
302 : size_t len;
303 : uid_t u;
304 : int r;
305 :
306 : /* We don't do any real authentication here. Instead, we if
307 : * the owner of this bus wanted authentication he should have
308 : * checked SO_PEERCRED before even creating the bus object. */
309 :
310 18 : if (!b->anonymous_auth && !b->ucred_valid)
311 0 : return 0;
312 :
313 18 : if (l <= 0)
314 18 : return 1;
315 :
316 0 : assert(p[0] == ' ');
317 0 : p++; l--;
318 :
319 0 : if (l % 2 != 0)
320 0 : return 0;
321 :
322 0 : r = unhexmem(p, l, (void**) &token, &len);
323 0 : if (r < 0)
324 0 : return 0;
325 :
326 0 : if (memchr(token, 0, len))
327 0 : return 0;
328 :
329 0 : r = parse_uid(token, &u);
330 0 : if (r < 0)
331 0 : return 0;
332 :
333 : /* We ignore the passed value if anonymous authentication is
334 : * on anyway. */
335 0 : if (!b->anonymous_auth && u != b->ucred.uid)
336 0 : return 0;
337 :
338 0 : return 1;
339 : }
340 :
341 32 : static int bus_socket_auth_write(sd_bus *b, const char *t) {
342 : char *p;
343 : size_t l;
344 :
345 32 : assert(b);
346 32 : assert(t);
347 :
348 : /* We only make use of the first iovec */
349 32 : assert(IN_SET(b->auth_index, 0, 1));
350 :
351 32 : l = strlen(t);
352 32 : p = malloc(b->auth_iovec[0].iov_len + l);
353 32 : if (!p)
354 0 : return -ENOMEM;
355 :
356 32 : memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
357 32 : memcpy(p + b->auth_iovec[0].iov_len, t, l);
358 :
359 32 : b->auth_iovec[0].iov_base = p;
360 32 : b->auth_iovec[0].iov_len += l;
361 :
362 32 : free(b->auth_buffer);
363 32 : b->auth_buffer = p;
364 32 : b->auth_index = 0;
365 32 : return 0;
366 : }
367 :
368 10 : static int bus_socket_auth_write_ok(sd_bus *b) {
369 : char t[3 + 32 + 2 + 1];
370 :
371 10 : assert(b);
372 :
373 10 : xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
374 :
375 10 : return bus_socket_auth_write(b, t);
376 : }
377 :
378 36 : static int bus_socket_auth_verify_server(sd_bus *b) {
379 : char *e;
380 : const char *line;
381 : size_t l;
382 36 : bool processed = false;
383 : int r;
384 :
385 36 : assert(b);
386 :
387 36 : if (b->rbuffer_size < 1)
388 13 : return 0;
389 :
390 : /* First char must be a NUL byte */
391 23 : if (*(char*) b->rbuffer != 0)
392 0 : return -EIO;
393 :
394 23 : if (b->rbuffer_size < 3)
395 0 : return 0;
396 :
397 : /* Begin with the first line */
398 23 : if (b->auth_rbegin <= 0)
399 11 : b->auth_rbegin = 1;
400 :
401 : for (;;) {
402 : /* Check if line is complete */
403 87 : line = (char*) b->rbuffer + b->auth_rbegin;
404 55 : e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
405 55 : if (!e)
406 3 : return processed;
407 :
408 52 : l = e - line;
409 :
410 52 : if (line_begins(line, l, "AUTH ANONYMOUS")) {
411 :
412 2 : r = verify_anonymous_token(b,
413 : line + strlen("AUTH ANONYMOUS"),
414 : l - strlen("AUTH ANONYMOUS"));
415 2 : if (r < 0)
416 0 : return r;
417 2 : if (r == 0)
418 1 : r = bus_socket_auth_write(b, "REJECTED\r\n");
419 : else {
420 1 : b->auth = BUS_AUTH_ANONYMOUS;
421 1 : if (l <= strlen("AUTH ANONYMOUS"))
422 1 : r = bus_socket_auth_write(b, "DATA\r\n");
423 : else
424 0 : r = bus_socket_auth_write_ok(b);
425 : }
426 :
427 50 : } else if (line_begins(line, l, "AUTH EXTERNAL")) {
428 :
429 9 : r = verify_external_token(b,
430 : line + strlen("AUTH EXTERNAL"),
431 : l - strlen("AUTH EXTERNAL"));
432 9 : if (r < 0)
433 0 : return r;
434 9 : if (r == 0)
435 0 : r = bus_socket_auth_write(b, "REJECTED\r\n");
436 : else {
437 9 : b->auth = BUS_AUTH_EXTERNAL;
438 9 : if (l <= strlen("AUTH EXTERNAL"))
439 9 : r = bus_socket_auth_write(b, "DATA\r\n");
440 : else
441 0 : r = bus_socket_auth_write_ok(b);
442 : }
443 :
444 41 : } else if (line_begins(line, l, "AUTH"))
445 0 : r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
446 82 : else if (line_equals(line, l, "CANCEL") ||
447 41 : line_begins(line, l, "ERROR")) {
448 :
449 0 : b->auth = _BUS_AUTH_INVALID;
450 0 : r = bus_socket_auth_write(b, "REJECTED\r\n");
451 :
452 41 : } else if (line_equals(line, l, "BEGIN")) {
453 :
454 21 : if (b->auth == _BUS_AUTH_INVALID)
455 1 : r = bus_socket_auth_write(b, "ERROR\r\n");
456 : else {
457 : /* We can't leave from the auth phase
458 : * before we haven't written
459 : * everything queued, so let's check
460 : * that */
461 :
462 20 : if (bus_socket_auth_needs_write(b))
463 10 : return 1;
464 :
465 10 : b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
466 10 : memmove(b->rbuffer, e + 2, b->rbuffer_size);
467 10 : return bus_start_running(b);
468 : }
469 :
470 20 : } else if (line_begins(line, l, "DATA")) {
471 :
472 11 : if (b->auth == _BUS_AUTH_INVALID)
473 1 : r = bus_socket_auth_write(b, "ERROR\r\n");
474 : else {
475 10 : if (b->auth == BUS_AUTH_ANONYMOUS)
476 1 : r = verify_anonymous_token(b, line + 4, l - 4);
477 : else
478 9 : r = verify_external_token(b, line + 4, l - 4);
479 :
480 10 : if (r < 0)
481 0 : return r;
482 10 : if (r == 0) {
483 0 : b->auth = _BUS_AUTH_INVALID;
484 0 : r = bus_socket_auth_write(b, "REJECTED\r\n");
485 : } else
486 10 : r = bus_socket_auth_write_ok(b);
487 : }
488 9 : } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
489 9 : if (b->auth == _BUS_AUTH_INVALID || !b->accept_fd)
490 2 : r = bus_socket_auth_write(b, "ERROR\r\n");
491 : else {
492 7 : b->can_fds = true;
493 7 : r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
494 : }
495 : } else
496 0 : r = bus_socket_auth_write(b, "ERROR\r\n");
497 :
498 32 : if (r < 0)
499 0 : return r;
500 :
501 32 : b->auth_rbegin = e + 2 - (char*) b->rbuffer;
502 :
503 32 : processed = true;
504 : }
505 : }
506 :
507 123 : static int bus_socket_auth_verify(sd_bus *b) {
508 123 : assert(b);
509 :
510 123 : if (b->is_server)
511 36 : return bus_socket_auth_verify_server(b);
512 : else
513 87 : return bus_socket_auth_verify_client(b);
514 : }
515 :
516 77 : static int bus_socket_read_auth(sd_bus *b) {
517 : struct msghdr mh;
518 77 : struct iovec iov = {};
519 : size_t n;
520 : ssize_t k;
521 : int r;
522 : void *p;
523 : union {
524 : struct cmsghdr cmsghdr;
525 : uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
526 : } control;
527 77 : bool handle_cmsg = false;
528 :
529 77 : assert(b);
530 77 : assert(b->state == BUS_AUTHENTICATING);
531 :
532 77 : r = bus_socket_auth_verify(b);
533 77 : if (r != 0)
534 10 : return r;
535 :
536 67 : n = MAX(256u, b->rbuffer_size * 2);
537 :
538 67 : if (n > BUS_AUTH_SIZE_MAX)
539 0 : n = BUS_AUTH_SIZE_MAX;
540 :
541 67 : if (b->rbuffer_size >= n)
542 0 : return -ENOBUFS;
543 :
544 67 : p = realloc(b->rbuffer, n);
545 67 : if (!p)
546 0 : return -ENOMEM;
547 :
548 67 : b->rbuffer = p;
549 :
550 67 : iov = IOVEC_MAKE((uint8_t *)b->rbuffer + b->rbuffer_size, n - b->rbuffer_size);
551 :
552 67 : if (b->prefer_readv)
553 0 : k = readv(b->input_fd, &iov, 1);
554 : else {
555 67 : zero(mh);
556 67 : mh.msg_iov = &iov;
557 67 : mh.msg_iovlen = 1;
558 67 : mh.msg_control = &control;
559 67 : mh.msg_controllen = sizeof(control);
560 :
561 67 : k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
562 67 : if (k < 0 && errno == ENOTSOCK) {
563 0 : b->prefer_readv = true;
564 0 : k = readv(b->input_fd, &iov, 1);
565 : } else
566 67 : handle_cmsg = true;
567 : }
568 67 : if (k < 0)
569 20 : return errno == EAGAIN ? 0 : -errno;
570 47 : if (k == 0)
571 1 : return -ECONNRESET;
572 :
573 46 : b->rbuffer_size += k;
574 :
575 46 : if (handle_cmsg) {
576 : struct cmsghdr *cmsg;
577 :
578 46 : CMSG_FOREACH(cmsg, &mh)
579 0 : if (cmsg->cmsg_level == SOL_SOCKET &&
580 0 : cmsg->cmsg_type == SCM_RIGHTS) {
581 : int j;
582 :
583 : /* Whut? We received fds during the auth
584 : * protocol? Somebody is playing games with
585 : * us. Close them all, and fail */
586 0 : j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
587 0 : close_many((int*) CMSG_DATA(cmsg), j);
588 0 : return -EIO;
589 : } else
590 0 : log_debug("Got unexpected auxiliary data with level=%d and type=%d",
591 : cmsg->cmsg_level, cmsg->cmsg_type);
592 : }
593 :
594 46 : r = bus_socket_auth_verify(b);
595 46 : if (r != 0)
596 46 : return r;
597 :
598 0 : return 1;
599 : }
600 :
601 79 : void bus_socket_setup(sd_bus *b) {
602 79 : assert(b);
603 :
604 : /* Increase the buffers to 8 MB */
605 79 : (void) fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
606 79 : (void) fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
607 :
608 79 : b->message_version = 1;
609 79 : b->message_endian = 0;
610 79 : }
611 :
612 51 : static void bus_get_peercred(sd_bus *b) {
613 : int r;
614 :
615 51 : assert(b);
616 51 : assert(!b->ucred_valid);
617 51 : assert(!b->label);
618 51 : assert(b->n_groups == (size_t) -1);
619 :
620 : /* Get the peer for socketpair() sockets */
621 51 : b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
622 :
623 : /* Get the SELinux context of the peer */
624 51 : r = getpeersec(b->input_fd, &b->label);
625 51 : if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
626 0 : log_debug_errno(r, "Failed to determine peer security context: %m");
627 :
628 : /* Get the list of auxiliary groups of the peer */
629 51 : r = getpeergroups(b->input_fd, &b->groups);
630 51 : if (r >= 0)
631 51 : b->n_groups = (size_t) r;
632 0 : else if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
633 0 : log_debug_errno(r, "Failed to determine peer's group list: %m");
634 51 : }
635 :
636 40 : static int bus_socket_start_auth_client(sd_bus *b) {
637 : static const char sasl_auth_anonymous[] = {
638 : /*
639 : * We use an arbitrary trace-string for the ANONYMOUS authentication. It can be used by the
640 : * message broker to aid debugging of clients. We fully anonymize the connection and use a
641 : * static default.
642 : */
643 : "\0AUTH ANONYMOUS\r\n"
644 : /* HEX a n o n y m o u s */
645 : "DATA 616e6f6e796d6f7573\r\n"
646 : };
647 : static const char sasl_auth_external[] = {
648 : "\0AUTH EXTERNAL\r\n"
649 : "DATA\r\n"
650 : };
651 : static const char sasl_negotiate_unix_fd[] = {
652 : "NEGOTIATE_UNIX_FD\r\n"
653 : };
654 : static const char sasl_begin[] = {
655 : "BEGIN\r\n"
656 : };
657 40 : size_t i = 0;
658 :
659 40 : assert(b);
660 :
661 40 : if (b->anonymous_auth)
662 2 : b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_anonymous, sizeof(sasl_auth_anonymous) - 1);
663 : else
664 38 : b->auth_iovec[i++] = IOVEC_MAKE((char*) sasl_auth_external, sizeof(sasl_auth_external) - 1);
665 :
666 40 : if (b->accept_fd)
667 38 : b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_negotiate_unix_fd);
668 :
669 40 : b->auth_iovec[i++] = IOVEC_MAKE_STRING(sasl_begin);
670 :
671 40 : return bus_socket_write_auth(b);
672 : }
673 :
674 51 : int bus_socket_start_auth(sd_bus *b) {
675 51 : assert(b);
676 :
677 51 : bus_get_peercred(b);
678 :
679 51 : bus_set_state(b, BUS_AUTHENTICATING);
680 51 : b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_AUTH_TIMEOUT;
681 :
682 51 : if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
683 0 : b->accept_fd = false;
684 :
685 51 : if (b->output_fd != b->input_fd)
686 0 : if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
687 0 : b->accept_fd = false;
688 :
689 51 : if (b->is_server)
690 11 : return bus_socket_read_auth(b);
691 : else
692 40 : return bus_socket_start_auth_client(b);
693 : }
694 :
695 14 : static int bus_socket_inotify_setup(sd_bus *b) {
696 14 : _cleanup_free_ int *new_watches = NULL;
697 14 : _cleanup_free_ char *absolute = NULL;
698 14 : size_t n_allocated = 0, n = 0, done = 0, i;
699 14 : unsigned max_follow = 32;
700 : const char *p;
701 : int wd, r;
702 :
703 14 : assert(b);
704 14 : assert(b->watch_bind);
705 14 : assert(b->sockaddr.sa.sa_family == AF_UNIX);
706 14 : assert(b->sockaddr.un.sun_path[0] != 0);
707 :
708 : /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system socket
709 : * appears before connecting to it. The implemented is pretty simplistic: we just subscribe to relevant changes
710 : * to all prefix components of the path, and every time we get an event for that we try to reconnect again,
711 : * without actually caring what precisely the event we got told us. If we still can't connect we re-subscribe
712 : * to all relevant changes of anything in the path, so that our watches include any possibly newly created path
713 : * components. */
714 :
715 14 : if (b->inotify_fd < 0) {
716 2 : b->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
717 2 : if (b->inotify_fd < 0)
718 0 : return -errno;
719 :
720 2 : b->inotify_fd = fd_move_above_stdio(b->inotify_fd);
721 : }
722 :
723 : /* Make sure the path is NUL terminated */
724 14 : p = strndupa(b->sockaddr.un.sun_path, sizeof(b->sockaddr.un.sun_path));
725 :
726 : /* Make sure the path is absolute */
727 14 : r = path_make_absolute_cwd(p, &absolute);
728 14 : if (r < 0)
729 0 : goto fail;
730 :
731 : /* Watch all parent directories, and don't mind any prefix that doesn't exist yet. For the innermost directory
732 : * that exists we want to know when files are created or moved into it. For all parents of it we just care if
733 : * they are removed or renamed. */
734 :
735 14 : if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) {
736 0 : r = -ENOMEM;
737 0 : goto fail;
738 : }
739 :
740 : /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a symlink, and
741 : * always exists */
742 14 : wd = inotify_add_watch(b->inotify_fd, "/", IN_CREATE|IN_MOVED_TO);
743 14 : if (wd < 0) {
744 0 : r = log_debug_errno(errno, "Failed to add inotify watch on /: %m");
745 0 : goto fail;
746 : } else
747 14 : new_watches[n++] = wd;
748 :
749 114 : for (;;) {
750 364 : _cleanup_free_ char *component = NULL, *prefix = NULL, *destination = NULL;
751 : size_t n_slashes, n_component;
752 128 : char *c = NULL;
753 :
754 128 : n_slashes = strspn(absolute + done, "/");
755 128 : n_component = n_slashes + strcspn(absolute + done + n_slashes, "/");
756 :
757 128 : if (n_component == 0) /* The end */
758 2 : break;
759 :
760 126 : component = strndup(absolute + done, n_component);
761 126 : if (!component) {
762 0 : r = -ENOMEM;
763 0 : goto fail;
764 : }
765 :
766 : /* A trailing slash? That's a directory, and not a socket then */
767 126 : if (path_equal(component, "/")) {
768 0 : r = -EISDIR;
769 0 : goto fail;
770 : }
771 :
772 : /* A single dot? Let's eat this up */
773 126 : if (path_equal(component, "/.")) {
774 0 : done += n_component;
775 0 : continue;
776 : }
777 :
778 126 : prefix = strndup(absolute, done + n_component);
779 126 : if (!prefix) {
780 0 : r = -ENOMEM;
781 0 : goto fail;
782 : }
783 :
784 126 : if (!GREEDY_REALLOC(new_watches, n_allocated, n + 1)) {
785 0 : r = -ENOMEM;
786 0 : goto fail;
787 : }
788 :
789 126 : wd = inotify_add_watch(b->inotify_fd, prefix, IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO|IN_DONT_FOLLOW);
790 126 : log_debug("Added inotify watch for %s on bus %s: %i", prefix, strna(b->description), wd);
791 :
792 126 : if (wd < 0) {
793 12 : if (IN_SET(errno, ENOENT, ELOOP))
794 12 : break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */
795 :
796 0 : r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix));
797 0 : goto fail;
798 : } else
799 114 : new_watches[n++] = wd;
800 :
801 : /* Check if this is possibly a symlink. If so, let's follow it and watch it too. */
802 114 : r = readlink_malloc(prefix, &destination);
803 114 : if (r == -EINVAL) { /* not a symlink */
804 104 : done += n_component;
805 104 : continue;
806 : }
807 10 : if (r < 0)
808 0 : goto fail;
809 :
810 10 : if (isempty(destination)) { /* Empty symlink target? Yuck! */
811 0 : r = -EINVAL;
812 0 : goto fail;
813 : }
814 :
815 10 : if (max_follow <= 0) { /* Let's make sure we don't follow symlinks forever */
816 0 : r = -ELOOP;
817 0 : goto fail;
818 : }
819 :
820 10 : if (path_is_absolute(destination)) {
821 : /* For absolute symlinks we build the new path and start anew */
822 6 : c = strjoin(destination, absolute + done + n_component);
823 6 : done = 0;
824 : } else {
825 4 : _cleanup_free_ char *t = NULL;
826 :
827 : /* For relative symlinks we replace the last component, and try again */
828 4 : t = strndup(absolute, done);
829 4 : if (!t)
830 0 : return -ENOMEM;
831 :
832 4 : c = strjoin(t, "/", destination, absolute + done + n_component);
833 : }
834 10 : if (!c) {
835 0 : r = -ENOMEM;
836 0 : goto fail;
837 : }
838 :
839 10 : free(absolute);
840 10 : absolute = c;
841 :
842 10 : max_follow--;
843 : }
844 :
845 : /* And now, let's remove all watches from the previous iteration we don't need anymore */
846 112 : for (i = 0; i < b->n_inotify_watches; i++) {
847 98 : bool found = false;
848 : size_t j;
849 :
850 406 : for (j = 0; j < n; j++)
851 404 : if (new_watches[j] == b->inotify_watches[i]) {
852 96 : found = true;
853 96 : break;
854 : }
855 :
856 98 : if (found)
857 96 : continue;
858 :
859 2 : (void) inotify_rm_watch(b->inotify_fd, b->inotify_watches[i]);
860 : }
861 :
862 14 : free_and_replace(b->inotify_watches, new_watches);
863 14 : b->n_inotify_watches = n;
864 :
865 14 : return 0;
866 :
867 0 : fail:
868 0 : bus_close_inotify_fd(b);
869 0 : return r;
870 : }
871 :
872 46 : int bus_socket_connect(sd_bus *b) {
873 46 : bool inotify_done = false;
874 : int r;
875 :
876 46 : assert(b);
877 :
878 : for (;;) {
879 60 : assert(b->input_fd < 0);
880 60 : assert(b->output_fd < 0);
881 60 : assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
882 :
883 60 : b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
884 60 : if (b->input_fd < 0)
885 0 : return -errno;
886 :
887 60 : b->input_fd = fd_move_above_stdio(b->input_fd);
888 :
889 60 : b->output_fd = b->input_fd;
890 60 : bus_socket_setup(b);
891 :
892 60 : if (connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size) < 0) {
893 28 : if (errno == EINPROGRESS) {
894 :
895 : /* If we have any inotify watches open, close them now, we don't need them anymore, as
896 : * we have successfully initiated a connection */
897 0 : bus_close_inotify_fd(b);
898 :
899 : /* Note that very likely we are already in BUS_OPENING state here, as we enter it when
900 : * we start parsing the address string. The only reason we set the state explicitly
901 : * here, is to undo BUS_WATCH_BIND, in case we did the inotify magic. */
902 0 : bus_set_state(b, BUS_OPENING);
903 0 : return 1;
904 : }
905 :
906 28 : if (IN_SET(errno, ENOENT, ECONNREFUSED) && /* ENOENT → unix socket doesn't exist at all; ECONNREFUSED → unix socket stale */
907 28 : b->watch_bind &&
908 28 : b->sockaddr.sa.sa_family == AF_UNIX &&
909 28 : b->sockaddr.un.sun_path[0] != 0) {
910 :
911 : /* This connection attempt failed, let's release the socket for now, and start with a
912 : * fresh one when reconnecting. */
913 28 : bus_close_io_fds(b);
914 :
915 28 : if (inotify_done) {
916 : /* inotify set up already, don't do it again, just return now, and remember
917 : * that we are waiting for inotify events now. */
918 14 : bus_set_state(b, BUS_WATCH_BIND);
919 14 : return 1;
920 : }
921 :
922 : /* This is a file system socket, and the inotify logic is enabled. Let's create the necessary inotify fd. */
923 14 : r = bus_socket_inotify_setup(b);
924 14 : if (r < 0)
925 0 : return r;
926 :
927 : /* Let's now try to connect a second time, because in theory there's otherwise a race
928 : * here: the socket might have been created in the time between our first connect() and
929 : * the time we set up the inotify logic. But let's remember that we set up inotify now,
930 : * so that we don't do the connect() more than twice. */
931 14 : inotify_done = true;
932 :
933 : } else
934 0 : return -errno;
935 : } else
936 32 : break;
937 : }
938 :
939 : /* Yay, established, we don't need no inotify anymore! */
940 32 : bus_close_inotify_fd(b);
941 :
942 32 : return bus_socket_start_auth(b);
943 : }
944 :
945 0 : int bus_socket_exec(sd_bus *b) {
946 : int s[2], r;
947 :
948 0 : assert(b);
949 0 : assert(b->input_fd < 0);
950 0 : assert(b->output_fd < 0);
951 0 : assert(b->exec_path);
952 0 : assert(b->busexec_pid == 0);
953 :
954 0 : r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
955 0 : if (r < 0)
956 0 : return -errno;
957 :
958 0 : r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &b->busexec_pid);
959 0 : if (r < 0) {
960 0 : safe_close_pair(s);
961 0 : return r;
962 : }
963 0 : if (r == 0) {
964 : /* Child */
965 :
966 0 : if (rearrange_stdio(s[1], s[1], STDERR_FILENO) < 0)
967 0 : _exit(EXIT_FAILURE);
968 :
969 0 : (void) rlimit_nofile_safe();
970 :
971 0 : if (b->exec_argv)
972 0 : execvp(b->exec_path, b->exec_argv);
973 : else {
974 0 : const char *argv[] = { b->exec_path, NULL };
975 0 : execvp(b->exec_path, (char**) argv);
976 : }
977 :
978 0 : _exit(EXIT_FAILURE);
979 : }
980 :
981 0 : safe_close(s[1]);
982 0 : b->output_fd = b->input_fd = fd_move_above_stdio(s[0]);
983 :
984 0 : bus_socket_setup(b);
985 :
986 0 : return bus_socket_start_auth(b);
987 : }
988 :
989 19 : int bus_socket_take_fd(sd_bus *b) {
990 19 : assert(b);
991 :
992 19 : bus_socket_setup(b);
993 :
994 19 : return bus_socket_start_auth(b);
995 : }
996 :
997 134 : int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
998 : struct iovec *iov;
999 : ssize_t k;
1000 : size_t n;
1001 : unsigned j;
1002 : int r;
1003 :
1004 134 : assert(bus);
1005 134 : assert(m);
1006 134 : assert(idx);
1007 134 : assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1008 :
1009 134 : if (*idx >= BUS_MESSAGE_SIZE(m))
1010 0 : return 0;
1011 :
1012 134 : r = bus_message_setup_iovec(m);
1013 134 : if (r < 0)
1014 0 : return r;
1015 :
1016 134 : n = m->n_iovec * sizeof(struct iovec);
1017 134 : iov = newa(struct iovec, n);
1018 134 : memcpy_safe(iov, m->iovec, n);
1019 :
1020 134 : j = 0;
1021 134 : iovec_advance(iov, &j, *idx);
1022 :
1023 134 : if (bus->prefer_writev)
1024 0 : k = writev(bus->output_fd, iov, m->n_iovec);
1025 : else {
1026 268 : struct msghdr mh = {
1027 : .msg_iov = iov,
1028 134 : .msg_iovlen = m->n_iovec,
1029 : };
1030 :
1031 134 : if (m->n_fds > 0 && *idx == 0) {
1032 : struct cmsghdr *control;
1033 :
1034 1 : mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
1035 1 : mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
1036 1 : control->cmsg_level = SOL_SOCKET;
1037 1 : control->cmsg_type = SCM_RIGHTS;
1038 1 : memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
1039 : }
1040 :
1041 134 : k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
1042 134 : if (k < 0 && errno == ENOTSOCK) {
1043 0 : bus->prefer_writev = true;
1044 0 : k = writev(bus->output_fd, iov, m->n_iovec);
1045 : }
1046 : }
1047 :
1048 134 : if (k < 0)
1049 0 : return errno == EAGAIN ? 0 : -errno;
1050 :
1051 134 : *idx += (size_t) k;
1052 134 : return 1;
1053 : }
1054 :
1055 625 : static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
1056 : uint32_t a, b;
1057 : uint8_t e;
1058 : uint64_t sum;
1059 :
1060 625 : assert(bus);
1061 625 : assert(need);
1062 625 : assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1063 :
1064 625 : if (bus->rbuffer_size < sizeof(struct bus_header)) {
1065 239 : *need = sizeof(struct bus_header) + 8;
1066 :
1067 : /* Minimum message size:
1068 : *
1069 : * Header +
1070 : *
1071 : * Method Call: +2 string headers
1072 : * Signal: +3 string headers
1073 : * Method Error: +1 string headers
1074 : * +1 uint32 headers
1075 : * Method Reply: +1 uint32 headers
1076 : *
1077 : * A string header is at least 9 bytes
1078 : * A uint32 header is at least 8 bytes
1079 : *
1080 : * Hence the minimum message size of a valid message
1081 : * is header + 8 bytes */
1082 :
1083 239 : return 0;
1084 : }
1085 :
1086 386 : a = ((const uint32_t*) bus->rbuffer)[1];
1087 386 : b = ((const uint32_t*) bus->rbuffer)[3];
1088 :
1089 386 : e = ((const uint8_t*) bus->rbuffer)[0];
1090 386 : if (e == BUS_LITTLE_ENDIAN) {
1091 386 : a = le32toh(a);
1092 386 : b = le32toh(b);
1093 0 : } else if (e == BUS_BIG_ENDIAN) {
1094 0 : a = be32toh(a);
1095 0 : b = be32toh(b);
1096 : } else
1097 0 : return -EBADMSG;
1098 :
1099 386 : sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
1100 386 : if (sum >= BUS_MESSAGE_SIZE_MAX)
1101 0 : return -ENOBUFS;
1102 :
1103 386 : *need = (size_t) sum;
1104 386 : return 0;
1105 : }
1106 :
1107 142 : static int bus_socket_make_message(sd_bus *bus, size_t size) {
1108 142 : sd_bus_message *t = NULL;
1109 : void *b;
1110 : int r;
1111 :
1112 142 : assert(bus);
1113 142 : assert(bus->rbuffer_size >= size);
1114 142 : assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1115 :
1116 142 : r = bus_rqueue_make_room(bus);
1117 142 : if (r < 0)
1118 0 : return r;
1119 :
1120 142 : if (bus->rbuffer_size > size) {
1121 0 : b = memdup((const uint8_t*) bus->rbuffer + size,
1122 0 : bus->rbuffer_size - size);
1123 0 : if (!b)
1124 0 : return -ENOMEM;
1125 : } else
1126 142 : b = NULL;
1127 :
1128 142 : r = bus_message_from_malloc(bus,
1129 : bus->rbuffer, size,
1130 : bus->fds, bus->n_fds,
1131 : NULL,
1132 : &t);
1133 142 : if (r == -EBADMSG) {
1134 0 : log_debug_errno(r, "Received invalid message from connection %s, dropping.", strna(bus->description));
1135 0 : free(bus->rbuffer); /* We want to drop current rbuffer and proceed with whatever remains in b */
1136 142 : } else if (r < 0) {
1137 0 : free(b);
1138 0 : return r;
1139 : }
1140 :
1141 : /* rbuffer ownership was either transferred to t, or we got EBADMSG and dropped it. */
1142 142 : bus->rbuffer = b;
1143 142 : bus->rbuffer_size -= size;
1144 :
1145 142 : bus->fds = NULL;
1146 142 : bus->n_fds = 0;
1147 :
1148 142 : if (t) {
1149 142 : t->read_counter = ++bus->read_counter;
1150 142 : bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(t, bus);
1151 142 : sd_bus_message_unref(t);
1152 : }
1153 :
1154 142 : return 1;
1155 : }
1156 :
1157 361 : int bus_socket_read_message(sd_bus *bus) {
1158 : struct msghdr mh;
1159 361 : struct iovec iov = {};
1160 : ssize_t k;
1161 : size_t need;
1162 : int r;
1163 : void *b;
1164 : union {
1165 : struct cmsghdr cmsghdr;
1166 : uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
1167 : } control;
1168 361 : bool handle_cmsg = false;
1169 :
1170 361 : assert(bus);
1171 361 : assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1172 :
1173 361 : r = bus_socket_read_message_need(bus, &need);
1174 361 : if (r < 0)
1175 0 : return r;
1176 :
1177 361 : if (bus->rbuffer_size >= need)
1178 0 : return bus_socket_make_message(bus, need);
1179 :
1180 361 : b = realloc(bus->rbuffer, need);
1181 361 : if (!b)
1182 0 : return -ENOMEM;
1183 :
1184 361 : bus->rbuffer = b;
1185 :
1186 361 : iov = IOVEC_MAKE((uint8_t *)bus->rbuffer + bus->rbuffer_size, need - bus->rbuffer_size);
1187 :
1188 361 : if (bus->prefer_readv)
1189 0 : k = readv(bus->input_fd, &iov, 1);
1190 : else {
1191 361 : zero(mh);
1192 361 : mh.msg_iov = &iov;
1193 361 : mh.msg_iovlen = 1;
1194 361 : mh.msg_control = &control;
1195 361 : mh.msg_controllen = sizeof(control);
1196 :
1197 361 : k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
1198 361 : if (k < 0 && errno == ENOTSOCK) {
1199 0 : bus->prefer_readv = true;
1200 0 : k = readv(bus->input_fd, &iov, 1);
1201 : } else
1202 361 : handle_cmsg = true;
1203 : }
1204 361 : if (k < 0)
1205 96 : return errno == EAGAIN ? 0 : -errno;
1206 265 : if (k == 0)
1207 1 : return -ECONNRESET;
1208 :
1209 264 : bus->rbuffer_size += k;
1210 :
1211 264 : if (handle_cmsg) {
1212 : struct cmsghdr *cmsg;
1213 :
1214 265 : CMSG_FOREACH(cmsg, &mh)
1215 1 : if (cmsg->cmsg_level == SOL_SOCKET &&
1216 1 : cmsg->cmsg_type == SCM_RIGHTS) {
1217 : int n, *f, i;
1218 :
1219 1 : n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1220 :
1221 1 : if (!bus->can_fds) {
1222 : /* Whut? We received fds but this
1223 : * isn't actually enabled? Close them,
1224 : * and fail */
1225 :
1226 0 : close_many((int*) CMSG_DATA(cmsg), n);
1227 0 : return -EIO;
1228 : }
1229 :
1230 1 : f = reallocarray(bus->fds, bus->n_fds + n, sizeof(int));
1231 1 : if (!f) {
1232 0 : close_many((int*) CMSG_DATA(cmsg), n);
1233 0 : return -ENOMEM;
1234 : }
1235 :
1236 2 : for (i = 0; i < n; i++)
1237 1 : f[bus->n_fds++] = fd_move_above_stdio(((int*) CMSG_DATA(cmsg))[i]);
1238 1 : bus->fds = f;
1239 : } else
1240 0 : log_debug("Got unexpected auxiliary data with level=%d and type=%d",
1241 : cmsg->cmsg_level, cmsg->cmsg_type);
1242 : }
1243 :
1244 264 : r = bus_socket_read_message_need(bus, &need);
1245 264 : if (r < 0)
1246 0 : return r;
1247 :
1248 264 : if (bus->rbuffer_size >= need)
1249 142 : return bus_socket_make_message(bus, need);
1250 :
1251 122 : return 1;
1252 : }
1253 :
1254 0 : int bus_socket_process_opening(sd_bus *b) {
1255 0 : int error = 0;
1256 0 : socklen_t slen = sizeof(error);
1257 0 : struct pollfd p = {
1258 0 : .fd = b->output_fd,
1259 : .events = POLLOUT,
1260 : };
1261 : int r;
1262 :
1263 0 : assert(b->state == BUS_OPENING);
1264 :
1265 0 : r = poll(&p, 1, 0);
1266 0 : if (r < 0)
1267 0 : return -errno;
1268 :
1269 0 : if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1270 0 : return 0;
1271 :
1272 0 : r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
1273 0 : if (r < 0)
1274 0 : b->last_connect_error = errno;
1275 0 : else if (error != 0)
1276 0 : b->last_connect_error = error;
1277 0 : else if (p.revents & (POLLERR|POLLHUP))
1278 0 : b->last_connect_error = ECONNREFUSED;
1279 : else
1280 0 : return bus_socket_start_auth(b);
1281 :
1282 0 : return bus_next_address(b);
1283 : }
1284 :
1285 77 : int bus_socket_process_authenticating(sd_bus *b) {
1286 : int r;
1287 :
1288 77 : assert(b);
1289 77 : assert(b->state == BUS_AUTHENTICATING);
1290 :
1291 77 : if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1292 0 : return -ETIMEDOUT;
1293 :
1294 77 : r = bus_socket_write_auth(b);
1295 77 : if (r != 0)
1296 11 : return r;
1297 :
1298 66 : return bus_socket_read_auth(b);
1299 : }
1300 :
1301 21 : int bus_socket_process_watch_bind(sd_bus *b) {
1302 : int r, q;
1303 :
1304 21 : assert(b);
1305 21 : assert(b->state == BUS_WATCH_BIND);
1306 21 : assert(b->inotify_fd >= 0);
1307 :
1308 21 : r = flush_fd(b->inotify_fd);
1309 21 : if (r <= 0)
1310 7 : return r;
1311 :
1312 14 : log_debug("Got inotify event on bus %s.", strna(b->description));
1313 :
1314 : /* We flushed events out of the inotify fd. In that case, maybe the socket is valid now? Let's try to connect
1315 : * to it again */
1316 :
1317 14 : r = bus_socket_connect(b);
1318 14 : if (r < 0)
1319 0 : return r;
1320 :
1321 14 : q = bus_attach_io_events(b);
1322 14 : if (q < 0)
1323 0 : return q;
1324 :
1325 14 : q = bus_attach_inotify_event(b);
1326 14 : if (q < 0)
1327 0 : return q;
1328 :
1329 14 : return r;
1330 : }
|