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