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