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