]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: fix rewinding in gvariant messages
[thirdparty/systemd.git] / src / libsystemd-bus / bus-socket.c
CommitLineData
a7e3212d
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <endian.h>
23#include <assert.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <sys/poll.h>
27#include <byteswap.h>
28
29#include "util.h"
30#include "macro.h"
31#include "missing.h"
32#include "strv.h"
2181a7f5 33#include "utf8.h"
9ab32f9d 34#include "sd-daemon.h"
a7e3212d
LP
35
36#include "sd-bus.h"
37#include "bus-socket.h"
38#include "bus-internal.h"
39#include "bus-message.h"
40
2181a7f5 41static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
a7e3212d
LP
42
43 while (size > 0) {
44 struct iovec *i = iov + *idx;
45
46 if (i->iov_len > size) {
47 i->iov_base = (uint8_t*) i->iov_base + size;
48 i->iov_len -= size;
49 return;
50 }
51
52 size -= i->iov_len;
53
54 i->iov_base = NULL;
55 i->iov_len = 0;
56
57 (*idx) ++;
58 }
59}
60
bc7fd8cd 61static int append_iovec(sd_bus_message *m, const void *p, size_t sz) {
2100fa10
LP
62 assert(m);
63 assert(p);
64 assert(sz > 0);
65
66 m->iovec[m->n_iovec].iov_base = (void*) p;
67 m->iovec[m->n_iovec].iov_len = sz;
68 m->n_iovec++;
bc7fd8cd
LP
69
70 return 0;
2100fa10
LP
71}
72
bc7fd8cd
LP
73static int bus_message_setup_iovec(sd_bus_message *m) {
74 struct bus_body_part *part;
13c299d3 75 unsigned n, i;
bc7fd8cd
LP
76 int r;
77
2100fa10
LP
78 assert(m);
79 assert(m->sealed);
80
81 if (m->n_iovec > 0)
bc7fd8cd
LP
82 return 0;
83
84 assert(!m->iovec);
2100fa10 85
c91cb83c 86 n = 1 + m->n_body_parts;
bc7fd8cd
LP
87 if (n < ELEMENTSOF(m->iovec_fixed))
88 m->iovec = m->iovec_fixed;
89 else {
90 m->iovec = new(struct iovec, n);
66b26c5c
LP
91 if (!m->iovec) {
92 r = -ENOMEM;
93 goto fail;
94 }
bc7fd8cd 95 }
2100fa10 96
c91cb83c 97 r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m));
bc7fd8cd 98 if (r < 0)
66b26c5c 99 goto fail;
2100fa10 100
9b29bb68 101 MESSAGE_FOREACH_PART(part, i, m) {
66b26c5c
LP
102 r = bus_body_part_map(part);
103 if (r < 0)
104 goto fail;
105
bc7fd8cd
LP
106 r = append_iovec(m, part->data, part->size);
107 if (r < 0)
66b26c5c 108 goto fail;
bc7fd8cd
LP
109 }
110
111 assert(n == m->n_iovec);
112
113 return 0;
66b26c5c
LP
114
115fail:
116 m->poisoned = true;
117 return r;
2100fa10
LP
118}
119
2181a7f5
LP
120bool bus_socket_auth_needs_write(sd_bus *b) {
121
122 unsigned i;
123
124 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
125 return false;
126
127 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
128 struct iovec *j = b->auth_iovec + i;
129
130 if (j->iov_len > 0)
131 return true;
132 }
133
134 return false;
135}
136
a7e3212d 137static int bus_socket_write_auth(sd_bus *b) {
a7e3212d
LP
138 ssize_t k;
139
140 assert(b);
141 assert(b->state == BUS_AUTHENTICATING);
142
2181a7f5 143 if (!bus_socket_auth_needs_write(b))
a7e3212d
LP
144 return 0;
145
15d5af81
LP
146 if (b->prefer_writev)
147 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
148 else {
149 struct msghdr mh;
150 zero(mh);
151
152 mh.msg_iov = b->auth_iovec + b->auth_index;
153 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
154
155 k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
156 if (k < 0 && errno == ENOTSOCK) {
157 b->prefer_writev = true;
158 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
159 }
160 }
a7e3212d 161
a7e3212d
LP
162 if (k < 0)
163 return errno == EAGAIN ? 0 : -errno;
164
165 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
a7e3212d
LP
166 return 1;
167}
168
2181a7f5 169static int bus_socket_auth_verify_client(sd_bus *b) {
a7e3212d
LP
170 char *e, *f, *start;
171 sd_id128_t peer;
172 unsigned i;
173 int r;
174
2181a7f5
LP
175 assert(b);
176
a7e3212d
LP
177 /* We expect two response lines: "OK" and possibly
178 * "AGREE_UNIX_FD" */
179
180 e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2);
181 if (!e)
182 return 0;
183
264ad849 184 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) {
a7e3212d
LP
185 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
186 if (!f)
187 return 0;
188
189 start = f + 2;
190 } else {
191 f = NULL;
192 start = e + 2;
193 }
194
195 /* Nice! We got all the lines we need. First check the OK
196 * line */
197
198 if (e - (char*) b->rbuffer != 3 + 32)
199 return -EPERM;
200
201 if (memcmp(b->rbuffer, "OK ", 3))
202 return -EPERM;
203
2181a7f5
LP
204 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
205
a7e3212d
LP
206 for (i = 0; i < 32; i += 2) {
207 int x, y;
208
209 x = unhexchar(((char*) b->rbuffer)[3 + i]);
210 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
211
212 if (x < 0 || y < 0)
213 return -EINVAL;
214
215 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
216 }
217
98178d39
LP
218 if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
219 !sd_id128_equal(b->server_id, peer))
a7e3212d
LP
220 return -EPERM;
221
98178d39 222 b->server_id = peer;
a7e3212d
LP
223
224 /* And possibly check the second line, too */
225
226 if (f)
227 b->can_fds =
228 (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
229 memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
230
231 b->rbuffer_size -= (start - (char*) b->rbuffer);
232 memmove(b->rbuffer, start, b->rbuffer_size);
233
234 r = bus_start_running(b);
235 if (r < 0)
236 return r;
237
238 return 1;
239}
240
2181a7f5
LP
241static bool line_equals(const char *s, size_t m, const char *line) {
242 size_t l;
243
244 l = strlen(line);
245 if (l != m)
246 return false;
247
248 return memcmp(s, line, l) == 0;
249}
250
251static bool line_begins(const char *s, size_t m, const char *word) {
252 size_t l;
253
254 l = strlen(word);
255 if (m < l)
256 return false;
257
258 if (memcmp(s, word, l) != 0)
259 return false;
260
261 return m == l || (m > l && s[l] == ' ');
262}
263
264static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
265 _cleanup_free_ char *token = NULL;
266
267 if (!b->anonymous_auth)
268 return 0;
269
270 if (l <= 0)
271 return 1;
272
273 assert(p[0] == ' ');
274 p++; l--;
275
276 if (l % 2 != 0)
277 return 0;
278 token = unhexmem(p, l);
279 if (!token)
280 return -ENOMEM;
281
282 if (memchr(token, 0, l/2))
283 return 0;
284
285 return !!utf8_is_valid(token);
286}
287
288static int verify_external_token(sd_bus *b, const char *p, size_t l) {
289 _cleanup_free_ char *token = NULL;
290 uid_t u;
291 int r;
292
293 /* We don't do any real authentication here. Instead, we if
294 * the owner of this bus wanted authentication he should have
295 * checked SO_PEERCRED before even creating the bus object. */
296
8411d2a2 297 if (!b->anonymous_auth && !b->ucred_valid)
2181a7f5
LP
298 return 0;
299
300 if (l <= 0)
301 return 1;
302
303 assert(p[0] == ' ');
304 p++; l--;
305
306 if (l % 2 != 0)
307 return 0;
308
309 token = unhexmem(p, l);
310 if (!token)
311 return -ENOMEM;
312
313 if (memchr(token, 0, l/2))
314 return 0;
315
316 r = parse_uid(token, &u);
317 if (r < 0)
318 return 0;
319
8411d2a2
LP
320 /* We ignore the passed value if anonymous authentication is
321 * on anyway. */
322 if (!b->anonymous_auth && u != b->ucred.uid)
2181a7f5
LP
323 return 0;
324
325 return 1;
326}
327
328static int bus_socket_auth_write(sd_bus *b, const char *t) {
329 char *p;
330 size_t l;
331
332 assert(b);
333 assert(t);
334
335 /* We only make use of the first iovec */
336 assert(b->auth_index == 0 || b->auth_index == 1);
337
338 l = strlen(t);
339 p = malloc(b->auth_iovec[0].iov_len + l);
340 if (!p)
341 return -ENOMEM;
342
343 memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
344 memcpy(p + b->auth_iovec[0].iov_len, t, l);
345
346 b->auth_iovec[0].iov_base = p;
347 b->auth_iovec[0].iov_len += l;
348
349 free(b->auth_buffer);
350 b->auth_buffer = p;
351 b->auth_index = 0;
352 return 0;
353}
354
355static int bus_socket_auth_write_ok(sd_bus *b) {
356 char t[3 + 32 + 2 + 1];
357
358 assert(b);
359
98178d39 360 snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
361 char_array_0(t);
362
363 return bus_socket_auth_write(b, t);
364}
365
366static int bus_socket_auth_verify_server(sd_bus *b) {
367 char *e;
368 const char *line;
369 size_t l;
370 bool processed = false;
371 int r;
372
373 assert(b);
374
2b4ac889 375 if (b->rbuffer_size < 1)
2181a7f5
LP
376 return 0;
377
378 /* First char must be a NUL byte */
379 if (*(char*) b->rbuffer != 0)
380 return -EIO;
381
2b4ac889
LP
382 if (b->rbuffer_size < 3)
383 return 0;
384
2181a7f5
LP
385 /* Begin with the first line */
386 if (b->auth_rbegin <= 0)
387 b->auth_rbegin = 1;
388
389 for (;;) {
390 /* Check if line is complete */
391 line = (char*) b->rbuffer + b->auth_rbegin;
392 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
393 if (!e)
394 return processed;
395
396 l = e - line;
397
398 if (line_begins(line, l, "AUTH ANONYMOUS")) {
399
400 r = verify_anonymous_token(b, line + 14, l - 14);
401 if (r < 0)
402 return r;
403 if (r == 0)
404 r = bus_socket_auth_write(b, "REJECTED\r\n");
405 else {
406 b->auth = BUS_AUTH_ANONYMOUS;
407 r = bus_socket_auth_write_ok(b);
408 }
409
410 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
411
412 r = verify_external_token(b, line + 13, l - 13);
413 if (r < 0)
414 return r;
415 if (r == 0)
416 r = bus_socket_auth_write(b, "REJECTED\r\n");
417 else {
418 b->auth = BUS_AUTH_EXTERNAL;
419 r = bus_socket_auth_write_ok(b);
420 }
421
422 } else if (line_begins(line, l, "AUTH"))
423 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
424 else if (line_equals(line, l, "CANCEL") ||
425 line_begins(line, l, "ERROR")) {
426
427 b->auth = _BUS_AUTH_INVALID;
428 r = bus_socket_auth_write(b, "REJECTED\r\n");
429
430 } else if (line_equals(line, l, "BEGIN")) {
431
432 if (b->auth == _BUS_AUTH_INVALID)
433 r = bus_socket_auth_write(b, "ERROR\r\n");
434 else {
435 /* We can't leave from the auth phase
436 * before we haven't written
437 * everything queued, so let's check
438 * that */
439
440 if (bus_socket_auth_needs_write(b))
441 return 1;
442
443 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
444 memmove(b->rbuffer, e + 2, b->rbuffer_size);
445 return bus_start_running(b);
446 }
447
448 } else if (line_begins(line, l, "DATA")) {
449
450 if (b->auth == _BUS_AUTH_INVALID)
451 r = bus_socket_auth_write(b, "ERROR\r\n");
452 else {
453 if (b->auth == BUS_AUTH_ANONYMOUS)
454 r = verify_anonymous_token(b, line + 4, l - 4);
455 else
456 r = verify_external_token(b, line + 4, l - 4);
457
458 if (r < 0)
459 return r;
460 if (r == 0) {
461 b->auth = _BUS_AUTH_INVALID;
462 r = bus_socket_auth_write(b, "REJECTED\r\n");
463 } else
464 r = bus_socket_auth_write_ok(b);
465 }
466 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
264ad849 467 if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
2181a7f5
LP
468 r = bus_socket_auth_write(b, "ERROR\r\n");
469 else {
470 b->can_fds = true;
471 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
472 }
473 } else
474 r = bus_socket_auth_write(b, "ERROR\r\n");
475
476 if (r < 0)
477 return r;
478
479 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
480
481 processed = true;
482 }
483}
484
485static int bus_socket_auth_verify(sd_bus *b) {
486 assert(b);
487
488 if (b->is_server)
489 return bus_socket_auth_verify_server(b);
490 else
491 return bus_socket_auth_verify_client(b);
492}
493
a7e3212d
LP
494static int bus_socket_read_auth(sd_bus *b) {
495 struct msghdr mh;
496 struct iovec iov;
497 size_t n;
498 ssize_t k;
499 int r;
500 void *p;
2181a7f5
LP
501 union {
502 struct cmsghdr cmsghdr;
503 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
504 CMSG_SPACE(sizeof(struct ucred)) +
505 CMSG_SPACE(NAME_MAX)]; /*selinux label */
506 } control;
507 struct cmsghdr *cmsg;
15d5af81 508 bool handle_cmsg = false;
a7e3212d
LP
509
510 assert(b);
2181a7f5 511 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
512
513 r = bus_socket_auth_verify(b);
514 if (r != 0)
515 return r;
516
9607d947 517 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
518
519 if (n > BUS_AUTH_SIZE_MAX)
520 n = BUS_AUTH_SIZE_MAX;
521
522 if (b->rbuffer_size >= n)
523 return -ENOBUFS;
524
525 p = realloc(b->rbuffer, n);
526 if (!p)
527 return -ENOMEM;
528
529 b->rbuffer = p;
530
531 zero(iov);
532 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
533 iov.iov_len = n - b->rbuffer_size;
534
15d5af81
LP
535 if (b->prefer_readv)
536 k = readv(b->input_fd, &iov, 1);
537 else {
538 zero(mh);
539 mh.msg_iov = &iov;
540 mh.msg_iovlen = 1;
541 mh.msg_control = &control;
542 mh.msg_controllen = sizeof(control);
543
544 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
545 if (k < 0 && errno == ENOTSOCK) {
546 b->prefer_readv = true;
547 k = readv(b->input_fd, &iov, 1);
548 } else
549 handle_cmsg = true;
550 }
a7e3212d
LP
551 if (k < 0)
552 return errno == EAGAIN ? 0 : -errno;
553 if (k == 0)
554 return -ECONNRESET;
555
556 b->rbuffer_size += k;
557
15d5af81
LP
558 if (handle_cmsg) {
559 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
560 if (cmsg->cmsg_level == SOL_SOCKET &&
561 cmsg->cmsg_type == SCM_RIGHTS) {
562 int j;
563
564 /* Whut? We received fds during the auth
565 * protocol? Somebody is playing games with
566 * us. Close them all, and fail */
567 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
568 close_many((int*) CMSG_DATA(cmsg), j);
569 return -EIO;
2181a7f5 570
15d5af81
LP
571 } else if (cmsg->cmsg_level == SOL_SOCKET &&
572 cmsg->cmsg_type == SCM_CREDENTIALS &&
573 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
2181a7f5 574
ea8f194f
LP
575 /* Ignore bogus data, which we might
576 * get on socketpair() sockets */
577 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
578 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
579 b->ucred_valid = true;
580 }
2181a7f5 581
15d5af81
LP
582 } else if (cmsg->cmsg_level == SOL_SOCKET &&
583 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 584
15d5af81 585 size_t l;
ea8f194f 586
15d5af81 587 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
588 if (l > 0) {
589 memcpy(&b->label, CMSG_DATA(cmsg), l);
590 b->label[l] = 0;
591 }
15d5af81 592 }
2181a7f5
LP
593 }
594 }
595
a7e3212d
LP
596 r = bus_socket_auth_verify(b);
597 if (r != 0)
598 return r;
599
600 return 1;
601}
602
a7893c6b 603int bus_socket_setup(sd_bus *b) {
0f4b73c8 604 int enable;
ea8f194f 605 socklen_t l;
a7e3212d
LP
606
607 assert(b);
608
d65ddaa4
LP
609 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
610 * socket, just in case. */
0f4b73c8 611 enable = !b->bus_client;
e82c9509 612 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
264ad849 613
d21a7bb1 614 enable = !b->bus_client && (b->attach_flags & KDBUS_ATTACH_SECLABEL);
e82c9509 615 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d
LP
616
617 /* Increase the buffers to a MB */
e82c9509
LP
618 fd_inc_rcvbuf(b->input_fd, 1024*1024);
619 fd_inc_sndbuf(b->output_fd, 1024*1024);
a7e3212d 620
ea8f194f
LP
621 /* Get the peer for socketpair() sockets */
622 l = sizeof(b->ucred);
623 if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
624 b->ucred_valid = b->ucred.pid > 0;
625
a7e3212d
LP
626 return 0;
627}
628
2181a7f5 629static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 630 size_t l;
2181a7f5 631 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
632
633 assert(b);
634
2181a7f5
LP
635 if (b->anonymous_auth) {
636 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 637
2181a7f5
LP
638 /* For ANONYMOUS auth we send some arbitrary "trace" string */
639 l = 9;
640 b->auth_buffer = hexmem("anonymous", l);
641 } else {
642 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 643
2181a7f5 644 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 645
2181a7f5
LP
646 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
647 char_array_0(text);
a7e3212d 648
2181a7f5
LP
649 l = strlen(text);
650 b->auth_buffer = hexmem(text, l);
651 }
652
653 if (!b->auth_buffer)
a7e3212d
LP
654 return -ENOMEM;
655
264ad849 656 if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2181a7f5
LP
657 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
658 else
659 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
660
661 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
662 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
663 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
664 b->auth_iovec[1].iov_len = l * 2;
665 b->auth_iovec[2].iov_base = (void*) auth_suffix;
666 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
667
668 return bus_socket_write_auth(b);
669}
670
a7893c6b 671int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
672 assert(b);
673
674 b->state = BUS_AUTHENTICATING;
675 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
676
9ab32f9d 677 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
264ad849 678 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
2181a7f5 679
9ab32f9d
LP
680 if (b->output_fd != b->input_fd)
681 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
264ad849 682 b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
e82c9509 683
2181a7f5
LP
684 if (b->is_server)
685 return bus_socket_read_auth(b);
686 else
687 return bus_socket_start_auth_client(b);
688}
689
a7e3212d
LP
690int bus_socket_connect(sd_bus *b) {
691 int r;
692
693 assert(b);
e82c9509
LP
694 assert(b->input_fd < 0);
695 assert(b->output_fd < 0);
a7e3212d
LP
696 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
697
e82c9509
LP
698 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
699 if (b->input_fd < 0)
a7e3212d
LP
700 return -errno;
701
e82c9509
LP
702 b->output_fd = b->input_fd;
703
a7e3212d
LP
704 r = bus_socket_setup(b);
705 if (r < 0)
706 return r;
707
e82c9509 708 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
709 if (r < 0) {
710 if (errno == EINPROGRESS)
711 return 1;
712
713 return -errno;
714 }
715
716 return bus_socket_start_auth(b);
717}
718
719int bus_socket_exec(sd_bus *b) {
e82c9509 720 int s[2], r;
a7e3212d
LP
721 pid_t pid;
722
723 assert(b);
e82c9509
LP
724 assert(b->input_fd < 0);
725 assert(b->output_fd < 0);
a7e3212d
LP
726 assert(b->exec_path);
727
e82c9509
LP
728 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
729 if (r < 0)
a7e3212d
LP
730 return -errno;
731
732 pid = fork();
733 if (pid < 0) {
734 close_pipe(s);
735 return -errno;
736 }
737 if (pid == 0) {
738 /* Child */
739
e82c9509
LP
740 reset_all_signal_handlers();
741
742 close_all_fds(s+1, 1);
a7e3212d
LP
743
744 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
745 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
746
747 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
748 close_nointr_nofail(s[1]);
749
750 fd_cloexec(STDIN_FILENO, false);
751 fd_cloexec(STDOUT_FILENO, false);
752 fd_nonblock(STDIN_FILENO, false);
753 fd_nonblock(STDOUT_FILENO, false);
754
755 if (b->exec_argv)
756 execvp(b->exec_path, b->exec_argv);
757 else {
758 const char *argv[] = { b->exec_path, NULL };
759 execvp(b->exec_path, (char**) argv);
760 }
761
762 _exit(EXIT_FAILURE);
763 }
764
765 close_nointr_nofail(s[1]);
e82c9509 766 b->output_fd = b->input_fd = s[0];
a7e3212d
LP
767
768 return bus_socket_start_auth(b);
769}
770
771int bus_socket_take_fd(sd_bus *b) {
772 int r;
773 assert(b);
774
775 r = bus_socket_setup(b);
776 if (r < 0)
777 return r;
778
779 return bus_socket_start_auth(b);
780}
781
782int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
783 struct iovec *iov;
784 ssize_t k;
785 size_t n;
786 unsigned j;
bc7fd8cd 787 int r;
a7e3212d
LP
788
789 assert(bus);
790 assert(m);
791 assert(idx);
792 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
793
6629161f 794 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 795 return 0;
a7e3212d 796
bc7fd8cd
LP
797 r = bus_message_setup_iovec(m);
798 if (r < 0)
799 return r;
2100fa10 800
a7e3212d
LP
801 n = m->n_iovec * sizeof(struct iovec);
802 iov = alloca(n);
803 memcpy(iov, m->iovec, n);
804
805 j = 0;
806 iovec_advance(iov, &j, *idx);
807
15d5af81
LP
808 if (bus->prefer_writev)
809 k = writev(bus->output_fd, iov, m->n_iovec);
810 else {
811 struct msghdr mh;
812 zero(mh);
813
814 if (m->n_fds > 0) {
815 struct cmsghdr *control;
816 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
817
818 mh.msg_control = control;
819 control->cmsg_level = SOL_SOCKET;
820 control->cmsg_type = SCM_RIGHTS;
821 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
822 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
823 }
824
825 mh.msg_iov = iov;
826 mh.msg_iovlen = m->n_iovec;
827
828 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
829 if (k < 0 && errno == ENOTSOCK) {
830 bus->prefer_writev = true;
831 k = writev(bus->output_fd, iov, m->n_iovec);
832 }
833 }
a7e3212d 834
a7e3212d
LP
835 if (k < 0)
836 return errno == EAGAIN ? 0 : -errno;
837
838 *idx += (size_t) k;
839 return 1;
840}
841
842static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
843 uint32_t a, b;
844 uint8_t e;
845 uint64_t sum;
846
847 assert(bus);
848 assert(need);
849 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
850
851 if (bus->rbuffer_size < sizeof(struct bus_header)) {
852 *need = sizeof(struct bus_header) + 8;
853
854 /* Minimum message size:
855 *
856 * Header +
857 *
858 * Method Call: +2 string headers
859 * Signal: +3 string headers
860 * Method Error: +1 string headers
861 * +1 uint32 headers
862 * Method Reply: +1 uint32 headers
863 *
864 * A string header is at least 9 bytes
865 * A uint32 header is at least 8 bytes
866 *
867 * Hence the minimum message size of a valid message
868 * is header + 8 bytes */
869
870 return 0;
871 }
872
873 a = ((const uint32_t*) bus->rbuffer)[1];
874 b = ((const uint32_t*) bus->rbuffer)[3];
875
876 e = ((const uint8_t*) bus->rbuffer)[0];
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,
0f4b73c8
LP
918 bus->ucred_valid ? &bus->ucred : NULL,
919 bus->label[0] ? bus->label : 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}