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