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