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