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