]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
util-lib: split our string related calls from util.[ch] into its own file string...
[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>
07630cea 23#include <poll.h>
a7e3212d
LP
24#include <stdlib.h>
25#include <unistd.h>
a7e3212d 26
07630cea 27#include "sd-bus.h"
24882e06 28#include "sd-daemon.h"
07630cea
LP
29
30#include "bus-internal.h"
31#include "bus-message.h"
32#include "formats-util.h"
a7e3212d
LP
33#include "macro.h"
34#include "missing.h"
24882e06 35#include "signal-util.h"
07630cea
LP
36#include "string-util.h"
37#include "utf8.h"
38#include "util.h"
a7e3212d 39#include "bus-socket.h"
a7e3212d 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
6e6c21c8 182 e = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2);
a7e3212d
LP
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 =
f8294e41
JT
230 (f - e == strlen("\r\nAGREE_UNIX_FD")) &&
231 memcmp(e + 2, "AGREE_UNIX_FD", strlen("AGREE_UNIX_FD")) == 0;
a7e3212d
LP
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;
30494563
TG
268 size_t len;
269 int r;
2181a7f5
LP
270
271 if (!b->anonymous_auth)
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;
2181a7f5 282
30494563
TG
283 r = unhexmem(p, l, (void **) &token, &len);
284 if (r < 0)
285 return 0;
286
287 if (memchr(token, 0, len))
2181a7f5
LP
288 return 0;
289
290 return !!utf8_is_valid(token);
291}
292
293static int verify_external_token(sd_bus *b, const char *p, size_t l) {
294 _cleanup_free_ char *token = NULL;
30494563 295 size_t len;
2181a7f5
LP
296 uid_t u;
297 int r;
298
299 /* We don't do any real authentication here. Instead, we if
300 * the owner of this bus wanted authentication he should have
301 * checked SO_PEERCRED before even creating the bus object. */
302
8411d2a2 303 if (!b->anonymous_auth && !b->ucred_valid)
2181a7f5
LP
304 return 0;
305
306 if (l <= 0)
307 return 1;
308
309 assert(p[0] == ' ');
310 p++; l--;
311
312 if (l % 2 != 0)
313 return 0;
314
30494563
TG
315 r = unhexmem(p, l, (void**) &token, &len);
316 if (r < 0)
317 return 0;
2181a7f5 318
30494563 319 if (memchr(token, 0, len))
2181a7f5
LP
320 return 0;
321
322 r = parse_uid(token, &u);
323 if (r < 0)
324 return 0;
325
8411d2a2
LP
326 /* We ignore the passed value if anonymous authentication is
327 * on anyway. */
328 if (!b->anonymous_auth && u != b->ucred.uid)
2181a7f5
LP
329 return 0;
330
331 return 1;
332}
333
334static int bus_socket_auth_write(sd_bus *b, const char *t) {
335 char *p;
336 size_t l;
337
338 assert(b);
339 assert(t);
340
341 /* We only make use of the first iovec */
342 assert(b->auth_index == 0 || b->auth_index == 1);
343
344 l = strlen(t);
345 p = malloc(b->auth_iovec[0].iov_len + l);
346 if (!p)
347 return -ENOMEM;
348
349 memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
350 memcpy(p + b->auth_iovec[0].iov_len, t, l);
351
352 b->auth_iovec[0].iov_base = p;
353 b->auth_iovec[0].iov_len += l;
354
355 free(b->auth_buffer);
356 b->auth_buffer = p;
357 b->auth_index = 0;
358 return 0;
359}
360
361static int bus_socket_auth_write_ok(sd_bus *b) {
362 char t[3 + 32 + 2 + 1];
363
364 assert(b);
365
5ffa8c81 366 xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
367
368 return bus_socket_auth_write(b, t);
369}
370
371static int bus_socket_auth_verify_server(sd_bus *b) {
372 char *e;
373 const char *line;
374 size_t l;
375 bool processed = false;
376 int r;
377
378 assert(b);
379
2b4ac889 380 if (b->rbuffer_size < 1)
2181a7f5
LP
381 return 0;
382
383 /* First char must be a NUL byte */
384 if (*(char*) b->rbuffer != 0)
385 return -EIO;
386
2b4ac889
LP
387 if (b->rbuffer_size < 3)
388 return 0;
389
2181a7f5
LP
390 /* Begin with the first line */
391 if (b->auth_rbegin <= 0)
392 b->auth_rbegin = 1;
393
394 for (;;) {
395 /* Check if line is complete */
396 line = (char*) b->rbuffer + b->auth_rbegin;
397 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
398 if (!e)
399 return processed;
400
401 l = e - line;
402
403 if (line_begins(line, l, "AUTH ANONYMOUS")) {
404
405 r = verify_anonymous_token(b, line + 14, l - 14);
406 if (r < 0)
407 return r;
408 if (r == 0)
409 r = bus_socket_auth_write(b, "REJECTED\r\n");
410 else {
411 b->auth = BUS_AUTH_ANONYMOUS;
412 r = bus_socket_auth_write_ok(b);
413 }
414
415 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
416
417 r = verify_external_token(b, line + 13, l - 13);
418 if (r < 0)
419 return r;
420 if (r == 0)
421 r = bus_socket_auth_write(b, "REJECTED\r\n");
422 else {
423 b->auth = BUS_AUTH_EXTERNAL;
424 r = bus_socket_auth_write_ok(b);
425 }
426
427 } else if (line_begins(line, l, "AUTH"))
428 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
429 else if (line_equals(line, l, "CANCEL") ||
430 line_begins(line, l, "ERROR")) {
431
432 b->auth = _BUS_AUTH_INVALID;
433 r = bus_socket_auth_write(b, "REJECTED\r\n");
434
435 } else if (line_equals(line, l, "BEGIN")) {
436
437 if (b->auth == _BUS_AUTH_INVALID)
438 r = bus_socket_auth_write(b, "ERROR\r\n");
439 else {
440 /* We can't leave from the auth phase
441 * before we haven't written
442 * everything queued, so let's check
443 * that */
444
445 if (bus_socket_auth_needs_write(b))
446 return 1;
447
448 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
449 memmove(b->rbuffer, e + 2, b->rbuffer_size);
450 return bus_start_running(b);
451 }
452
453 } else if (line_begins(line, l, "DATA")) {
454
455 if (b->auth == _BUS_AUTH_INVALID)
456 r = bus_socket_auth_write(b, "ERROR\r\n");
457 else {
458 if (b->auth == BUS_AUTH_ANONYMOUS)
459 r = verify_anonymous_token(b, line + 4, l - 4);
460 else
461 r = verify_external_token(b, line + 4, l - 4);
462
463 if (r < 0)
464 return r;
465 if (r == 0) {
466 b->auth = _BUS_AUTH_INVALID;
467 r = bus_socket_auth_write(b, "REJECTED\r\n");
468 } else
469 r = bus_socket_auth_write_ok(b);
470 }
471 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
264ad849 472 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
2181a7f5
LP
473 r = bus_socket_auth_write(b, "ERROR\r\n");
474 else {
475 b->can_fds = true;
476 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
477 }
478 } else
479 r = bus_socket_auth_write(b, "ERROR\r\n");
480
481 if (r < 0)
482 return r;
483
484 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
485
486 processed = true;
487 }
488}
489
490static int bus_socket_auth_verify(sd_bus *b) {
491 assert(b);
492
493 if (b->is_server)
494 return bus_socket_auth_verify_server(b);
495 else
496 return bus_socket_auth_verify_client(b);
497}
498
a7e3212d
LP
499static int bus_socket_read_auth(sd_bus *b) {
500 struct msghdr mh;
7f4e6a1c 501 struct iovec iov = {};
a7e3212d
LP
502 size_t n;
503 ssize_t k;
504 int r;
505 void *p;
2181a7f5
LP
506 union {
507 struct cmsghdr cmsghdr;
d868f2a3 508 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
2181a7f5 509 } control;
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
a7e3212d
LP
533 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
534 iov.iov_len = n - b->rbuffer_size;
535
15d5af81
LP
536 if (b->prefer_readv)
537 k = readv(b->input_fd, &iov, 1);
538 else {
539 zero(mh);
540 mh.msg_iov = &iov;
541 mh.msg_iovlen = 1;
542 mh.msg_control = &control;
543 mh.msg_controllen = sizeof(control);
544
545 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
546 if (k < 0 && errno == ENOTSOCK) {
547 b->prefer_readv = true;
548 k = readv(b->input_fd, &iov, 1);
549 } else
550 handle_cmsg = true;
551 }
a7e3212d
LP
552 if (k < 0)
553 return errno == EAGAIN ? 0 : -errno;
554 if (k == 0)
555 return -ECONNRESET;
556
557 b->rbuffer_size += k;
558
2a1288ff
LP
559 if (handle_cmsg) {
560 struct cmsghdr *cmsg;
561
562 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
563 if (cmsg->cmsg_level == SOL_SOCKET &&
564 cmsg->cmsg_type == SCM_RIGHTS) {
565 int j;
566
567 /* Whut? We received fds during the auth
568 * protocol? Somebody is playing games with
569 * us. Close them all, and fail */
570 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
571 close_many((int*) CMSG_DATA(cmsg), j);
572 return -EIO;
d868f2a3
ZJS
573 } else
574 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
575 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 576 }
2181a7f5 577
a7e3212d
LP
578 r = bus_socket_auth_verify(b);
579 if (r != 0)
580 return r;
581
582 return 1;
583}
584
8f04d2eb 585void bus_socket_setup(sd_bus *b) {
a7e3212d
LP
586 assert(b);
587
aec6d91f
LP
588 /* Increase the buffers to 8 MB */
589 fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
590 fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 591
e1d337d4
LP
592 b->is_kernel = false;
593 b->message_version = 1;
0f437184 594 b->message_endian = 0;
8f04d2eb 595}
e1d337d4 596
8f04d2eb 597static void bus_get_peercred(sd_bus *b) {
c4e6556c
ZJS
598 int r;
599
8f04d2eb
LP
600 assert(b);
601
602 /* Get the peer for socketpair() sockets */
eff05270 603 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
c4e6556c
ZJS
604
605 /* Get the SELinux context of the peer */
606 r = getpeersec(b->input_fd, &b->label);
607 if (r < 0 && r != -EOPNOTSUPP)
608 log_debug_errno(r, "Failed to determine peer security context: %m");
a7e3212d
LP
609}
610
2181a7f5 611static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 612 size_t l;
2181a7f5 613 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
614
615 assert(b);
616
2181a7f5
LP
617 if (b->anonymous_auth) {
618 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 619
2181a7f5
LP
620 /* For ANONYMOUS auth we send some arbitrary "trace" string */
621 l = 9;
622 b->auth_buffer = hexmem("anonymous", l);
623 } else {
5ffa8c81 624 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 625
2181a7f5 626 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 627
5ffa8c81 628 xsprintf(text, UID_FMT, geteuid());
a7e3212d 629
2181a7f5
LP
630 l = strlen(text);
631 b->auth_buffer = hexmem(text, l);
632 }
633
634 if (!b->auth_buffer)
a7e3212d
LP
635 return -ENOMEM;
636
264ad849 637 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
638 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
639 else
640 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
641
642 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
643 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
644 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
645 b->auth_iovec[1].iov_len = l * 2;
646 b->auth_iovec[2].iov_base = (void*) auth_suffix;
647 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
648
649 return bus_socket_write_auth(b);
650}
651
a7893c6b 652int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
653 assert(b);
654
8f04d2eb
LP
655 bus_get_peercred(b);
656
2181a7f5
LP
657 b->state = BUS_AUTHENTICATING;
658 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
659
9ab32f9d 660 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 661 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 662
9ab32f9d
LP
663 if (b->output_fd != b->input_fd)
664 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 665 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 666
2181a7f5
LP
667 if (b->is_server)
668 return bus_socket_read_auth(b);
669 else
670 return bus_socket_start_auth_client(b);
671}
672
a7e3212d
LP
673int bus_socket_connect(sd_bus *b) {
674 int r;
675
676 assert(b);
e82c9509
LP
677 assert(b->input_fd < 0);
678 assert(b->output_fd < 0);
a7e3212d
LP
679 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
680
e82c9509
LP
681 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
682 if (b->input_fd < 0)
a7e3212d
LP
683 return -errno;
684
e82c9509
LP
685 b->output_fd = b->input_fd;
686
8f04d2eb 687 bus_socket_setup(b);
a7e3212d 688
e82c9509 689 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
690 if (r < 0) {
691 if (errno == EINPROGRESS)
692 return 1;
693
694 return -errno;
695 }
696
697 return bus_socket_start_auth(b);
698}
699
700int bus_socket_exec(sd_bus *b) {
e82c9509 701 int s[2], r;
a7e3212d
LP
702 pid_t pid;
703
704 assert(b);
e82c9509
LP
705 assert(b->input_fd < 0);
706 assert(b->output_fd < 0);
a7e3212d
LP
707 assert(b->exec_path);
708
e82c9509
LP
709 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
710 if (r < 0)
a7e3212d
LP
711 return -errno;
712
713 pid = fork();
714 if (pid < 0) {
3d94f76c 715 safe_close_pair(s);
a7e3212d
LP
716 return -errno;
717 }
718 if (pid == 0) {
719 /* Child */
720
ce30c8dc
LP
721 (void) reset_all_signal_handlers();
722 (void) reset_signal_mask();
e82c9509
LP
723
724 close_all_fds(s+1, 1);
a7e3212d
LP
725
726 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
727 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
728
729 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
03e334a1 730 safe_close(s[1]);
a7e3212d
LP
731
732 fd_cloexec(STDIN_FILENO, false);
733 fd_cloexec(STDOUT_FILENO, false);
734 fd_nonblock(STDIN_FILENO, false);
735 fd_nonblock(STDOUT_FILENO, false);
736
737 if (b->exec_argv)
738 execvp(b->exec_path, b->exec_argv);
739 else {
740 const char *argv[] = { b->exec_path, NULL };
741 execvp(b->exec_path, (char**) argv);
742 }
743
744 _exit(EXIT_FAILURE);
745 }
746
03e334a1 747 safe_close(s[1]);
e82c9509 748 b->output_fd = b->input_fd = s[0];
a7e3212d 749
8f04d2eb 750 bus_socket_setup(b);
e1d337d4 751
a7e3212d
LP
752 return bus_socket_start_auth(b);
753}
754
755int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
756 assert(b);
757
8f04d2eb 758 bus_socket_setup(b);
a7e3212d
LP
759
760 return bus_socket_start_auth(b);
761}
762
763int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
764 struct iovec *iov;
765 ssize_t k;
766 size_t n;
767 unsigned j;
bc7fd8cd 768 int r;
a7e3212d
LP
769
770 assert(bus);
771 assert(m);
772 assert(idx);
773 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
774
6629161f 775 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 776 return 0;
a7e3212d 777
bc7fd8cd
LP
778 r = bus_message_setup_iovec(m);
779 if (r < 0)
780 return r;
2100fa10 781
a7e3212d
LP
782 n = m->n_iovec * sizeof(struct iovec);
783 iov = alloca(n);
784 memcpy(iov, m->iovec, n);
785
786 j = 0;
787 iovec_advance(iov, &j, *idx);
788
15d5af81
LP
789 if (bus->prefer_writev)
790 k = writev(bus->output_fd, iov, m->n_iovec);
791 else {
7f4e6a1c
ZJS
792 struct msghdr mh = {
793 .msg_iov = iov,
794 .msg_iovlen = m->n_iovec,
795 };
15d5af81
LP
796
797 if (m->n_fds > 0) {
798 struct cmsghdr *control;
15d5af81 799
7f4e6a1c
ZJS
800 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
801 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
15d5af81
LP
802 control->cmsg_level = SOL_SOCKET;
803 control->cmsg_type = SCM_RIGHTS;
15d5af81
LP
804 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
805 }
806
15d5af81
LP
807 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
808 if (k < 0 && errno == ENOTSOCK) {
809 bus->prefer_writev = true;
810 k = writev(bus->output_fd, iov, m->n_iovec);
811 }
812 }
a7e3212d 813
a7e3212d
LP
814 if (k < 0)
815 return errno == EAGAIN ? 0 : -errno;
816
817 *idx += (size_t) k;
818 return 1;
819}
820
821static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
822 uint32_t a, b;
823 uint8_t e;
824 uint64_t sum;
825
826 assert(bus);
827 assert(need);
828 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
829
830 if (bus->rbuffer_size < sizeof(struct bus_header)) {
831 *need = sizeof(struct bus_header) + 8;
832
833 /* Minimum message size:
834 *
835 * Header +
836 *
837 * Method Call: +2 string headers
838 * Signal: +3 string headers
839 * Method Error: +1 string headers
840 * +1 uint32 headers
841 * Method Reply: +1 uint32 headers
842 *
843 * A string header is at least 9 bytes
844 * A uint32 header is at least 8 bytes
845 *
846 * Hence the minimum message size of a valid message
847 * is header + 8 bytes */
848
849 return 0;
850 }
851
852 a = ((const uint32_t*) bus->rbuffer)[1];
853 b = ((const uint32_t*) bus->rbuffer)[3];
854
855 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 856 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
857 a = le32toh(a);
858 b = le32toh(b);
0461f8cd 859 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
860 a = be32toh(a);
861 b = be32toh(b);
862 } else
863 return -EBADMSG;
864
865 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
866 if (sum >= BUS_MESSAGE_SIZE_MAX)
867 return -ENOBUFS;
868
869 *need = (size_t) sum;
870 return 0;
871}
872
7d22c717 873static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
874 sd_bus_message *t;
875 void *b;
876 int r;
877
878 assert(bus);
a7e3212d
LP
879 assert(bus->rbuffer_size >= size);
880 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
881
7adc46fc
LP
882 r = bus_rqueue_make_room(bus);
883 if (r < 0)
884 return r;
885
a7e3212d
LP
886 if (bus->rbuffer_size > size) {
887 b = memdup((const uint8_t*) bus->rbuffer + size,
888 bus->rbuffer_size - size);
889 if (!b)
890 return -ENOMEM;
891 } else
892 b = NULL;
893
df2d202e
LP
894 r = bus_message_from_malloc(bus,
895 bus->rbuffer, size,
a7e3212d 896 bus->fds, bus->n_fds,
038f9863 897 NULL,
a7e3212d
LP
898 &t);
899 if (r < 0) {
900 free(b);
901 return r;
902 }
903
904 bus->rbuffer = b;
905 bus->rbuffer_size -= size;
906
907 bus->fds = NULL;
908 bus->n_fds = 0;
909
7adc46fc 910 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 911
a7e3212d
LP
912 return 1;
913}
914
7d22c717 915int bus_socket_read_message(sd_bus *bus) {
a7e3212d 916 struct msghdr mh;
7f4e6a1c 917 struct iovec iov = {};
a7e3212d
LP
918 ssize_t k;
919 size_t need;
920 int r;
921 void *b;
922 union {
923 struct cmsghdr cmsghdr;
d868f2a3 924 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
a7e3212d 925 } control;
4d3a5b10 926 bool handle_cmsg = false;
a7e3212d
LP
927
928 assert(bus);
a7e3212d
LP
929 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
930
931 r = bus_socket_read_message_need(bus, &need);
932 if (r < 0)
933 return r;
934
935 if (bus->rbuffer_size >= need)
7d22c717 936 return bus_socket_make_message(bus, need);
a7e3212d
LP
937
938 b = realloc(bus->rbuffer, need);
939 if (!b)
940 return -ENOMEM;
941
942 bus->rbuffer = b;
943
a7e3212d
LP
944 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
945 iov.iov_len = need - bus->rbuffer_size;
946
15d5af81
LP
947 if (bus->prefer_readv)
948 k = readv(bus->input_fd, &iov, 1);
949 else {
950 zero(mh);
951 mh.msg_iov = &iov;
952 mh.msg_iovlen = 1;
953 mh.msg_control = &control;
954 mh.msg_controllen = sizeof(control);
955
956 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
957 if (k < 0 && errno == ENOTSOCK) {
958 bus->prefer_readv = true;
959 k = readv(bus->input_fd, &iov, 1);
960 } else
961 handle_cmsg = true;
962 }
a7e3212d
LP
963 if (k < 0)
964 return errno == EAGAIN ? 0 : -errno;
965 if (k == 0)
966 return -ECONNRESET;
967
968 bus->rbuffer_size += k;
969
2a1288ff
LP
970 if (handle_cmsg) {
971 struct cmsghdr *cmsg;
972
973 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
974 if (cmsg->cmsg_level == SOL_SOCKET &&
975 cmsg->cmsg_type == SCM_RIGHTS) {
976 int n, *f;
977
978 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
979
980 if (!bus->can_fds) {
981 /* Whut? We received fds but this
982 * isn't actually enabled? Close them,
983 * and fail */
984
985 close_many((int*) CMSG_DATA(cmsg), n);
986 return -EIO;
987 }
988
a0f5ab70 989 f = realloc(bus->fds, sizeof(int) * (bus->n_fds + n));
15d5af81
LP
990 if (!f) {
991 close_many((int*) CMSG_DATA(cmsg), n);
992 return -ENOMEM;
993 }
994
995 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
996 bus->fds = f;
997 bus->n_fds += n;
d868f2a3
ZJS
998 } else
999 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
1000 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 1001 }
a7e3212d
LP
1002
1003 r = bus_socket_read_message_need(bus, &need);
1004 if (r < 0)
1005 return r;
1006
1007 if (bus->rbuffer_size >= need)
7d22c717 1008 return bus_socket_make_message(bus, need);
a7e3212d
LP
1009
1010 return 1;
1011}
1012
1013int bus_socket_process_opening(sd_bus *b) {
1014 int error = 0;
1015 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1016 struct pollfd p = {
1017 .fd = b->output_fd,
1018 .events = POLLOUT,
1019 };
a7e3212d
LP
1020 int r;
1021
a7e3212d
LP
1022 assert(b->state == BUS_OPENING);
1023
a7e3212d
LP
1024 r = poll(&p, 1, 0);
1025 if (r < 0)
1026 return -errno;
1027
1028 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1029 return 0;
1030
e82c9509 1031 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1032 if (r < 0)
1033 b->last_connect_error = errno;
1034 else if (error != 0)
1035 b->last_connect_error = error;
1036 else if (p.revents & (POLLERR|POLLHUP))
1037 b->last_connect_error = ECONNREFUSED;
1038 else
1039 return bus_socket_start_auth(b);
1040
1041 return bus_next_address(b);
1042}
1043
1044int bus_socket_process_authenticating(sd_bus *b) {
1045 int r;
1046
1047 assert(b);
1048 assert(b->state == BUS_AUTHENTICATING);
1049
1050 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1051 return -ETIMEDOUT;
1052
1053 r = bus_socket_write_auth(b);
1054 if (r != 0)
1055 return r;
1056
1057 return bus_socket_read_auth(b);
1058}