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