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