]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
bus: touch() the AF_UNIX sockets we listen() on after the fact
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-socket.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7e3212d
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <endian.h>
07630cea 22#include <poll.h>
a7e3212d
LP
23#include <stdlib.h>
24#include <unistd.h>
a7e3212d 25
07630cea 26#include "sd-bus.h"
24882e06 27#include "sd-daemon.h"
07630cea 28
b5efdb8a 29#include "alloc-util.h"
07630cea
LP
30#include "bus-internal.h"
31#include "bus-message.h"
3ffd4af2
LP
32#include "bus-socket.h"
33#include "fd-util.h"
f97b34a6 34#include "format-util.h"
15a5e950 35#include "hexdecoct.h"
a7e3212d
LP
36#include "macro.h"
37#include "missing.h"
7fc04b12 38#include "selinux-util.h"
24882e06 39#include "signal-util.h"
15a5e950 40#include "stdio-util.h"
07630cea 41#include "string-util.h"
b1d4f8e1 42#include "user-util.h"
07630cea
LP
43#include "utf8.h"
44#include "util.h"
a7e3212d 45
aec6d91f
LP
46#define SNDBUF_SIZE (8*1024*1024)
47
2181a7f5 48static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
a7e3212d
LP
49
50 while (size > 0) {
51 struct iovec *i = iov + *idx;
52
53 if (i->iov_len > size) {
54 i->iov_base = (uint8_t*) i->iov_base + size;
55 i->iov_len -= size;
56 return;
57 }
58
59 size -= i->iov_len;
60
61 i->iov_base = NULL;
62 i->iov_len = 0;
63
313cefa1 64 (*idx)++;
a7e3212d
LP
65 }
66}
67
bc7fd8cd 68static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
2100fa10
LP
69 assert(m);
70 assert(p);
71 assert(sz > 0);
72
73 m->iovec[m->n_iovec].iov_base = (void*) p;
74 m->iovec[m->n_iovec].iov_len = sz;
75 m->n_iovec++;
bc7fd8cd
LP
76
77 return 0;
2100fa10
LP
78}
79
bc7fd8cd
LP
80static int bus_message_setup_iovec(sd_bus_message *m) {
81 struct bus_body_part *part;
13c299d3 82 unsigned n, i;
bc7fd8cd
LP
83 int r;
84
2100fa10
LP
85 assert(m);
86 assert(m->sealed);
87
88 if (m->n_iovec > 0)
bc7fd8cd
LP
89 return 0;
90
91 assert(!m->iovec);
2100fa10 92
c91cb83c 93 n = 1 + m->n_body_parts;
bc7fd8cd
LP
94 if (n < ELEMENTSOF(m->iovec_fixed))
95 m->iovec = m->iovec_fixed;
96 else {
97 m->iovec = new(struct iovec, n);
66b26c5c
LP
98 if (!m->iovec) {
99 r = -ENOMEM;
100 goto fail;
101 }
bc7fd8cd 102 }
2100fa10 103
c91cb83c 104 r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
bc7fd8cd 105 if (r < 0)
66b26c5c 106 goto fail;
2100fa10 107
9b29bb68 108 MESSAGE_FOREACH_PART(part, i, m) {
66b26c5c
LP
109 r = bus_body_part_map(part);
110 if (r < 0)
111 goto fail;
112
bc7fd8cd
LP
113 r = append_iovec(m, part->data, part->size);
114 if (r < 0)
66b26c5c 115 goto fail;
bc7fd8cd
LP
116 }
117
118 assert(n == m->n_iovec);
119
120 return 0;
66b26c5c
LP
121
122fail:
123 m->poisoned = true;
124 return r;
2100fa10
LP
125}
126
2181a7f5
LP
127bool bus_socket_auth_needs_write(sd_bus *b) {
128
129 unsigned i;
130
131 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
132 return false;
133
134 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
135 struct iovec *j = b->auth_iovec + i;
136
137 if (j->iov_len > 0)
138 return true;
139 }
140
141 return false;
142}
143
a7e3212d 144static int bus_socket_write_auth(sd_bus *b) {
a7e3212d
LP
145 ssize_t k;
146
147 assert(b);
148 assert(b->state == BUS_AUTHENTICATING);
149
2181a7f5 150 if (!bus_socket_auth_needs_write(b))
a7e3212d
LP
151 return 0;
152
15d5af81
LP
153 if (b->prefer_writev)
154 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
155 else {
156 struct msghdr mh;
157 zero(mh);
158
159 mh.msg_iov = b->auth_iovec + b->auth_index;
160 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
161
162 k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
163 if (k < 0 && errno == ENOTSOCK) {
164 b->prefer_writev = true;
165 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
166 }
167 }
a7e3212d 168
a7e3212d
LP
169 if (k < 0)
170 return errno == EAGAIN ? 0 : -errno;
171
172 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
a7e3212d
LP
173 return 1;
174}
175
2181a7f5 176static int bus_socket_auth_verify_client(sd_bus *b) {
a7e3212d
LP
177 char *e, *f, *start;
178 sd_id128_t peer;
179 unsigned i;
180 int r;
181
2181a7f5
LP
182 assert(b);
183
a7e3212d
LP
184 /* We expect two response lines: "OK" and possibly
185 * "AGREE_UNIX_FD" */
186
6e6c21c8 187 e = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2);
a7e3212d
LP
188 if (!e)
189 return 0;
190
264ad849 191 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) {
a7e3212d
LP
192 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
193 if (!f)
194 return 0;
195
196 start = f + 2;
197 } else {
198 f = NULL;
199 start = e + 2;
200 }
201
202 /* Nice! We got all the lines we need. First check the OK
203 * line */
204
205 if (e - (char*) b->rbuffer != 3 + 32)
206 return -EPERM;
207
208 if (memcmp(b->rbuffer, "OK ", 3))
209 return -EPERM;
210
2181a7f5
LP
211 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
212
a7e3212d
LP
213 for (i = 0; i < 32; i += 2) {
214 int x, y;
215
216 x = unhexchar(((char*) b->rbuffer)[3 + i]);
217 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
218
219 if (x < 0 || y < 0)
220 return -EINVAL;
221
222 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
223 }
224
3bbaff3e 225 if (!sd_id128_is_null(b->server_id) &&
98178d39 226 !sd_id128_equal(b->server_id, peer))
a7e3212d
LP
227 return -EPERM;
228
98178d39 229 b->server_id = peer;
a7e3212d
LP
230
231 /* And possibly check the second line, too */
232
233 if (f)
234 b->can_fds =
fbd0b64f
LP
235 (f - e == STRLEN("\r\nAGREE_UNIX_FD")) &&
236 memcmp(e + 2, "AGREE_UNIX_FD",
237 STRLEN("AGREE_UNIX_FD")) == 0;
a7e3212d
LP
238
239 b->rbuffer_size -= (start - (char*) b->rbuffer);
240 memmove(b->rbuffer, start, b->rbuffer_size);
241
242 r = bus_start_running(b);
243 if (r < 0)
244 return r;
245
246 return 1;
247}
248
2181a7f5
LP
249static bool line_equals(const char *s, size_t m, const char *line) {
250 size_t l;
251
252 l = strlen(line);
253 if (l != m)
254 return false;
255
256 return memcmp(s, line, l) == 0;
257}
258
259static bool line_begins(const char *s, size_t m, const char *word) {
260 size_t l;
261
262 l = strlen(word);
263 if (m < l)
264 return false;
265
266 if (memcmp(s, word, l) != 0)
267 return false;
268
269 return m == l || (m > l && s[l] == ' ');
270}
271
272static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
273 _cleanup_free_ char *token = NULL;
30494563
TG
274 size_t len;
275 int r;
2181a7f5
LP
276
277 if (!b->anonymous_auth)
278 return 0;
279
280 if (l <= 0)
281 return 1;
282
283 assert(p[0] == ' ');
284 p++; l--;
285
286 if (l % 2 != 0)
287 return 0;
2181a7f5 288
30494563
TG
289 r = unhexmem(p, l, (void **) &token, &len);
290 if (r < 0)
291 return 0;
292
293 if (memchr(token, 0, len))
2181a7f5
LP
294 return 0;
295
296 return !!utf8_is_valid(token);
297}
298
299static int verify_external_token(sd_bus *b, const char *p, size_t l) {
300 _cleanup_free_ char *token = NULL;
30494563 301 size_t len;
2181a7f5
LP
302 uid_t u;
303 int r;
304
305 /* We don't do any real authentication here. Instead, we if
306 * the owner of this bus wanted authentication he should have
307 * checked SO_PEERCRED before even creating the bus object. */
308
8411d2a2 309 if (!b->anonymous_auth && !b->ucred_valid)
2181a7f5
LP
310 return 0;
311
312 if (l <= 0)
313 return 1;
314
315 assert(p[0] == ' ');
316 p++; l--;
317
318 if (l % 2 != 0)
319 return 0;
320
30494563
TG
321 r = unhexmem(p, l, (void**) &token, &len);
322 if (r < 0)
323 return 0;
2181a7f5 324
30494563 325 if (memchr(token, 0, len))
2181a7f5
LP
326 return 0;
327
328 r = parse_uid(token, &u);
329 if (r < 0)
330 return 0;
331
8411d2a2
LP
332 /* We ignore the passed value if anonymous authentication is
333 * on anyway. */
334 if (!b->anonymous_auth && u != b->ucred.uid)
2181a7f5
LP
335 return 0;
336
337 return 1;
338}
339
340static int bus_socket_auth_write(sd_bus *b, const char *t) {
341 char *p;
342 size_t l;
343
344 assert(b);
345 assert(t);
346
347 /* We only make use of the first iovec */
945c2931 348 assert(IN_SET(b->auth_index, 0, 1));
2181a7f5
LP
349
350 l = strlen(t);
351 p = malloc(b->auth_iovec[0].iov_len + l);
352 if (!p)
353 return -ENOMEM;
354
75f32f04 355 memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
2181a7f5
LP
356 memcpy(p + b->auth_iovec[0].iov_len, t, l);
357
358 b->auth_iovec[0].iov_base = p;
359 b->auth_iovec[0].iov_len += l;
360
361 free(b->auth_buffer);
362 b->auth_buffer = p;
363 b->auth_index = 0;
364 return 0;
365}
366
367static int bus_socket_auth_write_ok(sd_bus *b) {
368 char t[3 + 32 + 2 + 1];
369
370 assert(b);
371
5ffa8c81 372 xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
373
374 return bus_socket_auth_write(b, t);
375}
376
377static int bus_socket_auth_verify_server(sd_bus *b) {
378 char *e;
379 const char *line;
380 size_t l;
381 bool processed = false;
382 int r;
383
384 assert(b);
385
2b4ac889 386 if (b->rbuffer_size < 1)
2181a7f5
LP
387 return 0;
388
389 /* First char must be a NUL byte */
390 if (*(char*) b->rbuffer != 0)
391 return -EIO;
392
2b4ac889
LP
393 if (b->rbuffer_size < 3)
394 return 0;
395
2181a7f5
LP
396 /* Begin with the first line */
397 if (b->auth_rbegin <= 0)
398 b->auth_rbegin = 1;
399
400 for (;;) {
401 /* Check if line is complete */
402 line = (char*) b->rbuffer + b->auth_rbegin;
403 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
404 if (!e)
405 return processed;
406
407 l = e - line;
408
409 if (line_begins(line, l, "AUTH ANONYMOUS")) {
410
411 r = verify_anonymous_token(b, line + 14, l - 14);
412 if (r < 0)
413 return r;
414 if (r == 0)
415 r = bus_socket_auth_write(b, "REJECTED\r\n");
416 else {
417 b->auth = BUS_AUTH_ANONYMOUS;
418 r = bus_socket_auth_write_ok(b);
419 }
420
421 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
422
423 r = verify_external_token(b, line + 13, l - 13);
424 if (r < 0)
425 return r;
426 if (r == 0)
427 r = bus_socket_auth_write(b, "REJECTED\r\n");
428 else {
429 b->auth = BUS_AUTH_EXTERNAL;
430 r = bus_socket_auth_write_ok(b);
431 }
432
433 } else if (line_begins(line, l, "AUTH"))
434 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
435 else if (line_equals(line, l, "CANCEL") ||
436 line_begins(line, l, "ERROR")) {
437
438 b->auth = _BUS_AUTH_INVALID;
439 r = bus_socket_auth_write(b, "REJECTED\r\n");
440
441 } else if (line_equals(line, l, "BEGIN")) {
442
443 if (b->auth == _BUS_AUTH_INVALID)
444 r = bus_socket_auth_write(b, "ERROR\r\n");
445 else {
446 /* We can't leave from the auth phase
447 * before we haven't written
448 * everything queued, so let's check
449 * that */
450
451 if (bus_socket_auth_needs_write(b))
452 return 1;
453
454 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
455 memmove(b->rbuffer, e + 2, b->rbuffer_size);
456 return bus_start_running(b);
457 }
458
459 } else if (line_begins(line, l, "DATA")) {
460
461 if (b->auth == _BUS_AUTH_INVALID)
462 r = bus_socket_auth_write(b, "ERROR\r\n");
463 else {
464 if (b->auth == BUS_AUTH_ANONYMOUS)
465 r = verify_anonymous_token(b, line + 4, l - 4);
466 else
467 r = verify_external_token(b, line + 4, l - 4);
468
469 if (r < 0)
470 return r;
471 if (r == 0) {
472 b->auth = _BUS_AUTH_INVALID;
473 r = bus_socket_auth_write(b, "REJECTED\r\n");
474 } else
475 r = bus_socket_auth_write_ok(b);
476 }
477 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
264ad849 478 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
2181a7f5
LP
479 r = bus_socket_auth_write(b, "ERROR\r\n");
480 else {
481 b->can_fds = true;
482 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
483 }
484 } else
485 r = bus_socket_auth_write(b, "ERROR\r\n");
486
487 if (r < 0)
488 return r;
489
490 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
491
492 processed = true;
493 }
494}
495
496static int bus_socket_auth_verify(sd_bus *b) {
497 assert(b);
498
499 if (b->is_server)
500 return bus_socket_auth_verify_server(b);
501 else
502 return bus_socket_auth_verify_client(b);
503}
504
a7e3212d
LP
505static int bus_socket_read_auth(sd_bus *b) {
506 struct msghdr mh;
7f4e6a1c 507 struct iovec iov = {};
a7e3212d
LP
508 size_t n;
509 ssize_t k;
510 int r;
511 void *p;
2181a7f5
LP
512 union {
513 struct cmsghdr cmsghdr;
d868f2a3 514 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
2181a7f5 515 } control;
15d5af81 516 bool handle_cmsg = false;
a7e3212d
LP
517
518 assert(b);
2181a7f5 519 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
520
521 r = bus_socket_auth_verify(b);
522 if (r != 0)
523 return r;
524
9607d947 525 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
526
527 if (n > BUS_AUTH_SIZE_MAX)
528 n = BUS_AUTH_SIZE_MAX;
529
530 if (b->rbuffer_size >= n)
531 return -ENOBUFS;
532
533 p = realloc(b->rbuffer, n);
534 if (!p)
535 return -ENOMEM;
536
537 b->rbuffer = p;
538
a7e3212d
LP
539 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
540 iov.iov_len = n - b->rbuffer_size;
541
15d5af81
LP
542 if (b->prefer_readv)
543 k = readv(b->input_fd, &iov, 1);
544 else {
545 zero(mh);
546 mh.msg_iov = &iov;
547 mh.msg_iovlen = 1;
548 mh.msg_control = &control;
549 mh.msg_controllen = sizeof(control);
550
551 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
552 if (k < 0 && errno == ENOTSOCK) {
553 b->prefer_readv = true;
554 k = readv(b->input_fd, &iov, 1);
555 } else
556 handle_cmsg = true;
557 }
a7e3212d
LP
558 if (k < 0)
559 return errno == EAGAIN ? 0 : -errno;
560 if (k == 0)
561 return -ECONNRESET;
562
563 b->rbuffer_size += k;
564
2a1288ff
LP
565 if (handle_cmsg) {
566 struct cmsghdr *cmsg;
567
568 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
569 if (cmsg->cmsg_level == SOL_SOCKET &&
570 cmsg->cmsg_type == SCM_RIGHTS) {
571 int j;
572
573 /* Whut? We received fds during the auth
574 * protocol? Somebody is playing games with
575 * us. Close them all, and fail */
576 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
577 close_many((int*) CMSG_DATA(cmsg), j);
578 return -EIO;
d868f2a3
ZJS
579 } else
580 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
581 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 582 }
2181a7f5 583
a7e3212d
LP
584 r = bus_socket_auth_verify(b);
585 if (r != 0)
586 return r;
587
588 return 1;
589}
590
8f04d2eb 591void bus_socket_setup(sd_bus *b) {
a7e3212d
LP
592 assert(b);
593
aec6d91f 594 /* Increase the buffers to 8 MB */
6ae22ffb
LP
595 (void) fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
596 (void) fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 597
e1d337d4 598 b->message_version = 1;
0f437184 599 b->message_endian = 0;
8f04d2eb 600}
e1d337d4 601
8f04d2eb 602static void bus_get_peercred(sd_bus *b) {
c4e6556c
ZJS
603 int r;
604
8f04d2eb 605 assert(b);
18ac4643
LP
606 assert(!b->ucred_valid);
607 assert(!b->label);
608 assert(b->n_groups == (size_t) -1);
8f04d2eb
LP
609
610 /* Get the peer for socketpair() sockets */
eff05270 611 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
c4e6556c
ZJS
612
613 /* Get the SELinux context of the peer */
db7d1dca 614 r = getpeersec(b->input_fd, &b->label);
18ac4643 615 if (r < 0 && !IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
db7d1dca 616 log_debug_errno(r, "Failed to determine peer security context: %m");
18ac4643
LP
617
618 /* Get the list of auxiliary groups of the peer */
619 r = getpeergroups(b->input_fd, &b->groups);
620 if (r < 0) {
621 if (!IN_SET(r, -EOPNOTSUPP, -ENOPROTOOPT))
622 log_debug_errno(r, "Failed to determine peer groups list: %m");
623
624 b->n_groups = (size_t) -1;
625 } else
626 b->n_groups = (size_t) r;
a7e3212d
LP
627}
628
2181a7f5 629static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 630 size_t l;
2181a7f5 631 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
632
633 assert(b);
634
2181a7f5
LP
635 if (b->anonymous_auth) {
636 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 637
2181a7f5
LP
638 /* For ANONYMOUS auth we send some arbitrary "trace" string */
639 l = 9;
640 b->auth_buffer = hexmem("anonymous", l);
641 } else {
5ffa8c81 642 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 643
2181a7f5 644 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 645
5ffa8c81 646 xsprintf(text, UID_FMT, geteuid());
a7e3212d 647
2181a7f5
LP
648 l = strlen(text);
649 b->auth_buffer = hexmem(text, l);
650 }
651
652 if (!b->auth_buffer)
a7e3212d
LP
653 return -ENOMEM;
654
264ad849 655 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
656 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
657 else
658 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
659
660 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
661 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
662 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
663 b->auth_iovec[1].iov_len = l * 2;
664 b->auth_iovec[2].iov_base = (void*) auth_suffix;
665 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
666
667 return bus_socket_write_auth(b);
668}
669
a7893c6b 670int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
671 assert(b);
672
8f04d2eb
LP
673 bus_get_peercred(b);
674
2181a7f5 675 b->state = BUS_AUTHENTICATING;
036d61b3 676 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_AUTH_TIMEOUT;
2181a7f5 677
9ab32f9d 678 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 679 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 680
9ab32f9d
LP
681 if (b->output_fd != b->input_fd)
682 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 683 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 684
2181a7f5
LP
685 if (b->is_server)
686 return bus_socket_read_auth(b);
687 else
688 return bus_socket_start_auth_client(b);
689}
690
a7e3212d
LP
691int bus_socket_connect(sd_bus *b) {
692 int r;
693
694 assert(b);
e82c9509
LP
695 assert(b->input_fd < 0);
696 assert(b->output_fd < 0);
a7e3212d
LP
697 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
698
e82c9509
LP
699 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
700 if (b->input_fd < 0)
a7e3212d
LP
701 return -errno;
702
e82c9509
LP
703 b->output_fd = b->input_fd;
704
8f04d2eb 705 bus_socket_setup(b);
a7e3212d 706
e82c9509 707 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
708 if (r < 0) {
709 if (errno == EINPROGRESS)
710 return 1;
711
712 return -errno;
713 }
714
715 return bus_socket_start_auth(b);
716}
717
718int bus_socket_exec(sd_bus *b) {
e82c9509 719 int s[2], r;
a7e3212d
LP
720 pid_t pid;
721
722 assert(b);
e82c9509
LP
723 assert(b->input_fd < 0);
724 assert(b->output_fd < 0);
a7e3212d
LP
725 assert(b->exec_path);
726
e82c9509
LP
727 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
728 if (r < 0)
a7e3212d
LP
729 return -errno;
730
4c253ed1
LP
731 r = safe_fork_full("(sd-busexec)", s+1, 1, FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &pid);
732 if (r < 0) {
3d94f76c 733 safe_close_pair(s);
4c253ed1 734 return r;
a7e3212d 735 }
4c253ed1 736 if (r == 0) {
a7e3212d
LP
737 /* Child */
738
a7e3212d
LP
739 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
740 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
741
945c2931 742 if (!IN_SET(s[1], STDIN_FILENO, STDOUT_FILENO))
03e334a1 743 safe_close(s[1]);
a7e3212d 744
6ae22ffb
LP
745 (void) fd_cloexec(STDIN_FILENO, false);
746 (void) fd_cloexec(STDOUT_FILENO, false);
747 (void) fd_nonblock(STDIN_FILENO, false);
748 (void) fd_nonblock(STDOUT_FILENO, false);
a7e3212d
LP
749
750 if (b->exec_argv)
751 execvp(b->exec_path, b->exec_argv);
752 else {
753 const char *argv[] = { b->exec_path, NULL };
754 execvp(b->exec_path, (char**) argv);
755 }
756
757 _exit(EXIT_FAILURE);
758 }
759
03e334a1 760 safe_close(s[1]);
e82c9509 761 b->output_fd = b->input_fd = s[0];
a7e3212d 762
8f04d2eb 763 bus_socket_setup(b);
e1d337d4 764
a7e3212d
LP
765 return bus_socket_start_auth(b);
766}
767
768int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
769 assert(b);
770
8f04d2eb 771 bus_socket_setup(b);
a7e3212d
LP
772
773 return bus_socket_start_auth(b);
774}
775
776int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
777 struct iovec *iov;
778 ssize_t k;
779 size_t n;
780 unsigned j;
bc7fd8cd 781 int r;
a7e3212d
LP
782
783 assert(bus);
784 assert(m);
785 assert(idx);
945c2931 786 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
a7e3212d 787
6629161f 788 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 789 return 0;
a7e3212d 790
bc7fd8cd
LP
791 r = bus_message_setup_iovec(m);
792 if (r < 0)
793 return r;
2100fa10 794
a7e3212d
LP
795 n = m->n_iovec * sizeof(struct iovec);
796 iov = alloca(n);
75f32f04 797 memcpy_safe(iov, m->iovec, n);
a7e3212d
LP
798
799 j = 0;
800 iovec_advance(iov, &j, *idx);
801
15d5af81
LP
802 if (bus->prefer_writev)
803 k = writev(bus->output_fd, iov, m->n_iovec);
804 else {
7f4e6a1c
ZJS
805 struct msghdr mh = {
806 .msg_iov = iov,
807 .msg_iovlen = m->n_iovec,
808 };
15d5af81 809
f29eef2e 810 if (m->n_fds > 0 && *idx == 0) {
15d5af81 811 struct cmsghdr *control;
15d5af81 812
7f4e6a1c
ZJS
813 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
814 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
15d5af81
LP
815 control->cmsg_level = SOL_SOCKET;
816 control->cmsg_type = SCM_RIGHTS;
15d5af81
LP
817 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
818 }
819
15d5af81
LP
820 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
821 if (k < 0 && errno == ENOTSOCK) {
822 bus->prefer_writev = true;
823 k = writev(bus->output_fd, iov, m->n_iovec);
824 }
825 }
a7e3212d 826
a7e3212d
LP
827 if (k < 0)
828 return errno == EAGAIN ? 0 : -errno;
829
830 *idx += (size_t) k;
831 return 1;
832}
833
834static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
835 uint32_t a, b;
836 uint8_t e;
837 uint64_t sum;
838
839 assert(bus);
840 assert(need);
945c2931 841 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
a7e3212d
LP
842
843 if (bus->rbuffer_size < sizeof(struct bus_header)) {
844 *need = sizeof(struct bus_header) + 8;
845
846 /* Minimum message size:
847 *
848 * Header +
849 *
850 * Method Call: +2 string headers
851 * Signal: +3 string headers
852 * Method Error: +1 string headers
853 * +1 uint32 headers
854 * Method Reply: +1 uint32 headers
855 *
856 * A string header is at least 9 bytes
857 * A uint32 header is at least 8 bytes
858 *
859 * Hence the minimum message size of a valid message
860 * is header + 8 bytes */
861
862 return 0;
863 }
864
865 a = ((const uint32_t*) bus->rbuffer)[1];
866 b = ((const uint32_t*) bus->rbuffer)[3];
867
868 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 869 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
870 a = le32toh(a);
871 b = le32toh(b);
0461f8cd 872 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
873 a = be32toh(a);
874 b = be32toh(b);
875 } else
876 return -EBADMSG;
877
878 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
879 if (sum >= BUS_MESSAGE_SIZE_MAX)
880 return -ENOBUFS;
881
882 *need = (size_t) sum;
883 return 0;
884}
885
7d22c717 886static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
887 sd_bus_message *t;
888 void *b;
889 int r;
890
891 assert(bus);
a7e3212d 892 assert(bus->rbuffer_size >= size);
945c2931 893 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
a7e3212d 894
7adc46fc
LP
895 r = bus_rqueue_make_room(bus);
896 if (r < 0)
897 return r;
898
a7e3212d
LP
899 if (bus->rbuffer_size > size) {
900 b = memdup((const uint8_t*) bus->rbuffer + size,
901 bus->rbuffer_size - size);
902 if (!b)
903 return -ENOMEM;
904 } else
905 b = NULL;
906
df2d202e
LP
907 r = bus_message_from_malloc(bus,
908 bus->rbuffer, size,
a7e3212d 909 bus->fds, bus->n_fds,
038f9863 910 NULL,
a7e3212d
LP
911 &t);
912 if (r < 0) {
913 free(b);
914 return r;
915 }
916
917 bus->rbuffer = b;
918 bus->rbuffer_size -= size;
919
920 bus->fds = NULL;
921 bus->n_fds = 0;
922
7adc46fc 923 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 924
a7e3212d
LP
925 return 1;
926}
927
7d22c717 928int bus_socket_read_message(sd_bus *bus) {
a7e3212d 929 struct msghdr mh;
7f4e6a1c 930 struct iovec iov = {};
a7e3212d
LP
931 ssize_t k;
932 size_t need;
933 int r;
934 void *b;
935 union {
936 struct cmsghdr cmsghdr;
d868f2a3 937 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
a7e3212d 938 } control;
4d3a5b10 939 bool handle_cmsg = false;
a7e3212d
LP
940
941 assert(bus);
945c2931 942 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
a7e3212d
LP
943
944 r = bus_socket_read_message_need(bus, &need);
945 if (r < 0)
946 return r;
947
948 if (bus->rbuffer_size >= need)
7d22c717 949 return bus_socket_make_message(bus, need);
a7e3212d
LP
950
951 b = realloc(bus->rbuffer, need);
952 if (!b)
953 return -ENOMEM;
954
955 bus->rbuffer = b;
956
a7e3212d
LP
957 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
958 iov.iov_len = need - bus->rbuffer_size;
959
15d5af81
LP
960 if (bus->prefer_readv)
961 k = readv(bus->input_fd, &iov, 1);
962 else {
963 zero(mh);
964 mh.msg_iov = &iov;
965 mh.msg_iovlen = 1;
966 mh.msg_control = &control;
967 mh.msg_controllen = sizeof(control);
968
969 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
970 if (k < 0 && errno == ENOTSOCK) {
971 bus->prefer_readv = true;
972 k = readv(bus->input_fd, &iov, 1);
973 } else
974 handle_cmsg = true;
975 }
a7e3212d
LP
976 if (k < 0)
977 return errno == EAGAIN ? 0 : -errno;
978 if (k == 0)
979 return -ECONNRESET;
980
981 bus->rbuffer_size += k;
982
2a1288ff
LP
983 if (handle_cmsg) {
984 struct cmsghdr *cmsg;
985
986 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
987 if (cmsg->cmsg_level == SOL_SOCKET &&
988 cmsg->cmsg_type == SCM_RIGHTS) {
989 int n, *f;
990
991 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
992
993 if (!bus->can_fds) {
994 /* Whut? We received fds but this
995 * isn't actually enabled? Close them,
996 * and fail */
997
998 close_many((int*) CMSG_DATA(cmsg), n);
999 return -EIO;
1000 }
1001
a0f5ab70 1002 f = realloc(bus->fds, sizeof(int) * (bus->n_fds + n));
15d5af81
LP
1003 if (!f) {
1004 close_many((int*) CMSG_DATA(cmsg), n);
1005 return -ENOMEM;
1006 }
1007
75f32f04 1008 memcpy_safe(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
15d5af81
LP
1009 bus->fds = f;
1010 bus->n_fds += n;
d868f2a3
ZJS
1011 } else
1012 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
1013 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 1014 }
a7e3212d
LP
1015
1016 r = bus_socket_read_message_need(bus, &need);
1017 if (r < 0)
1018 return r;
1019
1020 if (bus->rbuffer_size >= need)
7d22c717 1021 return bus_socket_make_message(bus, need);
a7e3212d
LP
1022
1023 return 1;
1024}
1025
1026int bus_socket_process_opening(sd_bus *b) {
1027 int error = 0;
1028 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1029 struct pollfd p = {
1030 .fd = b->output_fd,
1031 .events = POLLOUT,
1032 };
a7e3212d
LP
1033 int r;
1034
a7e3212d
LP
1035 assert(b->state == BUS_OPENING);
1036
a7e3212d
LP
1037 r = poll(&p, 1, 0);
1038 if (r < 0)
1039 return -errno;
1040
1041 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1042 return 0;
1043
e82c9509 1044 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1045 if (r < 0)
1046 b->last_connect_error = errno;
1047 else if (error != 0)
1048 b->last_connect_error = error;
1049 else if (p.revents & (POLLERR|POLLHUP))
1050 b->last_connect_error = ECONNREFUSED;
1051 else
1052 return bus_socket_start_auth(b);
1053
1054 return bus_next_address(b);
1055}
1056
1057int bus_socket_process_authenticating(sd_bus *b) {
1058 int r;
1059
1060 assert(b);
1061 assert(b->state == BUS_AUTHENTICATING);
1062
1063 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1064 return -ETIMEDOUT;
1065
1066 r = bus_socket_write_auth(b);
1067 if (r != 0)
1068 return r;
1069
1070 return bus_socket_read_auth(b);
1071}