]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
util: use GNU comparison function prototype for qsort_safe()
[thirdparty/systemd.git] / src / libsystemd / sd-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>
a7e3212d
LP
23#include <stdlib.h>
24#include <unistd.h>
0a6f50c0 25#include <poll.h>
a7e3212d
LP
26
27#include "util.h"
28#include "macro.h"
29#include "missing.h"
2181a7f5 30#include "utf8.h"
9ab32f9d 31#include "sd-daemon.h"
6482f626 32#include "formats-util.h"
a7e3212d
LP
33
34#include "sd-bus.h"
35#include "bus-socket.h"
36#include "bus-internal.h"
37#include "bus-message.h"
38
aec6d91f
LP
39#define SNDBUF_SIZE (8*1024*1024)
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 =
f8294e41
JT
228 (f - e == strlen("\r\nAGREE_UNIX_FD")) &&
229 memcmp(e + 2, "AGREE_UNIX_FD", strlen("AGREE_UNIX_FD")) == 0;
a7e3212d
LP
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
5ffa8c81 360 xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
361
362 return bus_socket_auth_write(b, t);
363}
364
365static int bus_socket_auth_verify_server(sd_bus *b) {
366 char *e;
367 const char *line;
368 size_t l;
369 bool processed = false;
370 int r;
371
372 assert(b);
373
2b4ac889 374 if (b->rbuffer_size < 1)
2181a7f5
LP
375 return 0;
376
377 /* First char must be a NUL byte */
378 if (*(char*) b->rbuffer != 0)
379 return -EIO;
380
2b4ac889
LP
381 if (b->rbuffer_size < 3)
382 return 0;
383
2181a7f5
LP
384 /* Begin with the first line */
385 if (b->auth_rbegin <= 0)
386 b->auth_rbegin = 1;
387
388 for (;;) {
389 /* Check if line is complete */
390 line = (char*) b->rbuffer + b->auth_rbegin;
391 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
392 if (!e)
393 return processed;
394
395 l = e - line;
396
397 if (line_begins(line, l, "AUTH ANONYMOUS")) {
398
399 r = verify_anonymous_token(b, line + 14, l - 14);
400 if (r < 0)
401 return r;
402 if (r == 0)
403 r = bus_socket_auth_write(b, "REJECTED\r\n");
404 else {
405 b->auth = BUS_AUTH_ANONYMOUS;
406 r = bus_socket_auth_write_ok(b);
407 }
408
409 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
410
411 r = verify_external_token(b, line + 13, l - 13);
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_EXTERNAL;
418 r = bus_socket_auth_write_ok(b);
419 }
420
421 } else if (line_begins(line, l, "AUTH"))
422 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
423 else if (line_equals(line, l, "CANCEL") ||
424 line_begins(line, l, "ERROR")) {
425
426 b->auth = _BUS_AUTH_INVALID;
427 r = bus_socket_auth_write(b, "REJECTED\r\n");
428
429 } else if (line_equals(line, l, "BEGIN")) {
430
431 if (b->auth == _BUS_AUTH_INVALID)
432 r = bus_socket_auth_write(b, "ERROR\r\n");
433 else {
434 /* We can't leave from the auth phase
435 * before we haven't written
436 * everything queued, so let's check
437 * that */
438
439 if (bus_socket_auth_needs_write(b))
440 return 1;
441
442 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
443 memmove(b->rbuffer, e + 2, b->rbuffer_size);
444 return bus_start_running(b);
445 }
446
447 } else if (line_begins(line, l, "DATA")) {
448
449 if (b->auth == _BUS_AUTH_INVALID)
450 r = bus_socket_auth_write(b, "ERROR\r\n");
451 else {
452 if (b->auth == BUS_AUTH_ANONYMOUS)
453 r = verify_anonymous_token(b, line + 4, l - 4);
454 else
455 r = verify_external_token(b, line + 4, l - 4);
456
457 if (r < 0)
458 return r;
459 if (r == 0) {
460 b->auth = _BUS_AUTH_INVALID;
461 r = bus_socket_auth_write(b, "REJECTED\r\n");
462 } else
463 r = bus_socket_auth_write_ok(b);
464 }
465 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
264ad849 466 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
2181a7f5
LP
467 r = bus_socket_auth_write(b, "ERROR\r\n");
468 else {
469 b->can_fds = true;
470 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
471 }
472 } else
473 r = bus_socket_auth_write(b, "ERROR\r\n");
474
475 if (r < 0)
476 return r;
477
478 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
479
480 processed = true;
481 }
482}
483
484static int bus_socket_auth_verify(sd_bus *b) {
485 assert(b);
486
487 if (b->is_server)
488 return bus_socket_auth_verify_server(b);
489 else
490 return bus_socket_auth_verify_client(b);
491}
492
a7e3212d
LP
493static int bus_socket_read_auth(sd_bus *b) {
494 struct msghdr mh;
495 struct iovec iov;
496 size_t n;
497 ssize_t k;
498 int r;
499 void *p;
2181a7f5
LP
500 union {
501 struct cmsghdr cmsghdr;
502 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
503 CMSG_SPACE(sizeof(struct ucred)) +
504 CMSG_SPACE(NAME_MAX)]; /*selinux label */
505 } control;
506 struct cmsghdr *cmsg;
15d5af81 507 bool handle_cmsg = false;
a7e3212d
LP
508
509 assert(b);
2181a7f5 510 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
511
512 r = bus_socket_auth_verify(b);
513 if (r != 0)
514 return r;
515
9607d947 516 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
517
518 if (n > BUS_AUTH_SIZE_MAX)
519 n = BUS_AUTH_SIZE_MAX;
520
521 if (b->rbuffer_size >= n)
522 return -ENOBUFS;
523
524 p = realloc(b->rbuffer, n);
525 if (!p)
526 return -ENOMEM;
527
528 b->rbuffer = p;
529
530 zero(iov);
531 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
532 iov.iov_len = n - b->rbuffer_size;
533
15d5af81
LP
534 if (b->prefer_readv)
535 k = readv(b->input_fd, &iov, 1);
536 else {
537 zero(mh);
538 mh.msg_iov = &iov;
539 mh.msg_iovlen = 1;
540 mh.msg_control = &control;
541 mh.msg_controllen = sizeof(control);
542
543 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
544 if (k < 0 && errno == ENOTSOCK) {
545 b->prefer_readv = true;
546 k = readv(b->input_fd, &iov, 1);
547 } else
548 handle_cmsg = true;
549 }
a7e3212d
LP
550 if (k < 0)
551 return errno == EAGAIN ? 0 : -errno;
552 if (k == 0)
553 return -ECONNRESET;
554
555 b->rbuffer_size += k;
556
15d5af81
LP
557 if (handle_cmsg) {
558 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
559 if (cmsg->cmsg_level == SOL_SOCKET &&
560 cmsg->cmsg_type == SCM_RIGHTS) {
561 int j;
562
563 /* Whut? We received fds during the auth
564 * protocol? Somebody is playing games with
565 * us. Close them all, and fail */
566 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
567 close_many((int*) CMSG_DATA(cmsg), j);
568 return -EIO;
2181a7f5 569
15d5af81
LP
570 } else if (cmsg->cmsg_level == SOL_SOCKET &&
571 cmsg->cmsg_type == SCM_CREDENTIALS &&
572 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
2181a7f5 573
ea8f194f
LP
574 /* Ignore bogus data, which we might
575 * get on socketpair() sockets */
576 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
577 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
578 b->ucred_valid = true;
579 }
2181a7f5 580
15d5af81
LP
581 } else if (cmsg->cmsg_level == SOL_SOCKET &&
582 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 583
15d5af81 584 size_t l;
ea8f194f 585
15d5af81 586 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
587 if (l > 0) {
588 memcpy(&b->label, CMSG_DATA(cmsg), l);
589 b->label[l] = 0;
590 }
15d5af81 591 }
2181a7f5
LP
592 }
593 }
594
a7e3212d
LP
595 r = bus_socket_auth_verify(b);
596 if (r != 0)
597 return r;
598
599 return 1;
600}
601
8f04d2eb 602void bus_socket_setup(sd_bus *b) {
0f4b73c8 603 int enable;
a7e3212d
LP
604
605 assert(b);
606
d65ddaa4
LP
607 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
608 * socket, just in case. */
0f4b73c8 609 enable = !b->bus_client;
dc751688 610 (void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
264ad849 611
d21a7bb1 612 enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
dc751688 613 (void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d 614
aec6d91f
LP
615 /* Increase the buffers to 8 MB */
616 fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
617 fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 618
e1d337d4
LP
619 b->is_kernel = false;
620 b->message_version = 1;
0f437184 621 b->message_endian = 0;
8f04d2eb 622}
e1d337d4 623
8f04d2eb 624static void bus_get_peercred(sd_bus *b) {
8f04d2eb
LP
625 assert(b);
626
627 /* Get the peer for socketpair() sockets */
eff05270 628 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
a7e3212d
LP
629}
630
2181a7f5 631static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 632 size_t l;
2181a7f5 633 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
634
635 assert(b);
636
2181a7f5
LP
637 if (b->anonymous_auth) {
638 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 639
2181a7f5
LP
640 /* For ANONYMOUS auth we send some arbitrary "trace" string */
641 l = 9;
642 b->auth_buffer = hexmem("anonymous", l);
643 } else {
5ffa8c81 644 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 645
2181a7f5 646 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 647
5ffa8c81 648 xsprintf(text, UID_FMT, geteuid());
a7e3212d 649
2181a7f5
LP
650 l = strlen(text);
651 b->auth_buffer = hexmem(text, l);
652 }
653
654 if (!b->auth_buffer)
a7e3212d
LP
655 return -ENOMEM;
656
264ad849 657 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
658 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
659 else
660 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
661
662 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
663 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
664 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
665 b->auth_iovec[1].iov_len = l * 2;
666 b->auth_iovec[2].iov_base = (void*) auth_suffix;
667 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
668
669 return bus_socket_write_auth(b);
670}
671
a7893c6b 672int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
673 assert(b);
674
8f04d2eb
LP
675 bus_get_peercred(b);
676
2181a7f5
LP
677 b->state = BUS_AUTHENTICATING;
678 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
679
9ab32f9d 680 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 681 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 682
9ab32f9d
LP
683 if (b->output_fd != b->input_fd)
684 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 685 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 686
2181a7f5
LP
687 if (b->is_server)
688 return bus_socket_read_auth(b);
689 else
690 return bus_socket_start_auth_client(b);
691}
692
a7e3212d
LP
693int bus_socket_connect(sd_bus *b) {
694 int r;
695
696 assert(b);
e82c9509
LP
697 assert(b->input_fd < 0);
698 assert(b->output_fd < 0);
a7e3212d
LP
699 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
700
e82c9509
LP
701 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
702 if (b->input_fd < 0)
a7e3212d
LP
703 return -errno;
704
e82c9509
LP
705 b->output_fd = b->input_fd;
706
8f04d2eb 707 bus_socket_setup(b);
a7e3212d 708
e82c9509 709 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
710 if (r < 0) {
711 if (errno == EINPROGRESS)
712 return 1;
713
714 return -errno;
715 }
716
717 return bus_socket_start_auth(b);
718}
719
720int bus_socket_exec(sd_bus *b) {
e82c9509 721 int s[2], r;
a7e3212d
LP
722 pid_t pid;
723
724 assert(b);
e82c9509
LP
725 assert(b->input_fd < 0);
726 assert(b->output_fd < 0);
a7e3212d
LP
727 assert(b->exec_path);
728
e82c9509
LP
729 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
730 if (r < 0)
a7e3212d
LP
731 return -errno;
732
733 pid = fork();
734 if (pid < 0) {
3d94f76c 735 safe_close_pair(s);
a7e3212d
LP
736 return -errno;
737 }
738 if (pid == 0) {
739 /* Child */
740
e82c9509
LP
741 reset_all_signal_handlers();
742
743 close_all_fds(s+1, 1);
a7e3212d
LP
744
745 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
746 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
747
748 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
03e334a1 749 safe_close(s[1]);
a7e3212d
LP
750
751 fd_cloexec(STDIN_FILENO, false);
752 fd_cloexec(STDOUT_FILENO, false);
753 fd_nonblock(STDIN_FILENO, false);
754 fd_nonblock(STDOUT_FILENO, false);
755
756 if (b->exec_argv)
757 execvp(b->exec_path, b->exec_argv);
758 else {
759 const char *argv[] = { b->exec_path, NULL };
760 execvp(b->exec_path, (char**) argv);
761 }
762
763 _exit(EXIT_FAILURE);
764 }
765
03e334a1 766 safe_close(s[1]);
e82c9509 767 b->output_fd = b->input_fd = s[0];
a7e3212d 768
8f04d2eb 769 bus_socket_setup(b);
e1d337d4 770
a7e3212d
LP
771 return bus_socket_start_auth(b);
772}
773
774int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
775 assert(b);
776
8f04d2eb 777 bus_socket_setup(b);
a7e3212d
LP
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];
0461f8cd 877 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
878 a = le32toh(a);
879 b = le32toh(b);
0461f8cd 880 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
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
7adc46fc
LP
903 r = bus_rqueue_make_room(bus);
904 if (r < 0)
905 return r;
906
a7e3212d
LP
907 if (bus->rbuffer_size > size) {
908 b = memdup((const uint8_t*) bus->rbuffer + size,
909 bus->rbuffer_size - size);
910 if (!b)
911 return -ENOMEM;
912 } else
913 b = NULL;
914
df2d202e
LP
915 r = bus_message_from_malloc(bus,
916 bus->rbuffer, size,
a7e3212d 917 bus->fds, bus->n_fds,
038f9863
LP
918 NULL,
919 NULL,
a7e3212d
LP
920 &t);
921 if (r < 0) {
922 free(b);
923 return r;
924 }
925
926 bus->rbuffer = b;
927 bus->rbuffer_size -= size;
928
929 bus->fds = NULL;
930 bus->n_fds = 0;
931
7adc46fc 932 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 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
956 r = bus_socket_read_message_need(bus, &need);
957 if (r < 0)
958 return r;
959
960 if (bus->rbuffer_size >= need)
7d22c717 961 return bus_socket_make_message(bus, need);
a7e3212d
LP
962
963 b = realloc(bus->rbuffer, need);
964 if (!b)
965 return -ENOMEM;
966
967 bus->rbuffer = b;
968
969 zero(iov);
970 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
971 iov.iov_len = need - bus->rbuffer_size;
972
15d5af81
LP
973 if (bus->prefer_readv)
974 k = readv(bus->input_fd, &iov, 1);
975 else {
976 zero(mh);
977 mh.msg_iov = &iov;
978 mh.msg_iovlen = 1;
979 mh.msg_control = &control;
980 mh.msg_controllen = sizeof(control);
981
982 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
983 if (k < 0 && errno == ENOTSOCK) {
984 bus->prefer_readv = true;
985 k = readv(bus->input_fd, &iov, 1);
986 } else
987 handle_cmsg = true;
988 }
a7e3212d
LP
989 if (k < 0)
990 return errno == EAGAIN ? 0 : -errno;
991 if (k == 0)
992 return -ECONNRESET;
993
994 bus->rbuffer_size += k;
995
15d5af81
LP
996 if (handle_cmsg) {
997 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
998 if (cmsg->cmsg_level == SOL_SOCKET &&
999 cmsg->cmsg_type == SCM_RIGHTS) {
1000 int n, *f;
1001
1002 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1003
1004 if (!bus->can_fds) {
1005 /* Whut? We received fds but this
1006 * isn't actually enabled? Close them,
1007 * and fail */
1008
1009 close_many((int*) CMSG_DATA(cmsg), n);
1010 return -EIO;
1011 }
1012
1013 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1014 if (!f) {
1015 close_many((int*) CMSG_DATA(cmsg), n);
1016 return -ENOMEM;
1017 }
1018
1019 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1020 bus->fds = f;
1021 bus->n_fds += n;
1022 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1023 cmsg->cmsg_type == SCM_CREDENTIALS &&
1024 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1025
ea8f194f
LP
1026 /* Ignore bogus data, which we might
1027 * get on socketpair() sockets */
1028 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1029 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1030 bus->ucred_valid = true;
1031 }
15d5af81
LP
1032
1033 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1034 cmsg->cmsg_type == SCM_SECURITY) {
1035
1036 size_t l;
1037 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1038 if (l > 0) {
1039 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1040 bus->label[l] = 0;
1041 }
a7e3212d 1042 }
a7e3212d
LP
1043 }
1044 }
1045
1046 r = bus_socket_read_message_need(bus, &need);
1047 if (r < 0)
1048 return r;
1049
1050 if (bus->rbuffer_size >= need)
7d22c717 1051 return bus_socket_make_message(bus, need);
a7e3212d
LP
1052
1053 return 1;
1054}
1055
1056int bus_socket_process_opening(sd_bus *b) {
1057 int error = 0;
1058 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1059 struct pollfd p = {
1060 .fd = b->output_fd,
1061 .events = POLLOUT,
1062 };
a7e3212d
LP
1063 int r;
1064
a7e3212d
LP
1065 assert(b->state == BUS_OPENING);
1066
a7e3212d
LP
1067 r = poll(&p, 1, 0);
1068 if (r < 0)
1069 return -errno;
1070
1071 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1072 return 0;
1073
e82c9509 1074 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1075 if (r < 0)
1076 b->last_connect_error = errno;
1077 else if (error != 0)
1078 b->last_connect_error = error;
1079 else if (p.revents & (POLLERR|POLLHUP))
1080 b->last_connect_error = ECONNREFUSED;
1081 else
1082 return bus_socket_start_auth(b);
1083
1084 return bus_next_address(b);
1085}
1086
1087int bus_socket_process_authenticating(sd_bus *b) {
1088 int r;
1089
1090 assert(b);
1091 assert(b->state == BUS_AUTHENTICATING);
1092
1093 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1094 return -ETIMEDOUT;
1095
1096 r = bus_socket_write_auth(b);
1097 if (r != 0)
1098 return r;
1099
1100 return bus_socket_read_auth(b);
1101}