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