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