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