]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
Merge pull request #558 from poettering/logind-bus-policy
[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;
d868f2a3 503 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
2181a7f5 504 } control;
15d5af81 505 bool handle_cmsg = false;
a7e3212d
LP
506
507 assert(b);
2181a7f5 508 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
509
510 r = bus_socket_auth_verify(b);
511 if (r != 0)
512 return r;
513
9607d947 514 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
515
516 if (n > BUS_AUTH_SIZE_MAX)
517 n = BUS_AUTH_SIZE_MAX;
518
519 if (b->rbuffer_size >= n)
520 return -ENOBUFS;
521
522 p = realloc(b->rbuffer, n);
523 if (!p)
524 return -ENOMEM;
525
526 b->rbuffer = p;
527
a7e3212d
LP
528 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
529 iov.iov_len = n - b->rbuffer_size;
530
15d5af81
LP
531 if (b->prefer_readv)
532 k = readv(b->input_fd, &iov, 1);
533 else {
534 zero(mh);
535 mh.msg_iov = &iov;
536 mh.msg_iovlen = 1;
537 mh.msg_control = &control;
538 mh.msg_controllen = sizeof(control);
539
540 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
541 if (k < 0 && errno == ENOTSOCK) {
542 b->prefer_readv = true;
543 k = readv(b->input_fd, &iov, 1);
544 } else
545 handle_cmsg = true;
546 }
a7e3212d
LP
547 if (k < 0)
548 return errno == EAGAIN ? 0 : -errno;
549 if (k == 0)
550 return -ECONNRESET;
551
552 b->rbuffer_size += k;
553
2a1288ff
LP
554 if (handle_cmsg) {
555 struct cmsghdr *cmsg;
556
557 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
558 if (cmsg->cmsg_level == SOL_SOCKET &&
559 cmsg->cmsg_type == SCM_RIGHTS) {
560 int j;
561
562 /* Whut? We received fds during the auth
563 * protocol? Somebody is playing games with
564 * us. Close them all, and fail */
565 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
566 close_many((int*) CMSG_DATA(cmsg), j);
567 return -EIO;
d868f2a3
ZJS
568 } else
569 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
570 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 571 }
2181a7f5 572
a7e3212d
LP
573 r = bus_socket_auth_verify(b);
574 if (r != 0)
575 return r;
576
577 return 1;
578}
579
8f04d2eb 580void bus_socket_setup(sd_bus *b) {
a7e3212d
LP
581 assert(b);
582
aec6d91f
LP
583 /* Increase the buffers to 8 MB */
584 fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
585 fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 586
e1d337d4
LP
587 b->is_kernel = false;
588 b->message_version = 1;
0f437184 589 b->message_endian = 0;
8f04d2eb 590}
e1d337d4 591
8f04d2eb 592static void bus_get_peercred(sd_bus *b) {
c4e6556c
ZJS
593 int r;
594
8f04d2eb
LP
595 assert(b);
596
597 /* Get the peer for socketpair() sockets */
eff05270 598 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
c4e6556c
ZJS
599
600 /* Get the SELinux context of the peer */
601 r = getpeersec(b->input_fd, &b->label);
602 if (r < 0 && r != -EOPNOTSUPP)
603 log_debug_errno(r, "Failed to determine peer security context: %m");
a7e3212d
LP
604}
605
2181a7f5 606static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 607 size_t l;
2181a7f5 608 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
609
610 assert(b);
611
2181a7f5
LP
612 if (b->anonymous_auth) {
613 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 614
2181a7f5
LP
615 /* For ANONYMOUS auth we send some arbitrary "trace" string */
616 l = 9;
617 b->auth_buffer = hexmem("anonymous", l);
618 } else {
5ffa8c81 619 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 620
2181a7f5 621 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 622
5ffa8c81 623 xsprintf(text, UID_FMT, geteuid());
a7e3212d 624
2181a7f5
LP
625 l = strlen(text);
626 b->auth_buffer = hexmem(text, l);
627 }
628
629 if (!b->auth_buffer)
a7e3212d
LP
630 return -ENOMEM;
631
264ad849 632 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
633 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
634 else
635 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
636
637 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
638 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
639 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
640 b->auth_iovec[1].iov_len = l * 2;
641 b->auth_iovec[2].iov_base = (void*) auth_suffix;
642 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
643
644 return bus_socket_write_auth(b);
645}
646
a7893c6b 647int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
648 assert(b);
649
8f04d2eb
LP
650 bus_get_peercred(b);
651
2181a7f5
LP
652 b->state = BUS_AUTHENTICATING;
653 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
654
9ab32f9d 655 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 656 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 657
9ab32f9d
LP
658 if (b->output_fd != b->input_fd)
659 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 660 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 661
2181a7f5
LP
662 if (b->is_server)
663 return bus_socket_read_auth(b);
664 else
665 return bus_socket_start_auth_client(b);
666}
667
a7e3212d
LP
668int bus_socket_connect(sd_bus *b) {
669 int r;
670
671 assert(b);
e82c9509
LP
672 assert(b->input_fd < 0);
673 assert(b->output_fd < 0);
a7e3212d
LP
674 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
675
e82c9509
LP
676 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
677 if (b->input_fd < 0)
a7e3212d
LP
678 return -errno;
679
e82c9509
LP
680 b->output_fd = b->input_fd;
681
8f04d2eb 682 bus_socket_setup(b);
a7e3212d 683
e82c9509 684 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
685 if (r < 0) {
686 if (errno == EINPROGRESS)
687 return 1;
688
689 return -errno;
690 }
691
692 return bus_socket_start_auth(b);
693}
694
695int bus_socket_exec(sd_bus *b) {
e82c9509 696 int s[2], r;
a7e3212d
LP
697 pid_t pid;
698
699 assert(b);
e82c9509
LP
700 assert(b->input_fd < 0);
701 assert(b->output_fd < 0);
a7e3212d
LP
702 assert(b->exec_path);
703
e82c9509
LP
704 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
705 if (r < 0)
a7e3212d
LP
706 return -errno;
707
708 pid = fork();
709 if (pid < 0) {
3d94f76c 710 safe_close_pair(s);
a7e3212d
LP
711 return -errno;
712 }
713 if (pid == 0) {
714 /* Child */
715
ce30c8dc
LP
716 (void) reset_all_signal_handlers();
717 (void) reset_signal_mask();
e82c9509
LP
718
719 close_all_fds(s+1, 1);
a7e3212d
LP
720
721 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
722 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
723
724 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
03e334a1 725 safe_close(s[1]);
a7e3212d
LP
726
727 fd_cloexec(STDIN_FILENO, false);
728 fd_cloexec(STDOUT_FILENO, false);
729 fd_nonblock(STDIN_FILENO, false);
730 fd_nonblock(STDOUT_FILENO, false);
731
732 if (b->exec_argv)
733 execvp(b->exec_path, b->exec_argv);
734 else {
735 const char *argv[] = { b->exec_path, NULL };
736 execvp(b->exec_path, (char**) argv);
737 }
738
739 _exit(EXIT_FAILURE);
740 }
741
03e334a1 742 safe_close(s[1]);
e82c9509 743 b->output_fd = b->input_fd = s[0];
a7e3212d 744
8f04d2eb 745 bus_socket_setup(b);
e1d337d4 746
a7e3212d
LP
747 return bus_socket_start_auth(b);
748}
749
750int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
751 assert(b);
752
8f04d2eb 753 bus_socket_setup(b);
a7e3212d
LP
754
755 return bus_socket_start_auth(b);
756}
757
758int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
759 struct iovec *iov;
760 ssize_t k;
761 size_t n;
762 unsigned j;
bc7fd8cd 763 int r;
a7e3212d
LP
764
765 assert(bus);
766 assert(m);
767 assert(idx);
768 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
769
6629161f 770 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 771 return 0;
a7e3212d 772
bc7fd8cd
LP
773 r = bus_message_setup_iovec(m);
774 if (r < 0)
775 return r;
2100fa10 776
a7e3212d
LP
777 n = m->n_iovec * sizeof(struct iovec);
778 iov = alloca(n);
779 memcpy(iov, m->iovec, n);
780
781 j = 0;
782 iovec_advance(iov, &j, *idx);
783
15d5af81
LP
784 if (bus->prefer_writev)
785 k = writev(bus->output_fd, iov, m->n_iovec);
786 else {
7f4e6a1c
ZJS
787 struct msghdr mh = {
788 .msg_iov = iov,
789 .msg_iovlen = m->n_iovec,
790 };
15d5af81
LP
791
792 if (m->n_fds > 0) {
793 struct cmsghdr *control;
15d5af81 794
7f4e6a1c
ZJS
795 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
796 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
15d5af81
LP
797 control->cmsg_level = SOL_SOCKET;
798 control->cmsg_type = SCM_RIGHTS;
15d5af81
LP
799 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
800 }
801
15d5af81
LP
802 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
803 if (k < 0 && errno == ENOTSOCK) {
804 bus->prefer_writev = true;
805 k = writev(bus->output_fd, iov, m->n_iovec);
806 }
807 }
a7e3212d 808
a7e3212d
LP
809 if (k < 0)
810 return errno == EAGAIN ? 0 : -errno;
811
812 *idx += (size_t) k;
813 return 1;
814}
815
816static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
817 uint32_t a, b;
818 uint8_t e;
819 uint64_t sum;
820
821 assert(bus);
822 assert(need);
823 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
824
825 if (bus->rbuffer_size < sizeof(struct bus_header)) {
826 *need = sizeof(struct bus_header) + 8;
827
828 /* Minimum message size:
829 *
830 * Header +
831 *
832 * Method Call: +2 string headers
833 * Signal: +3 string headers
834 * Method Error: +1 string headers
835 * +1 uint32 headers
836 * Method Reply: +1 uint32 headers
837 *
838 * A string header is at least 9 bytes
839 * A uint32 header is at least 8 bytes
840 *
841 * Hence the minimum message size of a valid message
842 * is header + 8 bytes */
843
844 return 0;
845 }
846
847 a = ((const uint32_t*) bus->rbuffer)[1];
848 b = ((const uint32_t*) bus->rbuffer)[3];
849
850 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 851 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
852 a = le32toh(a);
853 b = le32toh(b);
0461f8cd 854 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
855 a = be32toh(a);
856 b = be32toh(b);
857 } else
858 return -EBADMSG;
859
860 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
861 if (sum >= BUS_MESSAGE_SIZE_MAX)
862 return -ENOBUFS;
863
864 *need = (size_t) sum;
865 return 0;
866}
867
7d22c717 868static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
869 sd_bus_message *t;
870 void *b;
871 int r;
872
873 assert(bus);
a7e3212d
LP
874 assert(bus->rbuffer_size >= size);
875 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
876
7adc46fc
LP
877 r = bus_rqueue_make_room(bus);
878 if (r < 0)
879 return r;
880
a7e3212d
LP
881 if (bus->rbuffer_size > size) {
882 b = memdup((const uint8_t*) bus->rbuffer + size,
883 bus->rbuffer_size - size);
884 if (!b)
885 return -ENOMEM;
886 } else
887 b = NULL;
888
df2d202e
LP
889 r = bus_message_from_malloc(bus,
890 bus->rbuffer, size,
a7e3212d 891 bus->fds, bus->n_fds,
038f9863 892 NULL,
a7e3212d
LP
893 &t);
894 if (r < 0) {
895 free(b);
896 return r;
897 }
898
899 bus->rbuffer = b;
900 bus->rbuffer_size -= size;
901
902 bus->fds = NULL;
903 bus->n_fds = 0;
904
7adc46fc 905 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 906
a7e3212d
LP
907 return 1;
908}
909
7d22c717 910int bus_socket_read_message(sd_bus *bus) {
a7e3212d 911 struct msghdr mh;
7f4e6a1c 912 struct iovec iov = {};
a7e3212d
LP
913 ssize_t k;
914 size_t need;
915 int r;
916 void *b;
917 union {
918 struct cmsghdr cmsghdr;
d868f2a3 919 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
a7e3212d 920 } control;
4d3a5b10 921 bool handle_cmsg = false;
a7e3212d
LP
922
923 assert(bus);
a7e3212d
LP
924 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
925
926 r = bus_socket_read_message_need(bus, &need);
927 if (r < 0)
928 return r;
929
930 if (bus->rbuffer_size >= need)
7d22c717 931 return bus_socket_make_message(bus, need);
a7e3212d
LP
932
933 b = realloc(bus->rbuffer, need);
934 if (!b)
935 return -ENOMEM;
936
937 bus->rbuffer = b;
938
a7e3212d
LP
939 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
940 iov.iov_len = need - bus->rbuffer_size;
941
15d5af81
LP
942 if (bus->prefer_readv)
943 k = readv(bus->input_fd, &iov, 1);
944 else {
945 zero(mh);
946 mh.msg_iov = &iov;
947 mh.msg_iovlen = 1;
948 mh.msg_control = &control;
949 mh.msg_controllen = sizeof(control);
950
951 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
952 if (k < 0 && errno == ENOTSOCK) {
953 bus->prefer_readv = true;
954 k = readv(bus->input_fd, &iov, 1);
955 } else
956 handle_cmsg = true;
957 }
a7e3212d
LP
958 if (k < 0)
959 return errno == EAGAIN ? 0 : -errno;
960 if (k == 0)
961 return -ECONNRESET;
962
963 bus->rbuffer_size += k;
964
2a1288ff
LP
965 if (handle_cmsg) {
966 struct cmsghdr *cmsg;
967
968 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
969 if (cmsg->cmsg_level == SOL_SOCKET &&
970 cmsg->cmsg_type == SCM_RIGHTS) {
971 int n, *f;
972
973 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
974
975 if (!bus->can_fds) {
976 /* Whut? We received fds but this
977 * isn't actually enabled? Close them,
978 * and fail */
979
980 close_many((int*) CMSG_DATA(cmsg), n);
981 return -EIO;
982 }
983
984 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
985 if (!f) {
986 close_many((int*) CMSG_DATA(cmsg), n);
987 return -ENOMEM;
988 }
989
990 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
991 bus->fds = f;
992 bus->n_fds += n;
d868f2a3
ZJS
993 } else
994 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
995 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 996 }
a7e3212d
LP
997
998 r = bus_socket_read_message_need(bus, &need);
999 if (r < 0)
1000 return r;
1001
1002 if (bus->rbuffer_size >= need)
7d22c717 1003 return bus_socket_make_message(bus, need);
a7e3212d
LP
1004
1005 return 1;
1006}
1007
1008int bus_socket_process_opening(sd_bus *b) {
1009 int error = 0;
1010 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1011 struct pollfd p = {
1012 .fd = b->output_fd,
1013 .events = POLLOUT,
1014 };
a7e3212d
LP
1015 int r;
1016
a7e3212d
LP
1017 assert(b->state == BUS_OPENING);
1018
a7e3212d
LP
1019 r = poll(&p, 1, 0);
1020 if (r < 0)
1021 return -errno;
1022
1023 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1024 return 0;
1025
e82c9509 1026 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1027 if (r < 0)
1028 b->last_connect_error = errno;
1029 else if (error != 0)
1030 b->last_connect_error = error;
1031 else if (p.revents & (POLLERR|POLLHUP))
1032 b->last_connect_error = ECONNREFUSED;
1033 else
1034 return bus_socket_start_auth(b);
1035
1036 return bus_next_address(b);
1037}
1038
1039int bus_socket_process_authenticating(sd_bus *b) {
1040 int r;
1041
1042 assert(b);
1043 assert(b->state == BUS_AUTHENTICATING);
1044
1045 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1046 return -ETIMEDOUT;
1047
1048 r = bus_socket_write_auth(b);
1049 if (r != 0)
1050 return r;
1051
1052 return bus_socket_read_auth(b);
1053}