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