chiark / gitweb /
sd-bus: fix path of object-manager signals
[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         bool handle_cmsg = false;
506
507         assert(b);
508         assert(b->state == BUS_AUTHENTICATING);
509
510         r = bus_socket_auth_verify(b);
511         if (r != 0)
512                 return r;
513
514         n = MAX(256u, b->rbuffer_size * 2);
515
516         if (n > BUS_AUTH_SIZE_MAX)
517                 n = BUS_AUTH_SIZE_MAX;
518
519         if (b->rbuffer_size >= n)
520                 return -ENOBUFS;
521
522         p = realloc(b->rbuffer, n);
523         if (!p)
524                 return -ENOMEM;
525
526         b->rbuffer = p;
527
528         iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
529         iov.iov_len = n - b->rbuffer_size;
530
531         if (b->prefer_readv)
532                 k = readv(b->input_fd, &iov, 1);
533         else {
534                 zero(mh);
535                 mh.msg_iov = &iov;
536                 mh.msg_iovlen = 1;
537                 mh.msg_control = &control;
538                 mh.msg_controllen = sizeof(control);
539
540                 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
541                 if (k < 0 && errno == ENOTSOCK) {
542                         b->prefer_readv = true;
543                         k = readv(b->input_fd, &iov, 1);
544                 } else
545                         handle_cmsg = true;
546         }
547         if (k < 0)
548                 return errno == EAGAIN ? 0 : -errno;
549         if (k == 0)
550                 return -ECONNRESET;
551
552         b->rbuffer_size += k;
553
554         if (handle_cmsg) {
555                 struct cmsghdr *cmsg;
556
557                 CMSG_FOREACH(cmsg, &mh)
558                         if (cmsg->cmsg_level == SOL_SOCKET &&
559                             cmsg->cmsg_type == SCM_RIGHTS) {
560                                 int j;
561
562                                 /* Whut? We received fds during the auth
563                                  * protocol? Somebody is playing games with
564                                  * us. Close them all, and fail */
565                                 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
566                                 close_many((int*) CMSG_DATA(cmsg), j);
567                                 return -EIO;
568                         } else
569                                 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
570                                           cmsg->cmsg_level, cmsg->cmsg_type);
571         }
572
573         r = bus_socket_auth_verify(b);
574         if (r != 0)
575                 return r;
576
577         return 1;
578 }
579
580 void bus_socket_setup(sd_bus *b) {
581         assert(b);
582
583         /* Increase the buffers to 8 MB */
584         fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
585         fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
586
587         b->is_kernel = false;
588         b->message_version = 1;
589         b->message_endian = 0;
590 }
591
592 static void bus_get_peercred(sd_bus *b) {
593         int r;
594
595         assert(b);
596
597         /* Get the peer for socketpair() sockets */
598         b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
599
600         /* Get the SELinux context of the peer */
601         r = getpeersec(b->input_fd, &b->label);
602         if (r < 0 && r != -EOPNOTSUPP)
603                 log_debug_errno(r, "Failed to determine peer security context: %m");
604 }
605
606 static int bus_socket_start_auth_client(sd_bus *b) {
607         size_t l;
608         const char *auth_suffix, *auth_prefix;
609
610         assert(b);
611
612         if (b->anonymous_auth) {
613                 auth_prefix = "\0AUTH ANONYMOUS ";
614
615                 /* For ANONYMOUS auth we send some arbitrary "trace" string */
616                 l = 9;
617                 b->auth_buffer = hexmem("anonymous", l);
618         } else {
619                 char text[DECIMAL_STR_MAX(uid_t) + 1];
620
621                 auth_prefix = "\0AUTH EXTERNAL ";
622
623                 xsprintf(text, UID_FMT, geteuid());
624
625                 l = strlen(text);
626                 b->auth_buffer = hexmem(text, l);
627         }
628
629         if (!b->auth_buffer)
630                 return -ENOMEM;
631
632         if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
633                 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
634         else
635                 auth_suffix = "\r\nBEGIN\r\n";
636
637         b->auth_iovec[0].iov_base = (void*) auth_prefix;
638         b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
639         b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
640         b->auth_iovec[1].iov_len = l * 2;
641         b->auth_iovec[2].iov_base = (void*) auth_suffix;
642         b->auth_iovec[2].iov_len = strlen(auth_suffix);
643
644         return bus_socket_write_auth(b);
645 }
646
647 int bus_socket_start_auth(sd_bus *b) {
648         assert(b);
649
650         bus_get_peercred(b);
651
652         b->state = BUS_AUTHENTICATING;
653         b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
654
655         if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
656                 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
657
658         if (b->output_fd != b->input_fd)
659                 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
660                         b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
661
662         if (b->is_server)
663                 return bus_socket_read_auth(b);
664         else
665                 return bus_socket_start_auth_client(b);
666 }
667
668 int bus_socket_connect(sd_bus *b) {
669         int r;
670
671         assert(b);
672         assert(b->input_fd < 0);
673         assert(b->output_fd < 0);
674         assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
675
676         b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
677         if (b->input_fd < 0)
678                 return -errno;
679
680         b->output_fd = b->input_fd;
681
682         bus_socket_setup(b);
683
684         r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
685         if (r < 0) {
686                 if (errno == EINPROGRESS)
687                         return 1;
688
689                 return -errno;
690         }
691
692         return bus_socket_start_auth(b);
693 }
694
695 int bus_socket_exec(sd_bus *b) {
696         int s[2], r;
697         pid_t pid;
698
699         assert(b);
700         assert(b->input_fd < 0);
701         assert(b->output_fd < 0);
702         assert(b->exec_path);
703
704         r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
705         if (r < 0)
706                 return -errno;
707
708         pid = fork();
709         if (pid < 0) {
710                 safe_close_pair(s);
711                 return -errno;
712         }
713         if (pid == 0) {
714                 /* Child */
715
716                 (void) reset_all_signal_handlers();
717                 (void) reset_signal_mask();
718
719                 close_all_fds(s+1, 1);
720
721                 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
722                 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
723
724                 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
725                         safe_close(s[1]);
726
727                 fd_cloexec(STDIN_FILENO, false);
728                 fd_cloexec(STDOUT_FILENO, false);
729                 fd_nonblock(STDIN_FILENO, false);
730                 fd_nonblock(STDOUT_FILENO, false);
731
732                 if (b->exec_argv)
733                         execvp(b->exec_path, b->exec_argv);
734                 else {
735                         const char *argv[] = { b->exec_path, NULL };
736                         execvp(b->exec_path, (char**) argv);
737                 }
738
739                 _exit(EXIT_FAILURE);
740         }
741
742         safe_close(s[1]);
743         b->output_fd = b->input_fd = s[0];
744
745         bus_socket_setup(b);
746
747         return bus_socket_start_auth(b);
748 }
749
750 int bus_socket_take_fd(sd_bus *b) {
751         assert(b);
752
753         bus_socket_setup(b);
754
755         return bus_socket_start_auth(b);
756 }
757
758 int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
759         struct iovec *iov;
760         ssize_t k;
761         size_t n;
762         unsigned j;
763         int r;
764
765         assert(bus);
766         assert(m);
767         assert(idx);
768         assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
769
770         if (*idx >= BUS_MESSAGE_SIZE(m))
771                 return 0;
772
773         r = bus_message_setup_iovec(m);
774         if (r < 0)
775                 return r;
776
777         n = m->n_iovec * sizeof(struct iovec);
778         iov = alloca(n);
779         memcpy(iov, m->iovec, n);
780
781         j = 0;
782         iovec_advance(iov, &j, *idx);
783
784         if (bus->prefer_writev)
785                 k = writev(bus->output_fd, iov, m->n_iovec);
786         else {
787                 struct msghdr mh = {
788                         .msg_iov = iov,
789                         .msg_iovlen = m->n_iovec,
790                 };
791
792                 if (m->n_fds > 0) {
793                         struct cmsghdr *control;
794
795                         mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
796                         mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
797                         control->cmsg_level = SOL_SOCKET;
798                         control->cmsg_type = SCM_RIGHTS;
799                         memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
800                 }
801
802                 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
803                 if (k < 0 && errno == ENOTSOCK) {
804                         bus->prefer_writev = true;
805                         k = writev(bus->output_fd, iov, m->n_iovec);
806                 }
807         }
808
809         if (k < 0)
810                 return errno == EAGAIN ? 0 : -errno;
811
812         *idx += (size_t) k;
813         return 1;
814 }
815
816 static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
817         uint32_t a, b;
818         uint8_t e;
819         uint64_t sum;
820
821         assert(bus);
822         assert(need);
823         assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
824
825         if (bus->rbuffer_size < sizeof(struct bus_header)) {
826                 *need = sizeof(struct bus_header) + 8;
827
828                 /* Minimum message size:
829                  *
830                  * Header +
831                  *
832                  *  Method Call: +2 string headers
833                  *       Signal: +3 string headers
834                  * Method Error: +1 string headers
835                  *               +1 uint32 headers
836                  * Method Reply: +1 uint32 headers
837                  *
838                  * A string header is at least 9 bytes
839                  * A uint32 header is at least 8 bytes
840                  *
841                  * Hence the minimum message size of a valid message
842                  * is header + 8 bytes */
843
844                 return 0;
845         }
846
847         a = ((const uint32_t*) bus->rbuffer)[1];
848         b = ((const uint32_t*) bus->rbuffer)[3];
849
850         e = ((const uint8_t*) bus->rbuffer)[0];
851         if (e == BUS_LITTLE_ENDIAN) {
852                 a = le32toh(a);
853                 b = le32toh(b);
854         } else if (e == BUS_BIG_ENDIAN) {
855                 a = be32toh(a);
856                 b = be32toh(b);
857         } else
858                 return -EBADMSG;
859
860         sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
861         if (sum >= BUS_MESSAGE_SIZE_MAX)
862                 return -ENOBUFS;
863
864         *need = (size_t) sum;
865         return 0;
866 }
867
868 static int bus_socket_make_message(sd_bus *bus, size_t size) {
869         sd_bus_message *t;
870         void *b;
871         int r;
872
873         assert(bus);
874         assert(bus->rbuffer_size >= size);
875         assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
876
877         r = bus_rqueue_make_room(bus);
878         if (r < 0)
879                 return r;
880
881         if (bus->rbuffer_size > size) {
882                 b = memdup((const uint8_t*) bus->rbuffer + size,
883                            bus->rbuffer_size - size);
884                 if (!b)
885                         return -ENOMEM;
886         } else
887                 b = NULL;
888
889         r = bus_message_from_malloc(bus,
890                                     bus->rbuffer, size,
891                                     bus->fds, bus->n_fds,
892                                     NULL,
893                                     &t);
894         if (r < 0) {
895                 free(b);
896                 return r;
897         }
898
899         bus->rbuffer = b;
900         bus->rbuffer_size -= size;
901
902         bus->fds = NULL;
903         bus->n_fds = 0;
904
905         bus->rqueue[bus->rqueue_size++] = t;
906
907         return 1;
908 }
909
910 int bus_socket_read_message(sd_bus *bus) {
911         struct msghdr mh;
912         struct iovec iov = {};
913         ssize_t k;
914         size_t need;
915         int r;
916         void *b;
917         union {
918                 struct cmsghdr cmsghdr;
919                 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
920         } control;
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                 struct cmsghdr *cmsg;
967
968                 CMSG_FOREACH(cmsg, &mh)
969                         if (cmsg->cmsg_level == SOL_SOCKET &&
970                             cmsg->cmsg_type == SCM_RIGHTS) {
971                                 int n, *f;
972
973                                 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
974
975                                 if (!bus->can_fds) {
976                                         /* Whut? We received fds but this
977                                          * isn't actually enabled? Close them,
978                                          * and fail */
979
980                                         close_many((int*) CMSG_DATA(cmsg), n);
981                                         return -EIO;
982                                 }
983
984                                 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
985                                 if (!f) {
986                                         close_many((int*) CMSG_DATA(cmsg), n);
987                                         return -ENOMEM;
988                                 }
989
990                                 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
991                                 bus->fds = f;
992                                 bus->n_fds += n;
993                         } else
994                                 log_debug("Got unexpected auxiliary data with level=%d and type=%d",
995                                           cmsg->cmsg_level, cmsg->cmsg_type);
996         }
997
998         r = bus_socket_read_message_need(bus, &need);
999         if (r < 0)
1000                 return r;
1001
1002         if (bus->rbuffer_size >= need)
1003                 return bus_socket_make_message(bus, need);
1004
1005         return 1;
1006 }
1007
1008 int bus_socket_process_opening(sd_bus *b) {
1009         int error = 0;
1010         socklen_t slen = sizeof(error);
1011         struct pollfd p = {
1012                 .fd = b->output_fd,
1013                 .events = POLLOUT,
1014         };
1015         int r;
1016
1017         assert(b->state == BUS_OPENING);
1018
1019         r = poll(&p, 1, 0);
1020         if (r < 0)
1021                 return -errno;
1022
1023         if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1024                 return 0;
1025
1026         r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
1027         if (r < 0)
1028                 b->last_connect_error = errno;
1029         else if (error != 0)
1030                 b->last_connect_error = error;
1031         else if (p.revents & (POLLERR|POLLHUP))
1032                 b->last_connect_error = ECONNREFUSED;
1033         else
1034                 return bus_socket_start_auth(b);
1035
1036         return bus_next_address(b);
1037 }
1038
1039 int bus_socket_process_authenticating(sd_bus *b) {
1040         int r;
1041
1042         assert(b);
1043         assert(b->state == BUS_AUTHENTICATING);
1044
1045         if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1046                 return -ETIMEDOUT;
1047
1048         r = bus_socket_write_auth(b);
1049         if (r != 0)
1050                 return r;
1051
1052         return bus_socket_read_auth(b);
1053 }