]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: add macro for iterating through body parts of a message
[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
bc7fd8cd
LP
86 n = 1 + !!m->fields + m->n_body_parts;
87 if (n < ELEMENTSOF(m->iovec_fixed))
88 m->iovec = m->iovec_fixed;
89 else {
90 m->iovec = new(struct iovec, n);
91 if (!m->iovec)
92 return -ENOMEM;
93 }
2100fa10 94
bc7fd8cd
LP
95 r = append_iovec(m, m->header, sizeof(*m->header));
96 if (r < 0)
97 return r;
2100fa10 98
bc7fd8cd
LP
99 if (m->fields) {
100 r = append_iovec(m, m->fields, ALIGN8(m->header->fields_size));
101 if (r < 0)
102 return r;
103 }
104
9b29bb68 105 MESSAGE_FOREACH_PART(part, i, m) {
bc7fd8cd
LP
106 r = append_iovec(m, part->data, part->size);
107 if (r < 0)
108 return r;
109 }
110
111 assert(n == m->n_iovec);
112
113 return 0;
2100fa10
LP
114}
115
2181a7f5
LP
116bool bus_socket_auth_needs_write(sd_bus *b) {
117
118 unsigned i;
119
120 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
121 return false;
122
123 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
124 struct iovec *j = b->auth_iovec + i;
125
126 if (j->iov_len > 0)
127 return true;
128 }
129
130 return false;
131}
132
a7e3212d 133static int bus_socket_write_auth(sd_bus *b) {
a7e3212d
LP
134 ssize_t k;
135
136 assert(b);
137 assert(b->state == BUS_AUTHENTICATING);
138
2181a7f5 139 if (!bus_socket_auth_needs_write(b))
a7e3212d
LP
140 return 0;
141
15d5af81
LP
142 if (b->prefer_writev)
143 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
144 else {
145 struct msghdr mh;
146 zero(mh);
147
148 mh.msg_iov = b->auth_iovec + b->auth_index;
149 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
150
151 k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
152 if (k < 0 && errno == ENOTSOCK) {
153 b->prefer_writev = true;
154 k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
155 }
156 }
a7e3212d 157
a7e3212d
LP
158 if (k < 0)
159 return errno == EAGAIN ? 0 : -errno;
160
161 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
a7e3212d
LP
162 return 1;
163}
164
2181a7f5 165static int bus_socket_auth_verify_client(sd_bus *b) {
a7e3212d
LP
166 char *e, *f, *start;
167 sd_id128_t peer;
168 unsigned i;
169 int r;
170
2181a7f5
LP
171 assert(b);
172
a7e3212d
LP
173 /* We expect two response lines: "OK" and possibly
174 * "AGREE_UNIX_FD" */
175
176 e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2);
177 if (!e)
178 return 0;
179
180 if (b->negotiate_fds) {
181 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
182 if (!f)
183 return 0;
184
185 start = f + 2;
186 } else {
187 f = NULL;
188 start = e + 2;
189 }
190
191 /* Nice! We got all the lines we need. First check the OK
192 * line */
193
194 if (e - (char*) b->rbuffer != 3 + 32)
195 return -EPERM;
196
197 if (memcmp(b->rbuffer, "OK ", 3))
198 return -EPERM;
199
2181a7f5
LP
200 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
201
a7e3212d
LP
202 for (i = 0; i < 32; i += 2) {
203 int x, y;
204
205 x = unhexchar(((char*) b->rbuffer)[3 + i]);
206 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
207
208 if (x < 0 || y < 0)
209 return -EINVAL;
210
211 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
212 }
213
98178d39
LP
214 if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
215 !sd_id128_equal(b->server_id, peer))
a7e3212d
LP
216 return -EPERM;
217
98178d39 218 b->server_id = peer;
a7e3212d
LP
219
220 /* And possibly check the second line, too */
221
222 if (f)
223 b->can_fds =
224 (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
225 memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
226
227 b->rbuffer_size -= (start - (char*) b->rbuffer);
228 memmove(b->rbuffer, start, b->rbuffer_size);
229
230 r = bus_start_running(b);
231 if (r < 0)
232 return r;
233
234 return 1;
235}
236
2181a7f5
LP
237static bool line_equals(const char *s, size_t m, const char *line) {
238 size_t l;
239
240 l = strlen(line);
241 if (l != m)
242 return false;
243
244 return memcmp(s, line, l) == 0;
245}
246
247static bool line_begins(const char *s, size_t m, const char *word) {
248 size_t l;
249
250 l = strlen(word);
251 if (m < l)
252 return false;
253
254 if (memcmp(s, word, l) != 0)
255 return false;
256
257 return m == l || (m > l && s[l] == ' ');
258}
259
260static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
261 _cleanup_free_ char *token = NULL;
262
263 if (!b->anonymous_auth)
264 return 0;
265
266 if (l <= 0)
267 return 1;
268
269 assert(p[0] == ' ');
270 p++; l--;
271
272 if (l % 2 != 0)
273 return 0;
274 token = unhexmem(p, l);
275 if (!token)
276 return -ENOMEM;
277
278 if (memchr(token, 0, l/2))
279 return 0;
280
281 return !!utf8_is_valid(token);
282}
283
284static int verify_external_token(sd_bus *b, const char *p, size_t l) {
285 _cleanup_free_ char *token = NULL;
286 uid_t u;
287 int r;
288
289 /* We don't do any real authentication here. Instead, we if
290 * the owner of this bus wanted authentication he should have
291 * checked SO_PEERCRED before even creating the bus object. */
292
8411d2a2 293 if (!b->anonymous_auth && !b->ucred_valid)
2181a7f5
LP
294 return 0;
295
296 if (l <= 0)
297 return 1;
298
299 assert(p[0] == ' ');
300 p++; l--;
301
302 if (l % 2 != 0)
303 return 0;
304
305 token = unhexmem(p, l);
306 if (!token)
307 return -ENOMEM;
308
309 if (memchr(token, 0, l/2))
310 return 0;
311
312 r = parse_uid(token, &u);
313 if (r < 0)
314 return 0;
315
8411d2a2
LP
316 /* We ignore the passed value if anonymous authentication is
317 * on anyway. */
318 if (!b->anonymous_auth && u != b->ucred.uid)
2181a7f5
LP
319 return 0;
320
321 return 1;
322}
323
324static int bus_socket_auth_write(sd_bus *b, const char *t) {
325 char *p;
326 size_t l;
327
328 assert(b);
329 assert(t);
330
331 /* We only make use of the first iovec */
332 assert(b->auth_index == 0 || b->auth_index == 1);
333
334 l = strlen(t);
335 p = malloc(b->auth_iovec[0].iov_len + l);
336 if (!p)
337 return -ENOMEM;
338
339 memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
340 memcpy(p + b->auth_iovec[0].iov_len, t, l);
341
342 b->auth_iovec[0].iov_base = p;
343 b->auth_iovec[0].iov_len += l;
344
345 free(b->auth_buffer);
346 b->auth_buffer = p;
347 b->auth_index = 0;
348 return 0;
349}
350
351static int bus_socket_auth_write_ok(sd_bus *b) {
352 char t[3 + 32 + 2 + 1];
353
354 assert(b);
355
98178d39 356 snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
357 char_array_0(t);
358
359 return bus_socket_auth_write(b, t);
360}
361
362static int bus_socket_auth_verify_server(sd_bus *b) {
363 char *e;
364 const char *line;
365 size_t l;
366 bool processed = false;
367 int r;
368
369 assert(b);
370
2b4ac889 371 if (b->rbuffer_size < 1)
2181a7f5
LP
372 return 0;
373
374 /* First char must be a NUL byte */
375 if (*(char*) b->rbuffer != 0)
376 return -EIO;
377
2b4ac889
LP
378 if (b->rbuffer_size < 3)
379 return 0;
380
2181a7f5
LP
381 /* Begin with the first line */
382 if (b->auth_rbegin <= 0)
383 b->auth_rbegin = 1;
384
385 for (;;) {
386 /* Check if line is complete */
387 line = (char*) b->rbuffer + b->auth_rbegin;
388 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
389 if (!e)
390 return processed;
391
392 l = e - line;
393
394 if (line_begins(line, l, "AUTH ANONYMOUS")) {
395
396 r = verify_anonymous_token(b, line + 14, l - 14);
397 if (r < 0)
398 return r;
399 if (r == 0)
400 r = bus_socket_auth_write(b, "REJECTED\r\n");
401 else {
402 b->auth = BUS_AUTH_ANONYMOUS;
403 r = bus_socket_auth_write_ok(b);
404 }
405
406 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
407
408 r = verify_external_token(b, line + 13, l - 13);
409 if (r < 0)
410 return r;
411 if (r == 0)
412 r = bus_socket_auth_write(b, "REJECTED\r\n");
413 else {
414 b->auth = BUS_AUTH_EXTERNAL;
415 r = bus_socket_auth_write_ok(b);
416 }
417
418 } else if (line_begins(line, l, "AUTH"))
419 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
420 else if (line_equals(line, l, "CANCEL") ||
421 line_begins(line, l, "ERROR")) {
422
423 b->auth = _BUS_AUTH_INVALID;
424 r = bus_socket_auth_write(b, "REJECTED\r\n");
425
426 } else if (line_equals(line, l, "BEGIN")) {
427
428 if (b->auth == _BUS_AUTH_INVALID)
429 r = bus_socket_auth_write(b, "ERROR\r\n");
430 else {
431 /* We can't leave from the auth phase
432 * before we haven't written
433 * everything queued, so let's check
434 * that */
435
436 if (bus_socket_auth_needs_write(b))
437 return 1;
438
439 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
440 memmove(b->rbuffer, e + 2, b->rbuffer_size);
441 return bus_start_running(b);
442 }
443
444 } else if (line_begins(line, l, "DATA")) {
445
446 if (b->auth == _BUS_AUTH_INVALID)
447 r = bus_socket_auth_write(b, "ERROR\r\n");
448 else {
449 if (b->auth == BUS_AUTH_ANONYMOUS)
450 r = verify_anonymous_token(b, line + 4, l - 4);
451 else
452 r = verify_external_token(b, line + 4, l - 4);
453
454 if (r < 0)
455 return r;
456 if (r == 0) {
457 b->auth = _BUS_AUTH_INVALID;
458 r = bus_socket_auth_write(b, "REJECTED\r\n");
459 } else
460 r = bus_socket_auth_write_ok(b);
461 }
462 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
463 if (b->auth == _BUS_AUTH_INVALID || !b->negotiate_fds)
464 r = bus_socket_auth_write(b, "ERROR\r\n");
465 else {
466 b->can_fds = true;
467 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
468 }
469 } else
470 r = bus_socket_auth_write(b, "ERROR\r\n");
471
472 if (r < 0)
473 return r;
474
475 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
476
477 processed = true;
478 }
479}
480
481static int bus_socket_auth_verify(sd_bus *b) {
482 assert(b);
483
484 if (b->is_server)
485 return bus_socket_auth_verify_server(b);
486 else
487 return bus_socket_auth_verify_client(b);
488}
489
a7e3212d
LP
490static int bus_socket_read_auth(sd_bus *b) {
491 struct msghdr mh;
492 struct iovec iov;
493 size_t n;
494 ssize_t k;
495 int r;
496 void *p;
2181a7f5
LP
497 union {
498 struct cmsghdr cmsghdr;
499 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
500 CMSG_SPACE(sizeof(struct ucred)) +
501 CMSG_SPACE(NAME_MAX)]; /*selinux label */
502 } control;
503 struct cmsghdr *cmsg;
15d5af81 504 bool handle_cmsg = false;
a7e3212d
LP
505
506 assert(b);
2181a7f5 507 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
508
509 r = bus_socket_auth_verify(b);
510 if (r != 0)
511 return r;
512
9607d947 513 n = MAX(256u, b->rbuffer_size * 2);
a7e3212d
LP
514
515 if (n > BUS_AUTH_SIZE_MAX)
516 n = BUS_AUTH_SIZE_MAX;
517
518 if (b->rbuffer_size >= n)
519 return -ENOBUFS;
520
521 p = realloc(b->rbuffer, n);
522 if (!p)
523 return -ENOMEM;
524
525 b->rbuffer = p;
526
527 zero(iov);
528 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
529 iov.iov_len = n - b->rbuffer_size;
530
15d5af81
LP
531 if (b->prefer_readv)
532 k = readv(b->input_fd, &iov, 1);
533 else {
534 zero(mh);
535 mh.msg_iov = &iov;
536 mh.msg_iovlen = 1;
537 mh.msg_control = &control;
538 mh.msg_controllen = sizeof(control);
539
540 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
541 if (k < 0 && errno == ENOTSOCK) {
542 b->prefer_readv = true;
543 k = readv(b->input_fd, &iov, 1);
544 } else
545 handle_cmsg = true;
546 }
a7e3212d
LP
547 if (k < 0)
548 return errno == EAGAIN ? 0 : -errno;
549 if (k == 0)
550 return -ECONNRESET;
551
552 b->rbuffer_size += k;
553
15d5af81
LP
554 if (handle_cmsg) {
555 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
556 if (cmsg->cmsg_level == SOL_SOCKET &&
557 cmsg->cmsg_type == SCM_RIGHTS) {
558 int j;
559
560 /* Whut? We received fds during the auth
561 * protocol? Somebody is playing games with
562 * us. Close them all, and fail */
563 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
564 close_many((int*) CMSG_DATA(cmsg), j);
565 return -EIO;
2181a7f5 566
15d5af81
LP
567 } else if (cmsg->cmsg_level == SOL_SOCKET &&
568 cmsg->cmsg_type == SCM_CREDENTIALS &&
569 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
2181a7f5 570
ea8f194f
LP
571 /* Ignore bogus data, which we might
572 * get on socketpair() sockets */
573 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
574 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
575 b->ucred_valid = true;
576 }
2181a7f5 577
15d5af81
LP
578 } else if (cmsg->cmsg_level == SOL_SOCKET &&
579 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 580
15d5af81 581 size_t l;
ea8f194f 582
15d5af81 583 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
584 if (l > 0) {
585 memcpy(&b->label, CMSG_DATA(cmsg), l);
586 b->label[l] = 0;
587 }
15d5af81 588 }
2181a7f5
LP
589 }
590 }
591
a7e3212d
LP
592 r = bus_socket_auth_verify(b);
593 if (r != 0)
594 return r;
595
596 return 1;
597}
598
599static int bus_socket_setup(sd_bus *b) {
0f4b73c8 600 int enable;
ea8f194f 601 socklen_t l;
a7e3212d
LP
602
603 assert(b);
604
d65ddaa4
LP
605 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
606 * socket, just in case. */
0f4b73c8 607 enable = !b->bus_client;
e82c9509
LP
608 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
609 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d
LP
610
611 /* Increase the buffers to a MB */
e82c9509
LP
612 fd_inc_rcvbuf(b->input_fd, 1024*1024);
613 fd_inc_sndbuf(b->output_fd, 1024*1024);
a7e3212d 614
ea8f194f
LP
615 /* Get the peer for socketpair() sockets */
616 l = sizeof(b->ucred);
617 if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
618 b->ucred_valid = b->ucred.pid > 0;
619
a7e3212d
LP
620 return 0;
621}
622
2181a7f5 623static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 624 size_t l;
2181a7f5 625 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
626
627 assert(b);
628
2181a7f5
LP
629 if (b->anonymous_auth) {
630 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 631
2181a7f5
LP
632 /* For ANONYMOUS auth we send some arbitrary "trace" string */
633 l = 9;
634 b->auth_buffer = hexmem("anonymous", l);
635 } else {
636 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 637
2181a7f5 638 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 639
2181a7f5
LP
640 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
641 char_array_0(text);
a7e3212d 642
2181a7f5
LP
643 l = strlen(text);
644 b->auth_buffer = hexmem(text, l);
645 }
646
647 if (!b->auth_buffer)
a7e3212d
LP
648 return -ENOMEM;
649
2181a7f5
LP
650 if (b->negotiate_fds)
651 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
652 else
653 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
654
655 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
656 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
657 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
658 b->auth_iovec[1].iov_len = l * 2;
659 b->auth_iovec[2].iov_base = (void*) auth_suffix;
660 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
661
662 return bus_socket_write_auth(b);
663}
664
2181a7f5 665static int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
666 assert(b);
667
668 b->state = BUS_AUTHENTICATING;
669 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
670
9ab32f9d 671 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
2181a7f5
LP
672 b->negotiate_fds = false;
673
9ab32f9d
LP
674 if (b->output_fd != b->input_fd)
675 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
e82c9509 676 b->negotiate_fds = false;
e82c9509 677
2181a7f5
LP
678 if (b->is_server)
679 return bus_socket_read_auth(b);
680 else
681 return bus_socket_start_auth_client(b);
682}
683
a7e3212d
LP
684int bus_socket_connect(sd_bus *b) {
685 int r;
686
687 assert(b);
e82c9509
LP
688 assert(b->input_fd < 0);
689 assert(b->output_fd < 0);
a7e3212d
LP
690 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
691
e82c9509
LP
692 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
693 if (b->input_fd < 0)
a7e3212d
LP
694 return -errno;
695
e82c9509
LP
696 b->output_fd = b->input_fd;
697
a7e3212d
LP
698 r = bus_socket_setup(b);
699 if (r < 0)
700 return r;
701
e82c9509 702 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
703 if (r < 0) {
704 if (errno == EINPROGRESS)
705 return 1;
706
707 return -errno;
708 }
709
710 return bus_socket_start_auth(b);
711}
712
713int bus_socket_exec(sd_bus *b) {
e82c9509 714 int s[2], r;
a7e3212d
LP
715 pid_t pid;
716
717 assert(b);
e82c9509
LP
718 assert(b->input_fd < 0);
719 assert(b->output_fd < 0);
a7e3212d
LP
720 assert(b->exec_path);
721
e82c9509
LP
722 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
723 if (r < 0)
a7e3212d
LP
724 return -errno;
725
726 pid = fork();
727 if (pid < 0) {
728 close_pipe(s);
729 return -errno;
730 }
731 if (pid == 0) {
732 /* Child */
733
e82c9509
LP
734 reset_all_signal_handlers();
735
736 close_all_fds(s+1, 1);
a7e3212d
LP
737
738 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
739 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
740
741 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
742 close_nointr_nofail(s[1]);
743
744 fd_cloexec(STDIN_FILENO, false);
745 fd_cloexec(STDOUT_FILENO, false);
746 fd_nonblock(STDIN_FILENO, false);
747 fd_nonblock(STDOUT_FILENO, false);
748
749 if (b->exec_argv)
750 execvp(b->exec_path, b->exec_argv);
751 else {
752 const char *argv[] = { b->exec_path, NULL };
753 execvp(b->exec_path, (char**) argv);
754 }
755
756 _exit(EXIT_FAILURE);
757 }
758
759 close_nointr_nofail(s[1]);
e82c9509 760 b->output_fd = b->input_fd = s[0];
a7e3212d
LP
761
762 return bus_socket_start_auth(b);
763}
764
765int bus_socket_take_fd(sd_bus *b) {
766 int r;
767 assert(b);
768
769 r = bus_socket_setup(b);
770 if (r < 0)
771 return r;
772
773 return bus_socket_start_auth(b);
774}
775
776int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
777 struct iovec *iov;
778 ssize_t k;
779 size_t n;
780 unsigned j;
bc7fd8cd 781 int r;
a7e3212d
LP
782
783 assert(bus);
784 assert(m);
785 assert(idx);
786 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
787
6629161f 788 if (*idx >= BUS_MESSAGE_SIZE(m))
a7e3212d 789 return 0;
a7e3212d 790
bc7fd8cd
LP
791 r = bus_message_setup_iovec(m);
792 if (r < 0)
793 return r;
2100fa10 794
a7e3212d
LP
795 n = m->n_iovec * sizeof(struct iovec);
796 iov = alloca(n);
797 memcpy(iov, m->iovec, n);
798
799 j = 0;
800 iovec_advance(iov, &j, *idx);
801
15d5af81
LP
802 if (bus->prefer_writev)
803 k = writev(bus->output_fd, iov, m->n_iovec);
804 else {
805 struct msghdr mh;
806 zero(mh);
807
808 if (m->n_fds > 0) {
809 struct cmsghdr *control;
810 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
811
812 mh.msg_control = control;
813 control->cmsg_level = SOL_SOCKET;
814 control->cmsg_type = SCM_RIGHTS;
815 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
816 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
817 }
818
819 mh.msg_iov = iov;
820 mh.msg_iovlen = m->n_iovec;
821
822 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
823 if (k < 0 && errno == ENOTSOCK) {
824 bus->prefer_writev = true;
825 k = writev(bus->output_fd, iov, m->n_iovec);
826 }
827 }
a7e3212d 828
a7e3212d
LP
829 if (k < 0)
830 return errno == EAGAIN ? 0 : -errno;
831
832 *idx += (size_t) k;
833 return 1;
834}
835
836static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
837 uint32_t a, b;
838 uint8_t e;
839 uint64_t sum;
840
841 assert(bus);
842 assert(need);
843 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
844
845 if (bus->rbuffer_size < sizeof(struct bus_header)) {
846 *need = sizeof(struct bus_header) + 8;
847
848 /* Minimum message size:
849 *
850 * Header +
851 *
852 * Method Call: +2 string headers
853 * Signal: +3 string headers
854 * Method Error: +1 string headers
855 * +1 uint32 headers
856 * Method Reply: +1 uint32 headers
857 *
858 * A string header is at least 9 bytes
859 * A uint32 header is at least 8 bytes
860 *
861 * Hence the minimum message size of a valid message
862 * is header + 8 bytes */
863
864 return 0;
865 }
866
867 a = ((const uint32_t*) bus->rbuffer)[1];
868 b = ((const uint32_t*) bus->rbuffer)[3];
869
870 e = ((const uint8_t*) bus->rbuffer)[0];
871 if (e == SD_BUS_LITTLE_ENDIAN) {
872 a = le32toh(a);
873 b = le32toh(b);
874 } else if (e == SD_BUS_BIG_ENDIAN) {
875 a = be32toh(a);
876 b = be32toh(b);
877 } else
878 return -EBADMSG;
879
880 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
881 if (sum >= BUS_MESSAGE_SIZE_MAX)
882 return -ENOBUFS;
883
884 *need = (size_t) sum;
885 return 0;
886}
887
888static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) {
889 sd_bus_message *t;
890 void *b;
891 int r;
892
893 assert(bus);
894 assert(m);
895 assert(bus->rbuffer_size >= size);
896 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
897
898 if (bus->rbuffer_size > size) {
899 b = memdup((const uint8_t*) bus->rbuffer + size,
900 bus->rbuffer_size - size);
901 if (!b)
902 return -ENOMEM;
903 } else
904 b = NULL;
905
906 r = bus_message_from_malloc(bus->rbuffer, size,
907 bus->fds, bus->n_fds,
0f4b73c8
LP
908 bus->ucred_valid ? &bus->ucred : NULL,
909 bus->label[0] ? bus->label : NULL,
a7e3212d
LP
910 &t);
911 if (r < 0) {
912 free(b);
913 return r;
914 }
915
916 bus->rbuffer = b;
917 bus->rbuffer_size -= size;
918
919 bus->fds = NULL;
920 bus->n_fds = 0;
921
922 *m = t;
923 return 1;
924}
925
926int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
927 struct msghdr mh;
928 struct iovec iov;
929 ssize_t k;
930 size_t need;
931 int r;
932 void *b;
933 union {
934 struct cmsghdr cmsghdr;
935 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
936 CMSG_SPACE(sizeof(struct ucred)) +
937 CMSG_SPACE(NAME_MAX)]; /*selinux label */
938 } control;
939 struct cmsghdr *cmsg;
4d3a5b10 940 bool handle_cmsg = false;
a7e3212d
LP
941
942 assert(bus);
943 assert(m);
944 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
945
946 r = bus_socket_read_message_need(bus, &need);
947 if (r < 0)
948 return r;
949
950 if (bus->rbuffer_size >= need)
951 return bus_socket_make_message(bus, need, m);
952
953 b = realloc(bus->rbuffer, need);
954 if (!b)
955 return -ENOMEM;
956
957 bus->rbuffer = b;
958
959 zero(iov);
960 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
961 iov.iov_len = need - bus->rbuffer_size;
962
15d5af81
LP
963 if (bus->prefer_readv)
964 k = readv(bus->input_fd, &iov, 1);
965 else {
966 zero(mh);
967 mh.msg_iov = &iov;
968 mh.msg_iovlen = 1;
969 mh.msg_control = &control;
970 mh.msg_controllen = sizeof(control);
971
972 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
973 if (k < 0 && errno == ENOTSOCK) {
974 bus->prefer_readv = true;
975 k = readv(bus->input_fd, &iov, 1);
976 } else
977 handle_cmsg = true;
978 }
a7e3212d
LP
979 if (k < 0)
980 return errno == EAGAIN ? 0 : -errno;
981 if (k == 0)
982 return -ECONNRESET;
983
984 bus->rbuffer_size += k;
985
15d5af81
LP
986 if (handle_cmsg) {
987 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
988 if (cmsg->cmsg_level == SOL_SOCKET &&
989 cmsg->cmsg_type == SCM_RIGHTS) {
990 int n, *f;
991
992 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
993
994 if (!bus->can_fds) {
995 /* Whut? We received fds but this
996 * isn't actually enabled? Close them,
997 * and fail */
998
999 close_many((int*) CMSG_DATA(cmsg), n);
1000 return -EIO;
1001 }
1002
1003 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
1004 if (!f) {
1005 close_many((int*) CMSG_DATA(cmsg), n);
1006 return -ENOMEM;
1007 }
1008
1009 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
1010 bus->fds = f;
1011 bus->n_fds += n;
1012 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1013 cmsg->cmsg_type == SCM_CREDENTIALS &&
1014 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1015
ea8f194f
LP
1016 /* Ignore bogus data, which we might
1017 * get on socketpair() sockets */
1018 if (((struct ucred*) CMSG_DATA(cmsg))->pid != 0) {
1019 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
1020 bus->ucred_valid = true;
1021 }
15d5af81
LP
1022
1023 } else if (cmsg->cmsg_level == SOL_SOCKET &&
1024 cmsg->cmsg_type == SCM_SECURITY) {
1025
1026 size_t l;
1027 l = cmsg->cmsg_len - CMSG_LEN(0);
ea8f194f
LP
1028 if (l > 0) {
1029 memcpy(&bus->label, CMSG_DATA(cmsg), l);
1030 bus->label[l] = 0;
1031 }
a7e3212d 1032 }
a7e3212d
LP
1033 }
1034 }
1035
1036 r = bus_socket_read_message_need(bus, &need);
1037 if (r < 0)
1038 return r;
1039
1040 if (bus->rbuffer_size >= need)
1041 return bus_socket_make_message(bus, need, m);
1042
1043 return 1;
1044}
1045
1046int bus_socket_process_opening(sd_bus *b) {
1047 int error = 0;
1048 socklen_t slen = sizeof(error);
b92bea5d
ZJS
1049 struct pollfd p = {
1050 .fd = b->output_fd,
1051 .events = POLLOUT,
1052 };
a7e3212d
LP
1053 int r;
1054
a7e3212d
LP
1055 assert(b->state == BUS_OPENING);
1056
a7e3212d
LP
1057 r = poll(&p, 1, 0);
1058 if (r < 0)
1059 return -errno;
1060
1061 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
1062 return 0;
1063
e82c9509 1064 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
1065 if (r < 0)
1066 b->last_connect_error = errno;
1067 else if (error != 0)
1068 b->last_connect_error = error;
1069 else if (p.revents & (POLLERR|POLLHUP))
1070 b->last_connect_error = ECONNREFUSED;
1071 else
1072 return bus_socket_start_auth(b);
1073
1074 return bus_next_address(b);
1075}
1076
1077int bus_socket_process_authenticating(sd_bus *b) {
1078 int r;
1079
1080 assert(b);
1081 assert(b->state == BUS_AUTHENTICATING);
1082
1083 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1084 return -ETIMEDOUT;
1085
1086 r = bus_socket_write_auth(b);
1087 if (r != 0)
1088 return r;
1089
1090 return bus_socket_read_auth(b);
1091}