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