]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
CODING_STYLE: document order in which to #include headers
[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
6e6c21c8 180 e = memmem_safe(b->rbuffer, b->rbuffer_size, "\r\n", 2);
a7e3212d
LP
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;
7f4e6a1c 495 struct iovec iov = {};
a7e3212d
LP
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
a7e3212d
LP
530 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
531 iov.iov_len = n - b->rbuffer_size;
532
15d5af81
LP
533 if (b->prefer_readv)
534 k = readv(b->input_fd, &iov, 1);
535 else {
536 zero(mh);
537 mh.msg_iov = &iov;
538 mh.msg_iovlen = 1;
539 mh.msg_control = &control;
540 mh.msg_controllen = sizeof(control);
541
542 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
543 if (k < 0 && errno == ENOTSOCK) {
544 b->prefer_readv = true;
545 k = readv(b->input_fd, &iov, 1);
546 } else
547 handle_cmsg = true;
548 }
a7e3212d
LP
549 if (k < 0)
550 return errno == EAGAIN ? 0 : -errno;
551 if (k == 0)
552 return -ECONNRESET;
553
554 b->rbuffer_size += k;
555
15d5af81
LP
556 if (handle_cmsg) {
557 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
558 if (cmsg->cmsg_level == SOL_SOCKET &&
559 cmsg->cmsg_type == SCM_RIGHTS) {
560 int j;
561
562 /* Whut? We received fds during the auth
563 * protocol? Somebody is playing games with
564 * us. Close them all, and fail */
565 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
566 close_many((int*) CMSG_DATA(cmsg), j);
567 return -EIO;
2181a7f5 568
15d5af81
LP
569 } else if (cmsg->cmsg_level == SOL_SOCKET &&
570 cmsg->cmsg_type == SCM_CREDENTIALS &&
571 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
2181a7f5 572
ea8f194f
LP
573 /* Ignore bogus data, which we might
574 * get on socketpair() sockets */
575 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
576 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
577 b->ucred_valid = true;
578 }
2181a7f5 579
15d5af81
LP
580 } else if (cmsg->cmsg_level == SOL_SOCKET &&
581 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 582
15d5af81 583 size_t l;
ea8f194f 584
15d5af81 585 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
586 if (l > 0) {
587 memcpy(&b->label, CMSG_DATA(cmsg), l);
588 b->label[l] = 0;
589 }
15d5af81 590 }
2181a7f5
LP
591 }
592 }
593
a7e3212d
LP
594 r = bus_socket_auth_verify(b);
595 if (r != 0)
596 return r;
597
598 return 1;
599}
600
8f04d2eb 601void bus_socket_setup(sd_bus *b) {
0f4b73c8 602 int enable;
a7e3212d
LP
603
604 assert(b);
605
d65ddaa4
LP
606 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
607 * socket, just in case. */
0f4b73c8 608 enable = !b->bus_client;
dc751688 609 (void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
264ad849 610
d21a7bb1 611 enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
dc751688 612 (void) setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d 613
aec6d91f
LP
614 /* Increase the buffers to 8 MB */
615 fd_inc_rcvbuf(b->input_fd, SNDBUF_SIZE);
616 fd_inc_sndbuf(b->output_fd, SNDBUF_SIZE);
a7e3212d 617
e1d337d4
LP
618 b->is_kernel = false;
619 b->message_version = 1;
0f437184 620 b->message_endian = 0;
8f04d2eb 621}
e1d337d4 622
8f04d2eb 623static void bus_get_peercred(sd_bus *b) {
8f04d2eb
LP
624 assert(b);
625
626 /* Get the peer for socketpair() sockets */
eff05270 627 b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
a7e3212d
LP
628}
629
2181a7f5 630static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 631 size_t l;
2181a7f5 632 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
633
634 assert(b);
635
2181a7f5
LP
636 if (b->anonymous_auth) {
637 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 638
2181a7f5
LP
639 /* For ANONYMOUS auth we send some arbitrary "trace" string */
640 l = 9;
641 b->auth_buffer = hexmem("anonymous", l);
642 } else {
5ffa8c81 643 char text[DECIMAL_STR_MAX(uid_t) + 1];
a7e3212d 644
2181a7f5 645 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 646
5ffa8c81 647 xsprintf(text, UID_FMT, geteuid());
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
8f04d2eb
LP
674 bus_get_peercred(b);
675
2181a7f5
LP
676 b->state = BUS_AUTHENTICATING;
677 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
678
9ab32f9d 679 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 680 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 681
9ab32f9d
LP
682 if (b->output_fd != b->input_fd)
683 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 684 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 685
2181a7f5
LP
686 if (b->is_server)
687 return bus_socket_read_auth(b);
688 else
689 return bus_socket_start_auth_client(b);
690}
691
a7e3212d
LP
692int bus_socket_connect(sd_bus *b) {
693 int r;
694
695 assert(b);
e82c9509
LP
696 assert(b->input_fd < 0);
697 assert(b->output_fd < 0);
a7e3212d
LP
698 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
699
e82c9509
LP
700 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
701 if (b->input_fd < 0)
a7e3212d
LP
702 return -errno;
703
e82c9509
LP
704 b->output_fd = b->input_fd;
705
8f04d2eb 706 bus_socket_setup(b);
a7e3212d 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) {
3d94f76c 734 safe_close_pair(s);
a7e3212d
LP
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)
03e334a1 748 safe_close(s[1]);
a7e3212d
LP
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
03e334a1 765 safe_close(s[1]);
e82c9509 766 b->output_fd = b->input_fd = s[0];
a7e3212d 767
8f04d2eb 768 bus_socket_setup(b);
e1d337d4 769
a7e3212d
LP
770 return bus_socket_start_auth(b);
771}
772
773int bus_socket_take_fd(sd_bus *b) {
a7e3212d
LP
774 assert(b);
775
8f04d2eb 776 bus_socket_setup(b);
a7e3212d
LP
777
778 return bus_socket_start_auth(b);
779}
780
781int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
782 struct iovec *iov;
783 ssize_t k;
784 size_t n;
785 unsigned j;
bc7fd8cd 786 int r;
a7e3212d
LP
787
788 assert(bus);
789 assert(m);
790 assert(idx);
791 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
792
6629161f 793 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 794 return 0;
a7e3212d 795
bc7fd8cd
LP
796 r = bus_message_setup_iovec(m);
797 if (r < 0)
798 return r;
2100fa10 799
a7e3212d
LP
800 n = m->n_iovec * sizeof(struct iovec);
801 iov = alloca(n);
802 memcpy(iov, m->iovec, n);
803
804 j = 0;
805 iovec_advance(iov, &j, *idx);
806
15d5af81
LP
807 if (bus->prefer_writev)
808 k = writev(bus->output_fd, iov, m->n_iovec);
809 else {
7f4e6a1c
ZJS
810 struct msghdr mh = {
811 .msg_iov = iov,
812 .msg_iovlen = m->n_iovec,
813 };
15d5af81
LP
814
815 if (m->n_fds > 0) {
816 struct cmsghdr *control;
15d5af81 817
7f4e6a1c
ZJS
818 mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
819 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
15d5af81
LP
820 control->cmsg_level = SOL_SOCKET;
821 control->cmsg_type = SCM_RIGHTS;
15d5af81
LP
822 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
823 }
824
15d5af81
LP
825 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
826 if (k < 0 && errno == ENOTSOCK) {
827 bus->prefer_writev = true;
828 k = writev(bus->output_fd, iov, m->n_iovec);
829 }
830 }
a7e3212d 831
a7e3212d
LP
832 if (k < 0)
833 return errno == EAGAIN ? 0 : -errno;
834
835 *idx += (size_t) k;
836 return 1;
837}
838
839static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
840 uint32_t a, b;
841 uint8_t e;
842 uint64_t sum;
843
844 assert(bus);
845 assert(need);
846 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
847
848 if (bus->rbuffer_size < sizeof(struct bus_header)) {
849 *need = sizeof(struct bus_header) + 8;
850
851 /* Minimum message size:
852 *
853 * Header +
854 *
855 * Method Call: +2 string headers
856 * Signal: +3 string headers
857 * Method Error: +1 string headers
858 * +1 uint32 headers
859 * Method Reply: +1 uint32 headers
860 *
861 * A string header is at least 9 bytes
862 * A uint32 header is at least 8 bytes
863 *
864 * Hence the minimum message size of a valid message
865 * is header + 8 bytes */
866
867 return 0;
868 }
869
870 a = ((const uint32_t*) bus->rbuffer)[1];
871 b = ((const uint32_t*) bus->rbuffer)[3];
872
873 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 874 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
875 a = le32toh(a);
876 b = le32toh(b);
0461f8cd 877 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
878 a = be32toh(a);
879 b = be32toh(b);
880 } else
881 return -EBADMSG;
882
883 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
884 if (sum >= BUS_MESSAGE_SIZE_MAX)
885 return -ENOBUFS;
886
887 *need = (size_t) sum;
888 return 0;
889}
890
7d22c717 891static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
892 sd_bus_message *t;
893 void *b;
894 int r;
895
896 assert(bus);
a7e3212d
LP
897 assert(bus->rbuffer_size >= size);
898 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
899
7adc46fc
LP
900 r = bus_rqueue_make_room(bus);
901 if (r < 0)
902 return r;
903
a7e3212d
LP
904 if (bus->rbuffer_size > size) {
905 b = memdup((const uint8_t*) bus->rbuffer + size,
906 bus->rbuffer_size - size);
907 if (!b)
908 return -ENOMEM;
909 } else
910 b = NULL;
911
df2d202e
LP
912 r = bus_message_from_malloc(bus,
913 bus->rbuffer, size,
a7e3212d 914 bus->fds, bus->n_fds,
038f9863
LP
915 NULL,
916 NULL,
a7e3212d
LP
917 &t);
918 if (r < 0) {
919 free(b);
920 return r;
921 }
922
923 bus->rbuffer = b;
924 bus->rbuffer_size -= size;
925
926 bus->fds = NULL;
927 bus->n_fds = 0;
928
7adc46fc 929 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 930
a7e3212d
LP
931 return 1;
932}
933
7d22c717 934int bus_socket_read_message(sd_bus *bus) {
a7e3212d 935 struct msghdr mh;
7f4e6a1c 936 struct iovec iov = {};
a7e3212d
LP
937 ssize_t k;
938 size_t need;
939 int r;
940 void *b;
941 union {
942 struct cmsghdr cmsghdr;
943 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
944 CMSG_SPACE(sizeof(struct ucred)) +
945 CMSG_SPACE(NAME_MAX)]; /*selinux label */
946 } control;
947 struct cmsghdr *cmsg;
4d3a5b10 948 bool handle_cmsg = false;
a7e3212d
LP
949
950 assert(bus);
a7e3212d
LP
951 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
952
953 r = bus_socket_read_message_need(bus, &need);
954 if (r < 0)
955 return r;
956
957 if (bus->rbuffer_size >= need)
7d22c717 958 return bus_socket_make_message(bus, need);
a7e3212d
LP
959
960 b = realloc(bus->rbuffer, need);
961 if (!b)
962 return -ENOMEM;
963
964 bus->rbuffer = b;
965
a7e3212d
LP
966 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
967 iov.iov_len = need - bus->rbuffer_size;
968
15d5af81
LP
969 if (bus->prefer_readv)
970 k = readv(bus->input_fd, &iov, 1);
971 else {
972 zero(mh);
973 mh.msg_iov = &iov;
974 mh.msg_iovlen = 1;
975 mh.msg_control = &control;
976 mh.msg_controllen = sizeof(control);
977
978 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
979 if (k < 0 && errno == ENOTSOCK) {
980 bus->prefer_readv = true;
981 k = readv(bus->input_fd, &iov, 1);
982 } else
983 handle_cmsg = true;
984 }
a7e3212d
LP
985 if (k < 0)
986 return errno == EAGAIN ? 0 : -errno;
987 if (k == 0)
988 return -ECONNRESET;
989
990 bus->rbuffer_size += k;
991
15d5af81
LP
992 if (handle_cmsg) {
993 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
994 if (cmsg->cmsg_level == SOL_SOCKET &&
995 cmsg->cmsg_type == SCM_RIGHTS) {
996 int n, *f;
997
998 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
999
1000 if (!bus->can_fds) {
1001 /* Whut? We received fds but this
1002 * isn't actually enabled? Close them,
1003 * and fail */
1004
1005 close_many((int*) CMSG_DATA(cmsg), n);
1006 return -EIO;
1007 }
1008
1009 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1010 if (!f) {
1011 close_many((int*) CMSG_DATA(cmsg), n);
1012 return -ENOMEM;
1013 }
1014
1015 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1016 bus->fds = f;
1017 bus->n_fds += n;
1018 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1019 cmsg->cmsg_type == SCM_CREDENTIALS &&
1020 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1021
ea8f194f
LP
1022 /* Ignore bogus data, which we might
1023 * get on socketpair() sockets */
1024 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1025 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1026 bus->ucred_valid = true;
1027 }
15d5af81
LP
1028
1029 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1030 cmsg->cmsg_type == SCM_SECURITY) {
1031
1032 size_t l;
1033 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1034 if (l > 0) {
1035 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1036 bus->label[l] = 0;
1037 }
a7e3212d 1038 }
a7e3212d
LP
1039 }
1040 }
1041
1042 r = bus_socket_read_message_need(bus, &need);
1043 if (r < 0)
1044 return r;
1045
1046 if (bus->rbuffer_size >= need)
7d22c717 1047 return bus_socket_make_message(bus, need);
a7e3212d
LP
1048
1049 return 1;
1050}
1051
1052int bus_socket_process_opening(sd_bus *b) {
1053 int error = 0;
1054 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1055 struct pollfd p = {
1056 .fd = b->output_fd,
1057 .events = POLLOUT,
1058 };
a7e3212d
LP
1059 int r;
1060
a7e3212d
LP
1061 assert(b->state == BUS_OPENING);
1062
a7e3212d
LP
1063 r = poll(&p, 1, 0);
1064 if (r < 0)
1065 return -errno;
1066
1067 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1068 return 0;
1069
e82c9509 1070 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1071 if (r < 0)
1072 b->last_connect_error = errno;
1073 else if (error != 0)
1074 b->last_connect_error = error;
1075 else if (p.revents & (POLLERR|POLLHUP))
1076 b->last_connect_error = ECONNREFUSED;
1077 else
1078 return bus_socket_start_auth(b);
1079
1080 return bus_next_address(b);
1081}
1082
1083int bus_socket_process_authenticating(sd_bus *b) {
1084 int r;
1085
1086 assert(b);
1087 assert(b->state == BUS_AUTHENTICATING);
1088
1089 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1090 return -ETIMEDOUT;
1091
1092 r = bus_socket_write_auth(b);
1093 if (r != 0)
1094 return r;
1095
1096 return bus_socket_read_auth(b);
1097}