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