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