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