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