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