]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
update TODO
[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
e1d337d4
LP
626 b->is_kernel = false;
627 b->message_version = 1;
0f437184 628 b->message_endian = 0;
e1d337d4 629
a7e3212d
LP
630 return 0;
631}
632
2181a7f5 633static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 634 size_t l;
2181a7f5 635 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
636
637 assert(b);
638
2181a7f5
LP
639 if (b->anonymous_auth) {
640 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 641
2181a7f5
LP
642 /* For ANONYMOUS auth we send some arbitrary "trace" string */
643 l = 9;
644 b->auth_buffer = hexmem("anonymous", l);
645 } else {
646 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 647
2181a7f5 648 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 649
2181a7f5
LP
650 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
651 char_array_0(text);
a7e3212d 652
2181a7f5
LP
653 l = strlen(text);
654 b->auth_buffer = hexmem(text, l);
655 }
656
657 if (!b->auth_buffer)
a7e3212d
LP
658 return -ENOMEM;
659
264ad849 660 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
661 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
662 else
663 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
664
665 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
666 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
667 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
668 b->auth_iovec[1].iov_len = l * 2;
669 b->auth_iovec[2].iov_base = (void*) auth_suffix;
670 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
671
672 return bus_socket_write_auth(b);
673}
674
a7893c6b 675int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
676 assert(b);
677
678 b->state = BUS_AUTHENTICATING;
679 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
680
9ab32f9d 681 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 682 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 683
9ab32f9d
LP
684 if (b->output_fd != b->input_fd)
685 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 686 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 687
2181a7f5
LP
688 if (b->is_server)
689 return bus_socket_read_auth(b);
690 else
691 return bus_socket_start_auth_client(b);
692}
693
a7e3212d
LP
694int bus_socket_connect(sd_bus *b) {
695 int r;
696
697 assert(b);
e82c9509
LP
698 assert(b->input_fd < 0);
699 assert(b->output_fd < 0);
a7e3212d
LP
700 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
701
e82c9509
LP
702 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
703 if (b->input_fd < 0)
a7e3212d
LP
704 return -errno;
705
e82c9509
LP
706 b->output_fd = b->input_fd;
707
a7e3212d
LP
708 r = bus_socket_setup(b);
709 if (r < 0)
710 return r;
711
e82c9509 712 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
713 if (r < 0) {
714 if (errno == EINPROGRESS)
715 return 1;
716
717 return -errno;
718 }
719
720 return bus_socket_start_auth(b);
721}
722
723int bus_socket_exec(sd_bus *b) {
e82c9509 724 int s[2], r;
a7e3212d
LP
725 pid_t pid;
726
727 assert(b);
e82c9509
LP
728 assert(b->input_fd < 0);
729 assert(b->output_fd < 0);
a7e3212d
LP
730 assert(b->exec_path);
731
e82c9509
LP
732 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
733 if (r < 0)
a7e3212d
LP
734 return -errno;
735
736 pid = fork();
737 if (pid < 0) {
738 close_pipe(s);
739 return -errno;
740 }
741 if (pid == 0) {
742 /* Child */
743
e82c9509
LP
744 reset_all_signal_handlers();
745
746 close_all_fds(s+1, 1);
a7e3212d
LP
747
748 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
749 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
750
751 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
752 close_nointr_nofail(s[1]);
753
754 fd_cloexec(STDIN_FILENO, false);
755 fd_cloexec(STDOUT_FILENO, false);
756 fd_nonblock(STDIN_FILENO, false);
757 fd_nonblock(STDOUT_FILENO, false);
758
759 if (b->exec_argv)
760 execvp(b->exec_path, b->exec_argv);
761 else {
762 const char *argv[] = { b->exec_path, NULL };
763 execvp(b->exec_path, (char**) argv);
764 }
765
766 _exit(EXIT_FAILURE);
767 }
768
769 close_nointr_nofail(s[1]);
e82c9509 770 b->output_fd = b->input_fd = s[0];
a7e3212d 771
e1d337d4
LP
772 r = bus_socket_setup(b);
773 if (r < 0)
774 return r;
775
a7e3212d
LP
776 return bus_socket_start_auth(b);
777}
778
779int bus_socket_take_fd(sd_bus *b) {
780 int r;
781 assert(b);
782
783 r = bus_socket_setup(b);
784 if (r < 0)
785 return r;
786
787 return bus_socket_start_auth(b);
788}
789
790int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
791 struct iovec *iov;
792 ssize_t k;
793 size_t n;
794 unsigned j;
bc7fd8cd 795 int r;
a7e3212d
LP
796
797 assert(bus);
798 assert(m);
799 assert(idx);
800 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
801
6629161f 802 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 803 return 0;
a7e3212d 804
bc7fd8cd
LP
805 r = bus_message_setup_iovec(m);
806 if (r < 0)
807 return r;
2100fa10 808
a7e3212d
LP
809 n = m->n_iovec * sizeof(struct iovec);
810 iov = alloca(n);
811 memcpy(iov, m->iovec, n);
812
813 j = 0;
814 iovec_advance(iov, &j, *idx);
815
15d5af81
LP
816 if (bus->prefer_writev)
817 k = writev(bus->output_fd, iov, m->n_iovec);
818 else {
819 struct msghdr mh;
820 zero(mh);
821
822 if (m->n_fds > 0) {
823 struct cmsghdr *control;
824 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
825
826 mh.msg_control = control;
827 control->cmsg_level = SOL_SOCKET;
828 control->cmsg_type = SCM_RIGHTS;
829 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
830 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
831 }
832
833 mh.msg_iov = iov;
834 mh.msg_iovlen = m->n_iovec;
835
836 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
837 if (k < 0 && errno == ENOTSOCK) {
838 bus->prefer_writev = true;
839 k = writev(bus->output_fd, iov, m->n_iovec);
840 }
841 }
a7e3212d 842
a7e3212d
LP
843 if (k < 0)
844 return errno == EAGAIN ? 0 : -errno;
845
846 *idx += (size_t) k;
847 return 1;
848}
849
850static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
851 uint32_t a, b;
852 uint8_t e;
853 uint64_t sum;
854
855 assert(bus);
856 assert(need);
857 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
858
859 if (bus->rbuffer_size < sizeof(struct bus_header)) {
860 *need = sizeof(struct bus_header) + 8;
861
862 /* Minimum message size:
863 *
864 * Header +
865 *
866 * Method Call: +2 string headers
867 * Signal: +3 string headers
868 * Method Error: +1 string headers
869 * +1 uint32 headers
870 * Method Reply: +1 uint32 headers
871 *
872 * A string header is at least 9 bytes
873 * A uint32 header is at least 8 bytes
874 *
875 * Hence the minimum message size of a valid message
876 * is header + 8 bytes */
877
878 return 0;
879 }
880
881 a = ((const uint32_t*) bus->rbuffer)[1];
882 b = ((const uint32_t*) bus->rbuffer)[3];
883
884 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 885 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
886 a = le32toh(a);
887 b = le32toh(b);
0461f8cd 888 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
889 a = be32toh(a);
890 b = be32toh(b);
891 } else
892 return -EBADMSG;
893
894 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
895 if (sum >= BUS_MESSAGE_SIZE_MAX)
896 return -ENOBUFS;
897
898 *need = (size_t) sum;
899 return 0;
900}
901
7d22c717 902static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
903 sd_bus_message *t;
904 void *b;
905 int r;
906
907 assert(bus);
a7e3212d
LP
908 assert(bus->rbuffer_size >= size);
909 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
910
7adc46fc
LP
911 r = bus_rqueue_make_room(bus);
912 if (r < 0)
913 return r;
914
a7e3212d
LP
915 if (bus->rbuffer_size > size) {
916 b = memdup((const uint8_t*) bus->rbuffer + size,
917 bus->rbuffer_size - size);
918 if (!b)
919 return -ENOMEM;
920 } else
921 b = NULL;
922
df2d202e
LP
923 r = bus_message_from_malloc(bus,
924 bus->rbuffer, size,
a7e3212d 925 bus->fds, bus->n_fds,
0f4b73c8
LP
926 bus->ucred_valid ? &bus->ucred : NULL,
927 bus->label[0] ? bus->label : NULL,
a7e3212d
LP
928 &t);
929 if (r < 0) {
930 free(b);
931 return r;
932 }
933
934 bus->rbuffer = b;
935 bus->rbuffer_size -= size;
936
937 bus->fds = NULL;
938 bus->n_fds = 0;
939
7adc46fc 940 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 941
a7e3212d
LP
942 return 1;
943}
944
7d22c717 945int bus_socket_read_message(sd_bus *bus) {
a7e3212d
LP
946 struct msghdr mh;
947 struct iovec iov;
948 ssize_t k;
949 size_t need;
950 int r;
951 void *b;
952 union {
953 struct cmsghdr cmsghdr;
954 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
955 CMSG_SPACE(sizeof(struct ucred)) +
956 CMSG_SPACE(NAME_MAX)]; /*selinux label */
957 } control;
958 struct cmsghdr *cmsg;
4d3a5b10 959 bool handle_cmsg = false;
a7e3212d
LP
960
961 assert(bus);
a7e3212d
LP
962 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
963
964 r = bus_socket_read_message_need(bus, &need);
965 if (r < 0)
966 return r;
967
968 if (bus->rbuffer_size >= need)
7d22c717 969 return bus_socket_make_message(bus, need);
a7e3212d
LP
970
971 b = realloc(bus->rbuffer, need);
972 if (!b)
973 return -ENOMEM;
974
975 bus->rbuffer = b;
976
977 zero(iov);
978 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
979 iov.iov_len = need - bus->rbuffer_size;
980
15d5af81
LP
981 if (bus->prefer_readv)
982 k = readv(bus->input_fd, &iov, 1);
983 else {
984 zero(mh);
985 mh.msg_iov = &iov;
986 mh.msg_iovlen = 1;
987 mh.msg_control = &control;
988 mh.msg_controllen = sizeof(control);
989
990 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
991 if (k < 0 && errno == ENOTSOCK) {
992 bus->prefer_readv = true;
993 k = readv(bus->input_fd, &iov, 1);
994 } else
995 handle_cmsg = true;
996 }
a7e3212d
LP
997 if (k < 0)
998 return errno == EAGAIN ? 0 : -errno;
999 if (k == 0)
1000 return -ECONNRESET;
1001
1002 bus->rbuffer_size += k;
1003
15d5af81
LP
1004 if (handle_cmsg) {
1005 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
1006 if (cmsg->cmsg_level == SOL_SOCKET &&
1007 cmsg->cmsg_type == SCM_RIGHTS) {
1008 int n, *f;
1009
1010 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1011
1012 if (!bus->can_fds) {
1013 /* Whut? We received fds but this
1014 * isn't actually enabled? Close them,
1015 * and fail */
1016
1017 close_many((int*) CMSG_DATA(cmsg), n);
1018 return -EIO;
1019 }
1020
1021 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1022 if (!f) {
1023 close_many((int*) CMSG_DATA(cmsg), n);
1024 return -ENOMEM;
1025 }
1026
1027 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1028 bus->fds = f;
1029 bus->n_fds += n;
1030 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1031 cmsg->cmsg_type == SCM_CREDENTIALS &&
1032 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1033
ea8f194f
LP
1034 /* Ignore bogus data, which we might
1035 * get on socketpair() sockets */
1036 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1037 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1038 bus->ucred_valid = true;
1039 }
15d5af81
LP
1040
1041 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1042 cmsg->cmsg_type == SCM_SECURITY) {
1043
1044 size_t l;
1045 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1046 if (l > 0) {
1047 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1048 bus->label[l] = 0;
1049 }
a7e3212d 1050 }
a7e3212d
LP
1051 }
1052 }
1053
1054 r = bus_socket_read_message_need(bus, &need);
1055 if (r < 0)
1056 return r;
1057
1058 if (bus->rbuffer_size >= need)
7d22c717 1059 return bus_socket_make_message(bus, need);
a7e3212d
LP
1060
1061 return 1;
1062}
1063
1064int bus_socket_process_opening(sd_bus *b) {
1065 int error = 0;
1066 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1067 struct pollfd p = {
1068 .fd = b->output_fd,
1069 .events = POLLOUT,
1070 };
a7e3212d
LP
1071 int r;
1072
a7e3212d
LP
1073 assert(b->state == BUS_OPENING);
1074
a7e3212d
LP
1075 r = poll(&p, 1, 0);
1076 if (r < 0)
1077 return -errno;
1078
1079 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1080 return 0;
1081
e82c9509 1082 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1083 if (r < 0)
1084 b->last_connect_error = errno;
1085 else if (error != 0)
1086 b->last_connect_error = error;
1087 else if (p.revents & (POLLERR|POLLHUP))
1088 b->last_connect_error = ECONNREFUSED;
1089 else
1090 return bus_socket_start_auth(b);
1091
1092 return bus_next_address(b);
1093}
1094
1095int bus_socket_process_authenticating(sd_bus *b) {
1096 int r;
1097
1098 assert(b);
1099 assert(b->state == BUS_AUTHENTICATING);
1100
1101 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1102 return -ETIMEDOUT;
1103
1104 r = bus_socket_write_auth(b);
1105 if (r != 0)
1106 return r;
1107
1108 return bus_socket_read_auth(b);
1109}