]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
Merge pull request #2706 from whot/hwdb-updates
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-socket.c
CommitLineData
a7e3212d
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2013 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <endian.h>
07630cea 21#include <poll.h>
a7e3212d
LP
22#include <stdlib.h>
23#include <unistd.h>
a7e3212d 24
07630cea 25#include "sd-bus.h"
24882e06 26#include "sd-daemon.h"
07630cea 27
b5efdb8a 28#include "alloc-util.h"
07630cea
LP
29#include "bus-internal.h"
30#include "bus-message.h"
3ffd4af2
LP
31#include "bus-socket.h"
32#include "fd-util.h"
07630cea 33#include "formats-util.h"
15a5e950 34#include "hexdecoct.h"
a7e3212d
LP
35#include "macro.h"
36#include "missing.h"
7fc04b12 37#include "selinux-util.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
75f32f04 353 memcpy_safe(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
2181a7f5
LP
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 */
6355e756 610 if (mac_selinux_have()) {
7fc04b12
LP
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");
614 }
a7e3212d
LP
615}
616
2181a7f5 617static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 618 size_t l;
2181a7f5 619 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
620
621 assert(b);
622
2181a7f5
LP
623 if (b->anonymous_auth) {
624 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 625
2181a7f5
LP
626 /* For ANONYMOUS auth we send some arbitrary "trace" string */
627 l = 9;
628 b->auth_buffer = hexmem("anonymous", l);
629 } else {
5ffa8c81 630 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 631
2181a7f5 632 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 633
5ffa8c81 634 xsprintf(text, UID_FMT, geteuid());
a7e3212d 635
2181a7f5
LP
636 l = strlen(text);
637 b->auth_buffer = hexmem(text, l);
638 }
639
640 if (!b->auth_buffer)
a7e3212d
LP
641 return -ENOMEM;
642
264ad849 643 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
644 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
645 else
646 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
647
648 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
649 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
650 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
651 b->auth_iovec[1].iov_len = l * 2;
652 b->auth_iovec[2].iov_base = (void*) auth_suffix;
653 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
654
655 return bus_socket_write_auth(b);
656}
657
a7893c6b 658int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
659 assert(b);
660
8f04d2eb
LP
661 bus_get_peercred(b);
662
2181a7f5
LP
663 b->state = BUS_AUTHENTICATING;
664 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
665
9ab32f9d 666 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 667 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 668
9ab32f9d
LP
669 if (b->output_fd != b->input_fd)
670 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 671 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 672
2181a7f5
LP
673 if (b->is_server)
674 return bus_socket_read_auth(b);
675 else
676 return bus_socket_start_auth_client(b);
677}
678
a7e3212d
LP
679int bus_socket_connect(sd_bus *b) {
680 int r;
681
682 assert(b);
e82c9509
LP
683 assert(b->input_fd < 0);
684 assert(b->output_fd < 0);
a7e3212d
LP
685 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
686
e82c9509
LP
687 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
688 if (b->input_fd < 0)
a7e3212d
LP
689 return -errno;
690
e82c9509
LP
691 b->output_fd = b->input_fd;
692
8f04d2eb 693 bus_socket_setup(b);
a7e3212d 694
e82c9509 695 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
696 if (r < 0) {
697 if (errno == EINPROGRESS)
698 return 1;
699
700 return -errno;
701 }
702
703 return bus_socket_start_auth(b);
704}
705
706int bus_socket_exec(sd_bus *b) {
e82c9509 707 int s[2], r;
a7e3212d
LP
708 pid_t pid;
709
710 assert(b);
e82c9509
LP
711 assert(b->input_fd < 0);
712 assert(b->output_fd < 0);
a7e3212d
LP
713 assert(b->exec_path);
714
e82c9509
LP
715 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
716 if (r < 0)
a7e3212d
LP
717 return -errno;
718
719 pid = fork();
720 if (pid < 0) {
3d94f76c 721 safe_close_pair(s);
a7e3212d
LP
722 return -errno;
723 }
724 if (pid == 0) {
725 /* Child */
726
ce30c8dc
LP
727 (void) reset_all_signal_handlers();
728 (void) reset_signal_mask();
e82c9509
LP
729
730 close_all_fds(s+1, 1);
a7e3212d
LP
731
732 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
733 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
734
735 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
03e334a1 736 safe_close(s[1]);
a7e3212d
LP
737
738 fd_cloexec(STDIN_FILENO, false);
739 fd_cloexec(STDOUT_FILENO, false);
740 fd_nonblock(STDIN_FILENO, false);
741 fd_nonblock(STDOUT_FILENO, false);
742
743 if (b->exec_argv)
744 execvp(b->exec_path, b->exec_argv);
745 else {
746 const char *argv[] = { b->exec_path, NULL };
747 execvp(b->exec_path, (char**) argv);
748 }
749
750 _exit(EXIT_FAILURE);
751 }
752
03e334a1 753 safe_close(s[1]);
e82c9509 754 b->output_fd = b->input_fd = s[0];
a7e3212d 755
8f04d2eb 756 bus_socket_setup(b);
e1d337d4 757
a7e3212d
LP
758 return bus_socket_start_auth(b);
759}
760
761int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
762 assert(b);
763
8f04d2eb 764 bus_socket_setup(b);
a7e3212d
LP
765
766 return bus_socket_start_auth(b);
767}
768
769int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
770 struct iovec *iov;
771 ssize_t k;
772 size_t n;
773 unsigned j;
bc7fd8cd 774 int r;
a7e3212d
LP
775
776 assert(bus);
777 assert(m);
778 assert(idx);
779 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
780
6629161f 781 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 782 return 0;
a7e3212d 783
bc7fd8cd
LP
784 r = bus_message_setup_iovec(m);
785 if (r < 0)
786 return r;
2100fa10 787
a7e3212d
LP
788 n = m->n_iovec * sizeof(struct iovec);
789 iov = alloca(n);
75f32f04 790 memcpy_safe(iov, m->iovec, n);
a7e3212d
LP
791
792 j = 0;
793 iovec_advance(iov, &j, *idx);
794
15d5af81
LP
795 if (bus->prefer_writev)
796 k = writev(bus->output_fd, iov, m->n_iovec);
797 else {
7f4e6a1c
ZJS
798 struct msghdr mh = {
799 .msg_iov = iov,
800 .msg_iovlen = m->n_iovec,
801 };
15d5af81
LP
802
803 if (m->n_fds > 0) {
804 struct cmsghdr *control;
15d5af81 805
7f4e6a1c
ZJS
806 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
807 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
15d5af81
LP
808 control->cmsg_level = SOL_SOCKET;
809 control->cmsg_type = SCM_RIGHTS;
15d5af81
LP
810 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
811 }
812
15d5af81
LP
813 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
814 if (k < 0 && errno == ENOTSOCK) {
815 bus->prefer_writev = true;
816 k = writev(bus->output_fd, iov, m->n_iovec);
817 }
818 }
a7e3212d 819
a7e3212d
LP
820 if (k < 0)
821 return errno == EAGAIN ? 0 : -errno;
822
823 *idx += (size_t) k;
824 return 1;
825}
826
827static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
828 uint32_t a, b;
829 uint8_t e;
830 uint64_t sum;
831
832 assert(bus);
833 assert(need);
834 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
835
836 if (bus->rbuffer_size < sizeof(struct bus_header)) {
837 *need = sizeof(struct bus_header) + 8;
838
839 /* Minimum message size:
840 *
841 * Header +
842 *
843 * Method Call: +2 string headers
844 * Signal: +3 string headers
845 * Method Error: +1 string headers
846 * +1 uint32 headers
847 * Method Reply: +1 uint32 headers
848 *
849 * A string header is at least 9 bytes
850 * A uint32 header is at least 8 bytes
851 *
852 * Hence the minimum message size of a valid message
853 * is header + 8 bytes */
854
855 return 0;
856 }
857
858 a = ((const uint32_t*) bus->rbuffer)[1];
859 b = ((const uint32_t*) bus->rbuffer)[3];
860
861 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 862 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
863 a = le32toh(a);
864 b = le32toh(b);
0461f8cd 865 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
866 a = be32toh(a);
867 b = be32toh(b);
868 } else
869 return -EBADMSG;
870
871 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
872 if (sum >= BUS_MESSAGE_SIZE_MAX)
873 return -ENOBUFS;
874
875 *need = (size_t) sum;
876 return 0;
877}
878
7d22c717 879static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
880 sd_bus_message *t;
881 void *b;
882 int r;
883
884 assert(bus);
a7e3212d
LP
885 assert(bus->rbuffer_size >= size);
886 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
887
7adc46fc
LP
888 r = bus_rqueue_make_room(bus);
889 if (r < 0)
890 return r;
891
a7e3212d
LP
892 if (bus->rbuffer_size > size) {
893 b = memdup((const uint8_t*) bus->rbuffer + size,
894 bus->rbuffer_size - size);
895 if (!b)
896 return -ENOMEM;
897 } else
898 b = NULL;
899
df2d202e
LP
900 r = bus_message_from_malloc(bus,
901 bus->rbuffer, size,
a7e3212d 902 bus->fds, bus->n_fds,
038f9863 903 NULL,
a7e3212d
LP
904 &t);
905 if (r < 0) {
906 free(b);
907 return r;
908 }
909
910 bus->rbuffer = b;
911 bus->rbuffer_size -= size;
912
913 bus->fds = NULL;
914 bus->n_fds = 0;
915
7adc46fc 916 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 917
a7e3212d
LP
918 return 1;
919}
920
7d22c717 921int bus_socket_read_message(sd_bus *bus) {
a7e3212d 922 struct msghdr mh;
7f4e6a1c 923 struct iovec iov = {};
a7e3212d
LP
924 ssize_t k;
925 size_t need;
926 int r;
927 void *b;
928 union {
929 struct cmsghdr cmsghdr;
d868f2a3 930 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
a7e3212d 931 } control;
4d3a5b10 932 bool handle_cmsg = false;
a7e3212d
LP
933
934 assert(bus);
a7e3212d
LP
935 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
936
937 r = bus_socket_read_message_need(bus, &need);
938 if (r < 0)
939 return r;
940
941 if (bus->rbuffer_size >= need)
7d22c717 942 return bus_socket_make_message(bus, need);
a7e3212d
LP
943
944 b = realloc(bus->rbuffer, need);
945 if (!b)
946 return -ENOMEM;
947
948 bus->rbuffer = b;
949
a7e3212d
LP
950 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
951 iov.iov_len = need - bus->rbuffer_size;
952
15d5af81
LP
953 if (bus->prefer_readv)
954 k = readv(bus->input_fd, &iov, 1);
955 else {
956 zero(mh);
957 mh.msg_iov = &iov;
958 mh.msg_iovlen = 1;
959 mh.msg_control = &control;
960 mh.msg_controllen = sizeof(control);
961
962 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
963 if (k < 0 && errno == ENOTSOCK) {
964 bus->prefer_readv = true;
965 k = readv(bus->input_fd, &iov, 1);
966 } else
967 handle_cmsg = true;
968 }
a7e3212d
LP
969 if (k < 0)
970 return errno == EAGAIN ? 0 : -errno;
971 if (k == 0)
972 return -ECONNRESET;
973
974 bus->rbuffer_size += k;
975
2a1288ff
LP
976 if (handle_cmsg) {
977 struct cmsghdr *cmsg;
978
979 CMSG_FOREACH(cmsg, &mh)
15d5af81
LP
980 if (cmsg->cmsg_level == SOL_SOCKET &&
981 cmsg->cmsg_type == SCM_RIGHTS) {
982 int n, *f;
983
984 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
985
986 if (!bus->can_fds) {
987 /* Whut? We received fds but this
988 * isn't actually enabled? Close them,
989 * and fail */
990
991 close_many((int*) CMSG_DATA(cmsg), n);
992 return -EIO;
993 }
994
a0f5ab70 995 f = realloc(bus->fds, sizeof(int) * (bus->n_fds + n));
15d5af81
LP
996 if (!f) {
997 close_many((int*) CMSG_DATA(cmsg), n);
998 return -ENOMEM;
999 }
1000
75f32f04 1001 memcpy_safe(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
15d5af81
LP
1002 bus->fds = f;
1003 bus->n_fds += n;
d868f2a3
ZJS
1004 } else
1005 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
1006 cmsg->cmsg_level, cmsg->cmsg_type);
2a1288ff 1007 }
a7e3212d
LP
1008
1009 r = bus_socket_read_message_need(bus, &need);
1010 if (r < 0)
1011 return r;
1012
1013 if (bus->rbuffer_size >= need)
7d22c717 1014 return bus_socket_make_message(bus, need);
a7e3212d
LP
1015
1016 return 1;
1017}
1018
1019int bus_socket_process_opening(sd_bus *b) {
1020 int error = 0;
1021 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1022 struct pollfd p = {
1023 .fd = b->output_fd,
1024 .events = POLLOUT,
1025 };
a7e3212d
LP
1026 int r;
1027
a7e3212d
LP
1028 assert(b->state == BUS_OPENING);
1029
a7e3212d
LP
1030 r = poll(&p, 1, 0);
1031 if (r < 0)
1032 return -errno;
1033
1034 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1035 return 0;
1036
e82c9509 1037 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1038 if (r < 0)
1039 b->last_connect_error = errno;
1040 else if (error != 0)
1041 b->last_connect_error = error;
1042 else if (p.revents & (POLLERR|POLLHUP))
1043 b->last_connect_error = ECONNREFUSED;
1044 else
1045 return bus_socket_start_auth(b);
1046
1047 return bus_next_address(b);
1048}
1049
1050int bus_socket_process_authenticating(sd_bus *b) {
1051 int r;
1052
1053 assert(b);
1054 assert(b->state == BUS_AUTHENTICATING);
1055
1056 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1057 return -ETIMEDOUT;
1058
1059 r = bus_socket_write_auth(b);
1060 if (r != 0)
1061 return r;
1062
1063 return bus_socket_read_auth(b);
1064}