]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-socket.c
core: ignore any issues with setting time on jobs_in_progress_event_source
[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"
a7e3212d
LP
32
33#include "sd-bus.h"
34#include "bus-socket.h"
35#include "bus-internal.h"
36#include "bus-message.h"
37
aec6d91f
LP
38#define SNDBUF_SIZE (8*1024*1024)
39
2181a7f5 40static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
a7e3212d
LP
41
42 while (size > 0) {
43 struct iovec *i = iov + *idx;
44
45 if (i->iov_len > size) {
46 i->iov_base = (uint8_t*) i->iov_base + size;
47 i->iov_len -= size;
48 return;
49 }
50
51 size -= i->iov_len;
52
53 i->iov_base = NULL;
54 i->iov_len = 0;
55
56 (*idx) ++;
57 }
58}
59
bc7fd8cd 60static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
2100fa10
LP
61 assert(m);
62 assert(p);
63 assert(sz > 0);
64
65 m->iovec[m->n_iovec].iov_base = (void*) p;
66 m->iovec[m->n_iovec].iov_len = sz;
67 m->n_iovec++;
bc7fd8cd
LP
68
69 return 0;
2100fa10
LP
70}
71
bc7fd8cd
LP
72static int bus_message_setup_iovec(sd_bus_message *m) {
73 struct bus_body_part *part;
13c299d3 74 unsigned n, i;
bc7fd8cd
LP
75 int r;
76
2100fa10
LP
77 assert(m);
78 assert(m->sealed);
79
80 if (m->n_iovec > 0)
bc7fd8cd
LP
81 return 0;
82
83 assert(!m->iovec);
2100fa10 84
c91cb83c 85 n = 1 + m->n_body_parts;
bc7fd8cd
LP
86 if (n < ELEMENTSOF(m->iovec_fixed))
87 m->iovec = m->iovec_fixed;
88 else {
89 m->iovec = new(struct iovec, n);
66b26c5c
LP
90 if (!m->iovec) {
91 r = -ENOMEM;
92 goto fail;
93 }
bc7fd8cd 94 }
2100fa10 95
c91cb83c 96 r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
bc7fd8cd 97 if (r < 0)
66b26c5c 98 goto fail;
2100fa10 99
9b29bb68 100 MESSAGE_FOREACH_PART(part, i, m) {
66b26c5c
LP
101 r = bus_body_part_map(part);
102 if (r < 0)
103 goto fail;
104
bc7fd8cd
LP
105 r = append_iovec(m, part->data, part->size);
106 if (r < 0)
66b26c5c 107 goto fail;
bc7fd8cd
LP
108 }
109
110 assert(n == m->n_iovec);
111
112 return 0;
66b26c5c
LP
113
114fail:
115 m->poisoned = true;
116 return r;
2100fa10
LP
117}
118
2181a7f5
LP
119bool bus_socket_auth_needs_write(sd_bus *b) {
120
121 unsigned i;
122
123 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
124 return false;
125
126 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
127 struct iovec *j = b->auth_iovec + i;
128
129 if (j->iov_len > 0)
130 return true;
131 }
132
133 return false;
134}
135
a7e3212d 136static int bus_socket_write_auth(sd_bus *b) {
a7e3212d
LP
137 ssize_t k;
138
139 assert(b);
140 assert(b->state == BUS_AUTHENTICATING);
141
2181a7f5 142 if (!bus_socket_auth_needs_write(b))
a7e3212d
LP
143 return 0;
144
15d5af81
LP
145 if (b->prefer_writev)
146 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
147 else {
148 struct msghdr mh;
149 zero(mh);
150
151 mh.msg_iov = b->auth_iovec + b->auth_index;
152 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
153
154 k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
155 if (k < 0 && errno == ENOTSOCK) {
156 b->prefer_writev = true;
157 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
158 }
159 }
a7e3212d 160
a7e3212d
LP
161 if (k < 0)
162 return errno == EAGAIN ? 0 : -errno;
163
164 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
a7e3212d
LP
165 return 1;
166}
167
2181a7f5 168static int bus_socket_auth_verify_client(sd_bus *b) {
a7e3212d
LP
169 char *e, *f, *start;
170 sd_id128_t peer;
171 unsigned i;
172 int r;
173
2181a7f5
LP
174 assert(b);
175
a7e3212d
LP
176 /* We expect two response lines: "OK" and possibly
177 * "AGREE_UNIX_FD" */
178
179 e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2);
180 if (!e)
181 return 0;
182
264ad849 183 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) {
a7e3212d
LP
184 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
185 if (!f)
186 return 0;
187
188 start = f + 2;
189 } else {
190 f = NULL;
191 start = e + 2;
192 }
193
194 /* Nice! We got all the lines we need. First check the OK
195 * line */
196
197 if (e - (char*) b->rbuffer != 3 + 32)
198 return -EPERM;
199
200 if (memcmp(b->rbuffer, "OK ", 3))
201 return -EPERM;
202
2181a7f5
LP
203 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
204
a7e3212d
LP
205 for (i = 0; i < 32; i += 2) {
206 int x, y;
207
208 x = unhexchar(((char*) b->rbuffer)[3 + i]);
209 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
210
211 if (x < 0 || y < 0)
212 return -EINVAL;
213
214 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
215 }
216
98178d39
LP
217 if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
218 !sd_id128_equal(b->server_id, peer))
a7e3212d
LP
219 return -EPERM;
220
98178d39 221 b->server_id = peer;
a7e3212d
LP
222
223 /* And possibly check the second line, too */
224
225 if (f)
226 b->can_fds =
f8294e41
JT
227 (f - e == strlen("\r\nAGREE_UNIX_FD")) &&
228 memcmp(e + 2, "AGREE_UNIX_FD", strlen("AGREE_UNIX_FD")) == 0;
a7e3212d
LP
229
230 b->rbuffer_size -= (start - (char*) b->rbuffer);
231 memmove(b->rbuffer, start, b->rbuffer_size);
232
233 r = bus_start_running(b);
234 if (r < 0)
235 return r;
236
237 return 1;
238}
239
2181a7f5
LP
240static bool line_equals(const char *s, size_t m, const char *line) {
241 size_t l;
242
243 l = strlen(line);
244 if (l != m)
245 return false;
246
247 return memcmp(s, line, l) == 0;
248}
249
250static bool line_begins(const char *s, size_t m, const char *word) {
251 size_t l;
252
253 l = strlen(word);
254 if (m < l)
255 return false;
256
257 if (memcmp(s, word, l) != 0)
258 return false;
259
260 return m == l || (m > l && s[l] == ' ');
261}
262
263static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
264 _cleanup_free_ char *token = NULL;
265
266 if (!b->anonymous_auth)
267 return 0;
268
269 if (l <= 0)
270 return 1;
271
272 assert(p[0] == ' ');
273 p++; l--;
274
275 if (l % 2 != 0)
276 return 0;
277 token = unhexmem(p, l);
278 if (!token)
279 return -ENOMEM;
280
281 if (memchr(token, 0, l/2))
282 return 0;
283
284 return !!utf8_is_valid(token);
285}
286
287static int verify_external_token(sd_bus *b, const char *p, size_t l) {
288 _cleanup_free_ char *token = NULL;
289 uid_t u;
290 int r;
291
292 /* We don't do any real authentication here. Instead, we if
293 * the owner of this bus wanted authentication he should have
294 * checked SO_PEERCRED before even creating the bus object. */
295
8411d2a2 296 if (!b->anonymous_auth && !b->ucred_valid)
2181a7f5
LP
297 return 0;
298
299 if (l <= 0)
300 return 1;
301
302 assert(p[0] == ' ');
303 p++; l--;
304
305 if (l % 2 != 0)
306 return 0;
307
308 token = unhexmem(p, l);
309 if (!token)
310 return -ENOMEM;
311
312 if (memchr(token, 0, l/2))
313 return 0;
314
315 r = parse_uid(token, &u);
316 if (r < 0)
317 return 0;
318
8411d2a2
LP
319 /* We ignore the passed value if anonymous authentication is
320 * on anyway. */
321 if (!b->anonymous_auth && u != b->ucred.uid)
2181a7f5
LP
322 return 0;
323
324 return 1;
325}
326
327static int bus_socket_auth_write(sd_bus *b, const char *t) {
328 char *p;
329 size_t l;
330
331 assert(b);
332 assert(t);
333
334 /* We only make use of the first iovec */
335 assert(b->auth_index == 0 || b->auth_index == 1);
336
337 l = strlen(t);
338 p = malloc(b->auth_iovec[0].iov_len + l);
339 if (!p)
340 return -ENOMEM;
341
342 memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
343 memcpy(p + b->auth_iovec[0].iov_len, t, l);
344
345 b->auth_iovec[0].iov_base = p;
346 b->auth_iovec[0].iov_len += l;
347
348 free(b->auth_buffer);
349 b->auth_buffer = p;
350 b->auth_index = 0;
351 return 0;
352}
353
354static int bus_socket_auth_write_ok(sd_bus *b) {
355 char t[3 + 32 + 2 + 1];
356
357 assert(b);
358
5ffa8c81 359 xsprintf(t, "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
360
361 return bus_socket_auth_write(b, t);
362}
363
364static int bus_socket_auth_verify_server(sd_bus *b) {
365 char *e;
366 const char *line;
367 size_t l;
368 bool processed = false;
369 int r;
370
371 assert(b);
372
2b4ac889 373 if (b->rbuffer_size < 1)
2181a7f5
LP
374 return 0;
375
376 /* First char must be a NUL byte */
377 if (*(char*) b->rbuffer != 0)
378 return -EIO;
379
2b4ac889
LP
380 if (b->rbuffer_size < 3)
381 return 0;
382
2181a7f5
LP
383 /* Begin with the first line */
384 if (b->auth_rbegin <= 0)
385 b->auth_rbegin = 1;
386
387 for (;;) {
388 /* Check if line is complete */
389 line = (char*) b->rbuffer + b->auth_rbegin;
390 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
391 if (!e)
392 return processed;
393
394 l = e - line;
395
396 if (line_begins(line, l, "AUTH ANONYMOUS")) {
397
398 r = verify_anonymous_token(b, line + 14, l - 14);
399 if (r < 0)
400 return r;
401 if (r == 0)
402 r = bus_socket_auth_write(b, "REJECTED\r\n");
403 else {
404 b->auth = BUS_AUTH_ANONYMOUS;
405 r = bus_socket_auth_write_ok(b);
406 }
407
408 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
409
410 r = verify_external_token(b, line + 13, l - 13);
411 if (r < 0)
412 return r;
413 if (r == 0)
414 r = bus_socket_auth_write(b, "REJECTED\r\n");
415 else {
416 b->auth = BUS_AUTH_EXTERNAL;
417 r = bus_socket_auth_write_ok(b);
418 }
419
420 } else if (line_begins(line, l, "AUTH"))
421 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
422 else if (line_equals(line, l, "CANCEL") ||
423 line_begins(line, l, "ERROR")) {
424
425 b->auth = _BUS_AUTH_INVALID;
426 r = bus_socket_auth_write(b, "REJECTED\r\n");
427
428 } else if (line_equals(line, l, "BEGIN")) {
429
430 if (b->auth == _BUS_AUTH_INVALID)
431 r = bus_socket_auth_write(b, "ERROR\r\n");
432 else {
433 /* We can't leave from the auth phase
434 * before we haven't written
435 * everything queued, so let's check
436 * that */
437
438 if (bus_socket_auth_needs_write(b))
439 return 1;
440
441 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
442 memmove(b->rbuffer, e + 2, b->rbuffer_size);
443 return bus_start_running(b);
444 }
445
446 } else if (line_begins(line, l, "DATA")) {
447
448 if (b->auth == _BUS_AUTH_INVALID)
449 r = bus_socket_auth_write(b, "ERROR\r\n");
450 else {
451 if (b->auth == BUS_AUTH_ANONYMOUS)
452 r = verify_anonymous_token(b, line + 4, l - 4);
453 else
454 r = verify_external_token(b, line + 4, l - 4);
455
456 if (r < 0)
457 return r;
458 if (r == 0) {
459 b->auth = _BUS_AUTH_INVALID;
460 r = bus_socket_auth_write(b, "REJECTED\r\n");
461 } else
462 r = bus_socket_auth_write_ok(b);
463 }
464 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
264ad849 465 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
2181a7f5
LP
466 r = bus_socket_auth_write(b, "ERROR\r\n");
467 else {
468 b->can_fds = true;
469 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
470 }
471 } else
472 r = bus_socket_auth_write(b, "ERROR\r\n");
473
474 if (r < 0)
475 return r;
476
477 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
478
479 processed = true;
480 }
481}
482
483static int bus_socket_auth_verify(sd_bus *b) {
484 assert(b);
485
486 if (b->is_server)
487 return bus_socket_auth_verify_server(b);
488 else
489 return bus_socket_auth_verify_client(b);
490}
491
a7e3212d
LP
492static int bus_socket_read_auth(sd_bus *b) {
493 struct msghdr mh;
494 struct iovec iov;
495 size_t n;
496 ssize_t k;
497 int r;
498 void *p;
2181a7f5
LP
499 union {
500 struct cmsghdr cmsghdr;
501 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
502 CMSG_SPACE(sizeof(struct ucred)) +
503 CMSG_SPACE(NAME_MAX)]; /*selinux label */
504 } control;
505 struct cmsghdr *cmsg;
15d5af81 506 bool handle_cmsg = false;
a7e3212d
LP
507
508 assert(b);
2181a7f5 509 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
510
511 r = bus_socket_auth_verify(b);
512 if (r != 0)
513 return r;
514
9607d947 515 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
516
517 if (n > BUS_AUTH_SIZE_MAX)
518 n = BUS_AUTH_SIZE_MAX;
519
520 if (b->rbuffer_size >= n)
521 return -ENOBUFS;
522
523 p = realloc(b->rbuffer, n);
524 if (!p)
525 return -ENOMEM;
526
527 b->rbuffer = p;
528
529 zero(iov);
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;
3aeaee97 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);
3aeaee97 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 {
810 struct msghdr mh;
811 zero(mh);
812
813 if (m->n_fds > 0) {
814 struct cmsghdr *control;
815 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
816
817 mh.msg_control = control;
818 control->cmsg_level = SOL_SOCKET;
819 control->cmsg_type = SCM_RIGHTS;
820 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
821 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
822 }
823
824 mh.msg_iov = iov;
825 mh.msg_iovlen = m->n_iovec;
826
827 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
828 if (k < 0 && errno == ENOTSOCK) {
829 bus->prefer_writev = true;
830 k = writev(bus->output_fd, iov, m->n_iovec);
831 }
832 }
a7e3212d 833
a7e3212d
LP
834 if (k < 0)
835 return errno == EAGAIN ? 0 : -errno;
836
837 *idx += (size_t) k;
838 return 1;
839}
840
841static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
842 uint32_t a, b;
843 uint8_t e;
844 uint64_t sum;
845
846 assert(bus);
847 assert(need);
848 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
849
850 if (bus->rbuffer_size < sizeof(struct bus_header)) {
851 *need = sizeof(struct bus_header) + 8;
852
853 /* Minimum message size:
854 *
855 * Header +
856 *
857 * Method Call: +2 string headers
858 * Signal: +3 string headers
859 * Method Error: +1 string headers
860 * +1 uint32 headers
861 * Method Reply: +1 uint32 headers
862 *
863 * A string header is at least 9 bytes
864 * A uint32 header is at least 8 bytes
865 *
866 * Hence the minimum message size of a valid message
867 * is header + 8 bytes */
868
869 return 0;
870 }
871
872 a = ((const uint32_t*) bus->rbuffer)[1];
873 b = ((const uint32_t*) bus->rbuffer)[3];
874
875 e = ((const uint8_t*) bus->rbuffer)[0];
0461f8cd 876 if (e == BUS_LITTLE_ENDIAN) {
a7e3212d
LP
877 a = le32toh(a);
878 b = le32toh(b);
0461f8cd 879 } else if (e == BUS_BIG_ENDIAN) {
a7e3212d
LP
880 a = be32toh(a);
881 b = be32toh(b);
882 } else
883 return -EBADMSG;
884
885 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
886 if (sum >= BUS_MESSAGE_SIZE_MAX)
887 return -ENOBUFS;
888
889 *need = (size_t) sum;
890 return 0;
891}
892
7d22c717 893static int bus_socket_make_message(sd_bus *bus, size_t size) {
a7e3212d
LP
894 sd_bus_message *t;
895 void *b;
896 int r;
897
898 assert(bus);
a7e3212d
LP
899 assert(bus->rbuffer_size >= size);
900 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
901
7adc46fc
LP
902 r = bus_rqueue_make_room(bus);
903 if (r < 0)
904 return r;
905
a7e3212d
LP
906 if (bus->rbuffer_size > size) {
907 b = memdup((const uint8_t*) bus->rbuffer + size,
908 bus->rbuffer_size - size);
909 if (!b)
910 return -ENOMEM;
911 } else
912 b = NULL;
913
df2d202e
LP
914 r = bus_message_from_malloc(bus,
915 bus->rbuffer, size,
a7e3212d 916 bus->fds, bus->n_fds,
e7f7a1b0
LP
917 !bus->bus_client && bus->ucred_valid ? &bus->ucred : NULL,
918 !bus->bus_client && bus->label[0] ? bus->label : NULL,
a7e3212d
LP
919 &t);
920 if (r < 0) {
921 free(b);
922 return r;
923 }
924
925 bus->rbuffer = b;
926 bus->rbuffer_size -= size;
927
928 bus->fds = NULL;
929 bus->n_fds = 0;
930
7adc46fc 931 bus->rqueue[bus->rqueue_size++] = t;
7d22c717 932
a7e3212d
LP
933 return 1;
934}
935
7d22c717 936int bus_socket_read_message(sd_bus *bus) {
a7e3212d
LP
937 struct msghdr mh;
938 struct iovec iov;
939 ssize_t k;
940 size_t need;
941 int r;
942 void *b;
943 union {
944 struct cmsghdr cmsghdr;
945 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
946 CMSG_SPACE(sizeof(struct ucred)) +
947 CMSG_SPACE(NAME_MAX)]; /*selinux label */
948 } control;
949 struct cmsghdr *cmsg;
4d3a5b10 950 bool handle_cmsg = false;
a7e3212d
LP
951
952 assert(bus);
a7e3212d
LP
953 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
954
955 r = bus_socket_read_message_need(bus, &need);
956 if (r < 0)
957 return r;
958
959 if (bus->rbuffer_size >= need)
7d22c717 960 return bus_socket_make_message(bus, need);
a7e3212d
LP
961
962 b = realloc(bus->rbuffer, need);
963 if (!b)
964 return -ENOMEM;
965
966 bus->rbuffer = b;
967
968 zero(iov);
969 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
970 iov.iov_len = need - bus->rbuffer_size;
971
15d5af81
LP
972 if (bus->prefer_readv)
973 k = readv(bus->input_fd, &iov, 1);
974 else {
975 zero(mh);
976 mh.msg_iov = &iov;
977 mh.msg_iovlen = 1;
978 mh.msg_control = &control;
979 mh.msg_controllen = sizeof(control);
980
981 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
982 if (k < 0 && errno == ENOTSOCK) {
983 bus->prefer_readv = true;
984 k = readv(bus->input_fd, &iov, 1);
985 } else
986 handle_cmsg = true;
987 }
a7e3212d
LP
988 if (k < 0)
989 return errno == EAGAIN ? 0 : -errno;
990 if (k == 0)
991 return -ECONNRESET;
992
993 bus->rbuffer_size += k;
994
15d5af81
LP
995 if (handle_cmsg) {
996 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
997 if (cmsg->cmsg_level == SOL_SOCKET &&
998 cmsg->cmsg_type == SCM_RIGHTS) {
999 int n, *f;
1000
1001 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
1002
1003 if (!bus->can_fds) {
1004 /* Whut? We received fds but this
1005 * isn't actually enabled? Close them,
1006 * and fail */
1007
1008 close_many((int*) CMSG_DATA(cmsg), n);
1009 return -EIO;
1010 }
1011
1012 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1013 if (!f) {
1014 close_many((int*) CMSG_DATA(cmsg), n);
1015 return -ENOMEM;
1016 }
1017
1018 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1019 bus->fds = f;
1020 bus->n_fds += n;
1021 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1022 cmsg->cmsg_type == SCM_CREDENTIALS &&
1023 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1024
ea8f194f
LP
1025 /* Ignore bogus data, which we might
1026 * get on socketpair() sockets */
1027 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1028 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1029 bus->ucred_valid = true;
1030 }
15d5af81
LP
1031
1032 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1033 cmsg->cmsg_type == SCM_SECURITY) {
1034
1035 size_t l;
1036 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1037 if (l > 0) {
1038 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1039 bus->label[l] = 0;
1040 }
a7e3212d 1041 }
a7e3212d
LP
1042 }
1043 }
1044
1045 r = bus_socket_read_message_need(bus, &need);
1046 if (r < 0)
1047 return r;
1048
1049 if (bus->rbuffer_size >= need)
7d22c717 1050 return bus_socket_make_message(bus, need);
a7e3212d
LP
1051
1052 return 1;
1053}
1054
1055int bus_socket_process_opening(sd_bus *b) {
1056 int error = 0;
1057 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1058 struct pollfd p = {
1059 .fd = b->output_fd,
1060 .events = POLLOUT,
1061 };
a7e3212d
LP
1062 int r;
1063
a7e3212d
LP
1064 assert(b->state == BUS_OPENING);
1065
a7e3212d
LP
1066 r = poll(&p, 1, 0);
1067 if (r < 0)
1068 return -errno;
1069
1070 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1071 return 0;
1072
e82c9509 1073 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1074 if (r < 0)
1075 b->last_connect_error = errno;
1076 else if (error != 0)
1077 b->last_connect_error = error;
1078 else if (p.revents & (POLLERR|POLLHUP))
1079 b->last_connect_error = ECONNREFUSED;
1080 else
1081 return bus_socket_start_auth(b);
1082
1083 return bus_next_address(b);
1084}
1085
1086int bus_socket_process_authenticating(sd_bus *b) {
1087 int r;
1088
1089 assert(b);
1090 assert(b->state == BUS_AUTHENTICATING);
1091
1092 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1093 return -ETIMEDOUT;
1094
1095 r = bus_socket_write_auth(b);
1096 if (r != 0)
1097 return r;
1098
1099 return bus_socket_read_auth(b);
1100}