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