]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/libsystemd-bus/bus-socket.c
bus: fix hello ioctl buffer size calculation
[thirdparty/systemd.git] / src / libsystemd-bus / bus-socket.c
... / ...
CommitLineData
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"
33#include "utf8.h"
34#include "sd-daemon.h"
35
36#include "sd-bus.h"
37#include "bus-socket.h"
38#include "bus-internal.h"
39#include "bus-message.h"
40
41#define SNDBUF_SIZE (8*1024*1024)
42
43static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
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
63static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
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++;
71
72 return 0;
73}
74
75static int bus_message_setup_iovec(sd_bus_message *m) {
76 struct bus_body_part *part;
77 unsigned n, i;
78 int r;
79
80 assert(m);
81 assert(m->sealed);
82
83 if (m->n_iovec > 0)
84 return 0;
85
86 assert(!m->iovec);
87
88 n = 1 + m->n_body_parts;
89 if (n < ELEMENTSOF(m->iovec_fixed))
90 m->iovec = m->iovec_fixed;
91 else {
92 m->iovec = new(struct iovec, n);
93 if (!m->iovec) {
94 r = -ENOMEM;
95 goto fail;
96 }
97 }
98
99 r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
100 if (r < 0)
101 goto fail;
102
103 MESSAGE_FOREACH_PART(part, i, m) {
104 r = bus_body_part_map(part);
105 if (r < 0)
106 goto fail;
107
108 r = append_iovec(m, part->data, part->size);
109 if (r < 0)
110 goto fail;
111 }
112
113 assert(n == m->n_iovec);
114
115 return 0;
116
117fail:
118 m->poisoned = true;
119 return r;
120}
121
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
139static int bus_socket_write_auth(sd_bus *b) {
140 ssize_t k;
141
142 assert(b);
143 assert(b->state == BUS_AUTHENTICATING);
144
145 if (!bus_socket_auth_needs_write(b))
146 return 0;
147
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 }
163
164 if (k < 0)
165 return errno == EAGAIN ? 0 : -errno;
166
167 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
168 return 1;
169}
170
171static int bus_socket_auth_verify_client(sd_bus *b) {
172 char *e, *f, *start;
173 sd_id128_t peer;
174 unsigned i;
175 int r;
176
177 assert(b);
178
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
186 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) {
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
206 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
207
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
220 if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
221 !sd_id128_equal(b->server_id, peer))
222 return -EPERM;
223
224 b->server_id = peer;
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
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
299 if (!b->anonymous_auth && !b->ucred_valid)
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
322 /* We ignore the passed value if anonymous authentication is
323 * on anyway. */
324 if (!b->anonymous_auth && u != b->ucred.uid)
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
362 snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
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
377 if (b->rbuffer_size < 1)
378 return 0;
379
380 /* First char must be a NUL byte */
381 if (*(char*) b->rbuffer != 0)
382 return -EIO;
383
384 if (b->rbuffer_size < 3)
385 return 0;
386
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")) {
469 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
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
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;
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;
510 bool handle_cmsg = false;
511
512 assert(b);
513 assert(b->state == BUS_AUTHENTICATING);
514
515 r = bus_socket_auth_verify(b);
516 if (r != 0)
517 return r;
518
519 n = MAX(256u, b->rbuffer_size * 2);
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
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 }
553 if (k < 0)
554 return errno == EAGAIN ? 0 : -errno;
555 if (k == 0)
556 return -ECONNRESET;
557
558 b->rbuffer_size += k;
559
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;
572
573 } else if (cmsg->cmsg_level == SOL_SOCKET &&
574 cmsg->cmsg_type == SCM_CREDENTIALS &&
575 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
576
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 }
583
584 } else if (cmsg->cmsg_level == SOL_SOCKET &&
585 cmsg->cmsg_type == SCM_SECURITY) {
586
587 size_t l;
588
589 l = cmsg->cmsg_len - CMSG_LEN(0);
590 if (l > 0) {
591 memcpy(&b->label, CMSG_DATA(cmsg), l);
592 b->label[l] = 0;
593 }
594 }
595 }
596 }
597
598 r = bus_socket_auth_verify(b);
599 if (r != 0)
600 return r;
601
602 return 1;
603}
604
605void bus_socket_setup(sd_bus *b) {
606 int enable;
607
608 assert(b);
609
610 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
611 * socket, just in case. */
612 enable = !b->bus_client;
613 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
614
615 enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
616 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
617
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);
621
622 b->is_kernel = false;
623 b->message_version = 1;
624 b->message_endian = 0;
625}
626
627static void bus_get_peercred(sd_bus *b) {
628 socklen_t l;
629
630 assert(b);
631
632 /* Get the peer for socketpair() sockets */
633 l = sizeof(b->ucred);
634 if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
635 b->ucred_valid = b->ucred.pid > 0;
636}
637
638static int bus_socket_start_auth_client(sd_bus *b) {
639 size_t l;
640 const char *auth_suffix, *auth_prefix;
641
642 assert(b);
643
644 if (b->anonymous_auth) {
645 auth_prefix = "\0AUTH ANONYMOUS ";
646
647 /* For ANONYMOUS auth we send some arbitrary "trace" string */
648 l = 9;
649 b->auth_buffer = hexmem("anonymous", l);
650 } else {
651 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
652
653 auth_prefix = "\0AUTH EXTERNAL ";
654
655 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
656 char_array_0(text);
657
658 l = strlen(text);
659 b->auth_buffer = hexmem(text, l);
660 }
661
662 if (!b->auth_buffer)
663 return -ENOMEM;
664
665 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
666 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
667 else
668 auth_suffix = "\r\nBEGIN\r\n";
669
670 b->auth_iovec[0].iov_base = (void*) auth_prefix;
671 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
672 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
673 b->auth_iovec[1].iov_len = l * 2;
674 b->auth_iovec[2].iov_base = (void*) auth_suffix;
675 b->auth_iovec[2].iov_len = strlen(auth_suffix);
676
677 return bus_socket_write_auth(b);
678}
679
680int bus_socket_start_auth(sd_bus *b) {
681 assert(b);
682
683 bus_get_peercred(b);
684
685 b->state = BUS_AUTHENTICATING;
686 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
687
688 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
689 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
690
691 if (b->output_fd != b->input_fd)
692 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
693 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
694
695 if (b->is_server)
696 return bus_socket_read_auth(b);
697 else
698 return bus_socket_start_auth_client(b);
699}
700
701int bus_socket_connect(sd_bus *b) {
702 int r;
703
704 assert(b);
705 assert(b->input_fd < 0);
706 assert(b->output_fd < 0);
707 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
708
709 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
710 if (b->input_fd < 0)
711 return -errno;
712
713 b->output_fd = b->input_fd;
714
715 bus_socket_setup(b);
716
717 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
718 if (r < 0) {
719 if (errno == EINPROGRESS)
720 return 1;
721
722 return -errno;
723 }
724
725 return bus_socket_start_auth(b);
726}
727
728int bus_socket_exec(sd_bus *b) {
729 int s[2], r;
730 pid_t pid;
731
732 assert(b);
733 assert(b->input_fd < 0);
734 assert(b->output_fd < 0);
735 assert(b->exec_path);
736
737 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
738 if (r < 0)
739 return -errno;
740
741 pid = fork();
742 if (pid < 0) {
743 close_pipe(s);
744 return -errno;
745 }
746 if (pid == 0) {
747 /* Child */
748
749 reset_all_signal_handlers();
750
751 close_all_fds(s+1, 1);
752
753 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
754 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
755
756 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
757 close_nointr_nofail(s[1]);
758
759 fd_cloexec(STDIN_FILENO, false);
760 fd_cloexec(STDOUT_FILENO, false);
761 fd_nonblock(STDIN_FILENO, false);
762 fd_nonblock(STDOUT_FILENO, false);
763
764 if (b->exec_argv)
765 execvp(b->exec_path, b->exec_argv);
766 else {
767 const char *argv[] = { b->exec_path, NULL };
768 execvp(b->exec_path, (char**) argv);
769 }
770
771 _exit(EXIT_FAILURE);
772 }
773
774 close_nointr_nofail(s[1]);
775 b->output_fd = b->input_fd = s[0];
776
777 bus_socket_setup(b);
778
779 return bus_socket_start_auth(b);
780}
781
782int bus_socket_take_fd(sd_bus *b) {
783 assert(b);
784
785 bus_socket_setup(b);
786
787 return bus_socket_start_auth(b);
788}
789
790int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
791 struct iovec *iov;
792 ssize_t k;
793 size_t n;
794 unsigned j;
795 int r;
796
797 assert(bus);
798 assert(m);
799 assert(idx);
800 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
801
802 if (*idx >= BUS_MESSAGE_SIZE(m))
803 return 0;
804
805 r = bus_message_setup_iovec(m);
806 if (r < 0)
807 return r;
808
809 n = m->n_iovec * sizeof(struct iovec);
810 iov = alloca(n);
811 memcpy(iov, m->iovec, n);
812
813 j = 0;
814 iovec_advance(iov, &j, *idx);
815
816 if (bus->prefer_writev)
817 k = writev(bus->output_fd, iov, m->n_iovec);
818 else {
819 struct msghdr mh;
820 zero(mh);
821
822 if (m->n_fds > 0) {
823 struct cmsghdr *control;
824 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
825
826 mh.msg_control = control;
827 control->cmsg_level = SOL_SOCKET;
828 control->cmsg_type = SCM_RIGHTS;
829 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
830 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
831 }
832
833 mh.msg_iov = iov;
834 mh.msg_iovlen = m->n_iovec;
835
836 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
837 if (k < 0 && errno == ENOTSOCK) {
838 bus->prefer_writev = true;
839 k = writev(bus->output_fd, iov, m->n_iovec);
840 }
841 }
842
843 if (k < 0)
844 return errno == EAGAIN ? 0 : -errno;
845
846 *idx += (size_t) k;
847 return 1;
848}
849
850static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
851 uint32_t a, b;
852 uint8_t e;
853 uint64_t sum;
854
855 assert(bus);
856 assert(need);
857 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
858
859 if (bus->rbuffer_size < sizeof(struct bus_header)) {
860 *need = sizeof(struct bus_header) + 8;
861
862 /* Minimum message size:
863 *
864 * Header +
865 *
866 * Method Call: +2 string headers
867 * Signal: +3 string headers
868 * Method Error: +1 string headers
869 * +1 uint32 headers
870 * Method Reply: +1 uint32 headers
871 *
872 * A string header is at least 9 bytes
873 * A uint32 header is at least 8 bytes
874 *
875 * Hence the minimum message size of a valid message
876 * is header + 8 bytes */
877
878 return 0;
879 }
880
881 a = ((const uint32_t*) bus->rbuffer)[1];
882 b = ((const uint32_t*) bus->rbuffer)[3];
883
884 e = ((const uint8_t*) bus->rbuffer)[0];
885 if (e == BUS_LITTLE_ENDIAN) {
886 a = le32toh(a);
887 b = le32toh(b);
888 } else if (e == BUS_BIG_ENDIAN) {
889 a = be32toh(a);
890 b = be32toh(b);
891 } else
892 return -EBADMSG;
893
894 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
895 if (sum >= BUS_MESSAGE_SIZE_MAX)
896 return -ENOBUFS;
897
898 *need = (size_t) sum;
899 return 0;
900}
901
902static int bus_socket_make_message(sd_bus *bus, size_t size) {
903 sd_bus_message *t;
904 void *b;
905 int r;
906
907 assert(bus);
908 assert(bus->rbuffer_size >= size);
909 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
910
911 r = bus_rqueue_make_room(bus);
912 if (r < 0)
913 return r;
914
915 if (bus->rbuffer_size > size) {
916 b = memdup((const uint8_t*) bus->rbuffer + size,
917 bus->rbuffer_size - size);
918 if (!b)
919 return -ENOMEM;
920 } else
921 b = NULL;
922
923 r = bus_message_from_malloc(bus,
924 bus->rbuffer, size,
925 bus->fds, bus->n_fds,
926 !bus->bus_client && bus->ucred_valid ? &bus->ucred : NULL,
927 !bus->bus_client && bus->label[0] ? bus->label : NULL,
928 &t);
929 if (r < 0) {
930 free(b);
931 return r;
932 }
933
934 bus->rbuffer = b;
935 bus->rbuffer_size -= size;
936
937 bus->fds = NULL;
938 bus->n_fds = 0;
939
940 bus->rqueue[bus->rqueue_size++] = t;
941
942 return 1;
943}
944
945int bus_socket_read_message(sd_bus *bus) {
946 struct msghdr mh;
947 struct iovec iov;
948 ssize_t k;
949 size_t need;
950 int r;
951 void *b;
952 union {
953 struct cmsghdr cmsghdr;
954 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
955 CMSG_SPACE(sizeof(struct ucred)) +
956 CMSG_SPACE(NAME_MAX)]; /*selinux label */
957 } control;
958 struct cmsghdr *cmsg;
959 bool handle_cmsg = false;
960
961 assert(bus);
962 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
963
964 r = bus_socket_read_message_need(bus, &need);
965 if (r < 0)
966 return r;
967
968 if (bus->rbuffer_size >= need)
969 return bus_socket_make_message(bus, need);
970
971 b = realloc(bus->rbuffer, need);
972 if (!b)
973 return -ENOMEM;
974
975 bus->rbuffer = b;
976
977 zero(iov);
978 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
979 iov.iov_len = need - bus->rbuffer_size;
980
981 if (bus->prefer_readv)
982 k = readv(bus->input_fd, &iov, 1);
983 else {
984 zero(mh);
985 mh.msg_iov = &iov;
986 mh.msg_iovlen = 1;
987 mh.msg_control = &control;
988 mh.msg_controllen = sizeof(control);
989
990 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
991 if (k < 0 && errno == ENOTSOCK) {
992 bus->prefer_readv = true;
993 k = readv(bus->input_fd, &iov, 1);
994 } else
995 handle_cmsg = true;
996 }
997 if (k < 0)
998 return errno == EAGAIN ? 0 : -errno;
999 if (k == 0)
1000 return -ECONNRESET;
1001
1002 bus->rbuffer_size += k;
1003
1004 if (handle_cmsg) {
1005 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
1006 if (cmsg->cmsg_level == SOL_SOCKET &&
1007 cmsg->cmsg_type == SCM_RIGHTS) {
1008 int n, *f;
1009
1010 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1011
1012 if (!bus->can_fds) {
1013 /* Whut? We received fds but this
1014 * isn't actually enabled? Close them,
1015 * and fail */
1016
1017 close_many((int*) CMSG_DATA(cmsg), n);
1018 return -EIO;
1019 }
1020
1021 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1022 if (!f) {
1023 close_many((int*) CMSG_DATA(cmsg), n);
1024 return -ENOMEM;
1025 }
1026
1027 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1028 bus->fds = f;
1029 bus->n_fds += n;
1030 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1031 cmsg->cmsg_type == SCM_CREDENTIALS &&
1032 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1033
1034 /* Ignore bogus data, which we might
1035 * get on socketpair() sockets */
1036 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1037 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1038 bus->ucred_valid = true;
1039 }
1040
1041 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1042 cmsg->cmsg_type == SCM_SECURITY) {
1043
1044 size_t l;
1045 l = cmsg->cmsg_len - CMSG_LEN(0);
1046 if (l > 0) {
1047 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1048 bus->label[l] = 0;
1049 }
1050 }
1051 }
1052 }
1053
1054 r = bus_socket_read_message_need(bus, &need);
1055 if (r < 0)
1056 return r;
1057
1058 if (bus->rbuffer_size >= need)
1059 return bus_socket_make_message(bus, need);
1060
1061 return 1;
1062}
1063
1064int bus_socket_process_opening(sd_bus *b) {
1065 int error = 0;
1066 socklen_t slen = sizeof(error);
1067 struct pollfd p = {
1068 .fd = b->output_fd,
1069 .events = POLLOUT,
1070 };
1071 int r;
1072
1073 assert(b->state == BUS_OPENING);
1074
1075 r = poll(&p, 1, 0);
1076 if (r < 0)
1077 return -errno;
1078
1079 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1080 return 0;
1081
1082 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
1083 if (r < 0)
1084 b->last_connect_error = errno;
1085 else if (error != 0)
1086 b->last_connect_error = error;
1087 else if (p.revents & (POLLERR|POLLHUP))
1088 b->last_connect_error = ECONNREFUSED;
1089 else
1090 return bus_socket_start_auth(b);
1091
1092 return bus_next_address(b);
1093}
1094
1095int bus_socket_process_authenticating(sd_bus *b) {
1096 int r;
1097
1098 assert(b);
1099 assert(b->state == BUS_AUTHENTICATING);
1100
1101 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1102 return -ETIMEDOUT;
1103
1104 r = bus_socket_write_auth(b);
1105 if (r != 0)
1106 return r;
1107
1108 return bus_socket_read_auth(b);
1109}