]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: always talk to the full dbus driver object
[thirdparty/systemd.git] / src / libsystemd-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 =
230 (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
231 memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
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
a7893c6b 605int bus_socket_setup(sd_bus *b) {
0f4b73c8 606 int enable;
ea8f194f 607 socklen_t l;
a7e3212d
LP
608
609 assert(b);
610
d65ddaa4
LP
611 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
612 * socket, just in case. */
0f4b73c8 613 enable = !b->bus_client;
e82c9509 614 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
264ad849 615
d21a7bb1 616 enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
e82c9509 617 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d 618
aec6d91f
LP
619 /* Increase the buffers to 8 MB */
620 fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
621 fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 622
ea8f194f
LP
623 /* Get the peer for socketpair() sockets */
624 l = sizeof(b->ucred);
625 if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
626 b->ucred_valid = b->ucred.pid > 0;
627
e1d337d4
LP
628 b->is_kernel = false;
629 b->message_version = 1;
0f437184 630 b->message_endian = 0;
e1d337d4 631
a7e3212d
LP
632 return 0;
633}
634
2181a7f5 635static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 636 size_t l;
2181a7f5 637 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
638
639 assert(b);
640
2181a7f5
LP
641 if (b->anonymous_auth) {
642 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 643
2181a7f5
LP
644 /* For ANONYMOUS auth we send some arbitrary "trace" string */
645 l = 9;
646 b->auth_buffer = hexmem("anonymous", l);
647 } else {
648 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 649
2181a7f5 650 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 651
2181a7f5
LP
652 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
653 char_array_0(text);
a7e3212d 654
2181a7f5
LP
655 l = strlen(text);
656 b->auth_buffer = hexmem(text, l);
657 }
658
659 if (!b->auth_buffer)
a7e3212d
LP
660 return -ENOMEM;
661
264ad849 662 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
663 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
664 else
665 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
666
667 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
668 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
669 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
670 b->auth_iovec[1].iov_len = l * 2;
671 b->auth_iovec[2].iov_base = (void*) auth_suffix;
672 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
673
674 return bus_socket_write_auth(b);
675}
676
a7893c6b 677int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
678 assert(b);
679
680 b->state = BUS_AUTHENTICATING;
681 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
682
9ab32f9d 683 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 684 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 685
9ab32f9d
LP
686 if (b->output_fd != b->input_fd)
687 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 688 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 689
2181a7f5
LP
690 if (b->is_server)
691 return bus_socket_read_auth(b);
692 else
693 return bus_socket_start_auth_client(b);
694}
695
a7e3212d
LP
696int bus_socket_connect(sd_bus *b) {
697 int r;
698
699 assert(b);
e82c9509
LP
700 assert(b->input_fd < 0);
701 assert(b->output_fd < 0);
a7e3212d
LP
702 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
703
e82c9509
LP
704 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
705 if (b->input_fd < 0)
a7e3212d
LP
706 return -errno;
707
e82c9509
LP
708 b->output_fd = b->input_fd;
709
a7e3212d
LP
710 r = bus_socket_setup(b);
711 if (r < 0)
712 return r;
713
e82c9509 714 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
715 if (r < 0) {
716 if (errno == EINPROGRESS)
717 return 1;
718
719 return -errno;
720 }
721
722 return bus_socket_start_auth(b);
723}
724
725int bus_socket_exec(sd_bus *b) {
e82c9509 726 int s[2], r;
a7e3212d
LP
727 pid_t pid;
728
729 assert(b);
e82c9509
LP
730 assert(b->input_fd < 0);
731 assert(b->output_fd < 0);
a7e3212d
LP
732 assert(b->exec_path);
733
e82c9509
LP
734 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
735 if (r < 0)
a7e3212d
LP
736 return -errno;
737
738 pid = fork();
739 if (pid < 0) {
740 close_pipe(s);
741 return -errno;
742 }
743 if (pid == 0) {
744 /* Child */
745
e82c9509
LP
746 reset_all_signal_handlers();
747
748 close_all_fds(s+1, 1);
a7e3212d
LP
749
750 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
751 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
752
753 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
754 close_nointr_nofail(s[1]);
755
756 fd_cloexec(STDIN_FILENO, false);
757 fd_cloexec(STDOUT_FILENO, false);
758 fd_nonblock(STDIN_FILENO, false);
759 fd_nonblock(STDOUT_FILENO, false);
760
761 if (b->exec_argv)
762 execvp(b->exec_path, b->exec_argv);
763 else {
764 const char *argv[] = { b->exec_path, NULL };
765 execvp(b->exec_path, (char**) argv);
766 }
767
768 _exit(EXIT_FAILURE);
769 }
770
771 close_nointr_nofail(s[1]);
e82c9509 772 b->output_fd = b->input_fd = s[0];
a7e3212d 773
e1d337d4
LP
774 r = bus_socket_setup(b);
775 if (r < 0)
776 return r;
777
a7e3212d
LP
778 return bus_socket_start_auth(b);
779}
780
781int bus_socket_take_fd(sd_bus *b) {
782 int r;
783 assert(b);
784
785 r = bus_socket_setup(b);
786 if (r < 0)
787 return r;
788
789 return bus_socket_start_auth(b);
790}
791
792int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
793 struct iovec *iov;
794 ssize_t k;
795 size_t n;
796 unsigned j;
bc7fd8cd 797 int r;
a7e3212d
LP
798
799 assert(bus);
800 assert(m);
801 assert(idx);
802 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
803
6629161f 804 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 805 return 0;
a7e3212d 806
bc7fd8cd
LP
807 r = bus_message_setup_iovec(m);
808 if (r < 0)
809 return r;
2100fa10 810
a7e3212d
LP
811 n = m->n_iovec * sizeof(struct iovec);
812 iov = alloca(n);
813 memcpy(iov, m->iovec, n);
814
815 j = 0;
816 iovec_advance(iov, &j, *idx);
817
15d5af81
LP
818 if (bus->prefer_writev)
819 k = writev(bus->output_fd, iov, m->n_iovec);
820 else {
821 struct msghdr mh;
822 zero(mh);
823
824 if (m->n_fds > 0) {
825 struct cmsghdr *control;
826 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
827
828 mh.msg_control = control;
829 control->cmsg_level = SOL_SOCKET;
830 control->cmsg_type = SCM_RIGHTS;
831 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
832 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
833 }
834
835 mh.msg_iov = iov;
836 mh.msg_iovlen = m->n_iovec;
837
838 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
839 if (k < 0 && errno == ENOTSOCK) {
840 bus->prefer_writev = true;
841 k = writev(bus->output_fd, iov, m->n_iovec);
842 }
843 }
a7e3212d 844
a7e3212d
LP
845 if (k < 0)
846 return errno == EAGAIN ? 0 : -errno;
847
848 *idx += (size_t) k;
849 return 1;
850}
851
852static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
853 uint32_t a, b;
854 uint8_t e;
855 uint64_t sum;
856
857 assert(bus);
858 assert(need);
859 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
860
861 if (bus->rbuffer_size < sizeof(struct bus_header)) {
862 *need = sizeof(struct bus_header) + 8;
863
864 /* Minimum message size:
865 *
866 * Header +
867 *
868 * Method Call: +2 string headers
869 * Signal: +3 string headers
870 * Method Error: +1 string headers
871 * +1 uint32 headers
872 * Method Reply: +1 uint32 headers
873 *
874 * A string header is at least 9 bytes
875 * A uint32 header is at least 8 bytes
876 *
877 * Hence the minimum message size of a valid message
878 * is header + 8 bytes */
879
880 return 0;
881 }
882
883 a = ((const uint32_t*) bus->rbuffer)[1];
884 b = ((const uint32_t*) bus->rbuffer)[3];
885
886 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 887 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
888 a = le32toh(a);
889 b = le32toh(b);
0461f8cd 890 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
891 a = be32toh(a);
892 b = be32toh(b);
893 } else
894 return -EBADMSG;
895
896 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
897 if (sum >= BUS_MESSAGE_SIZE_MAX)
898 return -ENOBUFS;
899
900 *need = (size_t) sum;
901 return 0;
902}
903
7d22c717 904static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
905 sd_bus_message *t;
906 void *b;
907 int r;
908
909 assert(bus);
a7e3212d
LP
910 assert(bus->rbuffer_size >= size);
911 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
912
7adc46fc
LP
913 r = bus_rqueue_make_room(bus);
914 if (r < 0)
915 return r;
916
a7e3212d
LP
917 if (bus->rbuffer_size > size) {
918 b = memdup((const uint8_t*) bus->rbuffer + size,
919 bus->rbuffer_size - size);
920 if (!b)
921 return -ENOMEM;
922 } else
923 b = NULL;
924
df2d202e
LP
925 r = bus_message_from_malloc(bus,
926 bus->rbuffer, size,
a7e3212d 927 bus->fds, bus->n_fds,
0f4b73c8
LP
928 bus->ucred_valid ? &bus->ucred : NULL,
929 bus->label[0] ? bus->label : NULL,
a7e3212d
LP
930 &t);
931 if (r < 0) {
932 free(b);
933 return r;
934 }
935
936 bus->rbuffer = b;
937 bus->rbuffer_size -= size;
938
939 bus->fds = NULL;
940 bus->n_fds = 0;
941
7adc46fc 942 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 943
a7e3212d
LP
944 return 1;
945}
946
7d22c717 947int bus_socket_read_message(sd_bus *bus) {
a7e3212d
LP
948 struct msghdr mh;
949 struct iovec iov;
950 ssize_t k;
951 size_t need;
952 int r;
953 void *b;
954 union {
955 struct cmsghdr cmsghdr;
956 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
957 CMSG_SPACE(sizeof(struct ucred)) +
958 CMSG_SPACE(NAME_MAX)]; /*selinux label */
959 } control;
960 struct cmsghdr *cmsg;
4d3a5b10 961 bool handle_cmsg = false;
a7e3212d
LP
962
963 assert(bus);
a7e3212d
LP
964 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
965
966 r = bus_socket_read_message_need(bus, &need);
967 if (r < 0)
968 return r;
969
970 if (bus->rbuffer_size >= need)
7d22c717 971 return bus_socket_make_message(bus, need);
a7e3212d
LP
972
973 b = realloc(bus->rbuffer, need);
974 if (!b)
975 return -ENOMEM;
976
977 bus->rbuffer = b;
978
979 zero(iov);
980 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
981 iov.iov_len = need - bus->rbuffer_size;
982
15d5af81
LP
983 if (bus->prefer_readv)
984 k = readv(bus->input_fd, &iov, 1);
985 else {
986 zero(mh);
987 mh.msg_iov = &iov;
988 mh.msg_iovlen = 1;
989 mh.msg_control = &control;
990 mh.msg_controllen = sizeof(control);
991
992 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
993 if (k < 0 && errno == ENOTSOCK) {
994 bus->prefer_readv = true;
995 k = readv(bus->input_fd, &iov, 1);
996 } else
997 handle_cmsg = true;
998 }
a7e3212d
LP
999 if (k < 0)
1000 return errno == EAGAIN ? 0 : -errno;
1001 if (k == 0)
1002 return -ECONNRESET;
1003
1004 bus->rbuffer_size += k;
1005
15d5af81
LP
1006 if (handle_cmsg) {
1007 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
1008 if (cmsg->cmsg_level == SOL_SOCKET &&
1009 cmsg->cmsg_type == SCM_RIGHTS) {
1010 int n, *f;
1011
1012 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1013
1014 if (!bus->can_fds) {
1015 /* Whut? We received fds but this
1016 * isn't actually enabled? Close them,
1017 * and fail */
1018
1019 close_many((int*) CMSG_DATA(cmsg), n);
1020 return -EIO;
1021 }
1022
1023 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1024 if (!f) {
1025 close_many((int*) CMSG_DATA(cmsg), n);
1026 return -ENOMEM;
1027 }
1028
1029 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1030 bus->fds = f;
1031 bus->n_fds += n;
1032 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1033 cmsg->cmsg_type == SCM_CREDENTIALS &&
1034 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1035
ea8f194f
LP
1036 /* Ignore bogus data, which we might
1037 * get on socketpair() sockets */
1038 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1039 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1040 bus->ucred_valid = true;
1041 }
15d5af81
LP
1042
1043 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1044 cmsg->cmsg_type == SCM_SECURITY) {
1045
1046 size_t l;
1047 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1048 if (l > 0) {
1049 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1050 bus->label[l] = 0;
1051 }
a7e3212d 1052 }
a7e3212d
LP
1053 }
1054 }
1055
1056 r = bus_socket_read_message_need(bus, &need);
1057 if (r < 0)
1058 return r;
1059
1060 if (bus->rbuffer_size >= need)
7d22c717 1061 return bus_socket_make_message(bus, need);
a7e3212d
LP
1062
1063 return 1;
1064}
1065
1066int bus_socket_process_opening(sd_bus *b) {
1067 int error = 0;
1068 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1069 struct pollfd p = {
1070 .fd = b->output_fd,
1071 .events = POLLOUT,
1072 };
a7e3212d
LP
1073 int r;
1074
a7e3212d
LP
1075 assert(b->state == BUS_OPENING);
1076
a7e3212d
LP
1077 r = poll(&p, 1, 0);
1078 if (r < 0)
1079 return -errno;
1080
1081 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1082 return 0;
1083
e82c9509 1084 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1085 if (r < 0)
1086 b->last_connect_error = errno;
1087 else if (error != 0)
1088 b->last_connect_error = error;
1089 else if (p.revents & (POLLERR|POLLHUP))
1090 b->last_connect_error = ECONNREFUSED;
1091 else
1092 return bus_socket_start_auth(b);
1093
1094 return bus_next_address(b);
1095}
1096
1097int bus_socket_process_authenticating(sd_bus *b) {
1098 int r;
1099
1100 assert(b);
1101 assert(b->state == BUS_AUTHENTICATING);
1102
1103 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1104 return -ETIMEDOUT;
1105
1106 r = bus_socket_write_auth(b);
1107 if (r != 0)
1108 return r;
1109
1110 return bus_socket_read_auth(b);
1111}