]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: when the first char a server receives isn't the NUL byte immediately fail
[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
2181a7f5 458 n = MAX(256, 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
15d5af81
LP
516 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
517 b->ucred_valid = true;
2181a7f5 518
15d5af81
LP
519 } else if (cmsg->cmsg_level == SOL_SOCKET &&
520 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 521
15d5af81
LP
522 size_t l;
523 l = cmsg->cmsg_len - CMSG_LEN(0);
524 memcpy(&b->label, CMSG_DATA(cmsg), l);
525 b->label[l] = 0;
526 }
2181a7f5
LP
527 }
528 }
529
a7e3212d
LP
530 r = bus_socket_auth_verify(b);
531 if (r != 0)
532 return r;
533
534 return 1;
535}
536
537static int bus_socket_setup(sd_bus *b) {
0f4b73c8 538 int enable;
a7e3212d
LP
539
540 assert(b);
541
d65ddaa4
LP
542 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
543 * socket, just in case. */
0f4b73c8 544 enable = !b->bus_client;
e82c9509
LP
545 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
546 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d
LP
547
548 /* Increase the buffers to a MB */
e82c9509
LP
549 fd_inc_rcvbuf(b->input_fd, 1024*1024);
550 fd_inc_sndbuf(b->output_fd, 1024*1024);
a7e3212d
LP
551
552 return 0;
553}
554
2181a7f5 555static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 556 size_t l;
2181a7f5 557 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
558
559 assert(b);
560
2181a7f5
LP
561 if (b->anonymous_auth) {
562 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 563
2181a7f5
LP
564 /* For ANONYMOUS auth we send some arbitrary "trace" string */
565 l = 9;
566 b->auth_buffer = hexmem("anonymous", l);
567 } else {
568 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 569
2181a7f5 570 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 571
2181a7f5
LP
572 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
573 char_array_0(text);
a7e3212d 574
2181a7f5
LP
575 l = strlen(text);
576 b->auth_buffer = hexmem(text, l);
577 }
578
579 if (!b->auth_buffer)
a7e3212d
LP
580 return -ENOMEM;
581
2181a7f5
LP
582 if (b->negotiate_fds)
583 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
584 else
585 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
586
587 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
588 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
589 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
590 b->auth_iovec[1].iov_len = l * 2;
591 b->auth_iovec[2].iov_base = (void*) auth_suffix;
592 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
593
594 return bus_socket_write_auth(b);
595}
596
2181a7f5 597static int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
598 assert(b);
599
600 b->state = BUS_AUTHENTICATING;
601 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
602
9ab32f9d 603 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
2181a7f5
LP
604 b->negotiate_fds = false;
605
9ab32f9d
LP
606 if (b->output_fd != b->input_fd)
607 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
e82c9509 608 b->negotiate_fds = false;
e82c9509 609
2181a7f5
LP
610 if (b->is_server)
611 return bus_socket_read_auth(b);
612 else
613 return bus_socket_start_auth_client(b);
614}
615
a7e3212d
LP
616int bus_socket_connect(sd_bus *b) {
617 int r;
618
619 assert(b);
e82c9509
LP
620 assert(b->input_fd < 0);
621 assert(b->output_fd < 0);
a7e3212d
LP
622 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
623
e82c9509
LP
624 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
625 if (b->input_fd < 0)
a7e3212d
LP
626 return -errno;
627
e82c9509
LP
628 b->output_fd = b->input_fd;
629
a7e3212d
LP
630 r = bus_socket_setup(b);
631 if (r < 0)
632 return r;
633
e82c9509 634 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
635 if (r < 0) {
636 if (errno == EINPROGRESS)
637 return 1;
638
639 return -errno;
640 }
641
642 return bus_socket_start_auth(b);
643}
644
645int bus_socket_exec(sd_bus *b) {
e82c9509 646 int s[2], r;
a7e3212d
LP
647 pid_t pid;
648
649 assert(b);
e82c9509
LP
650 assert(b->input_fd < 0);
651 assert(b->output_fd < 0);
a7e3212d
LP
652 assert(b->exec_path);
653
e82c9509
LP
654 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
655 if (r < 0)
a7e3212d
LP
656 return -errno;
657
658 pid = fork();
659 if (pid < 0) {
660 close_pipe(s);
661 return -errno;
662 }
663 if (pid == 0) {
664 /* Child */
665
e82c9509
LP
666 reset_all_signal_handlers();
667
668 close_all_fds(s+1, 1);
a7e3212d
LP
669
670 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
671 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
672
673 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
674 close_nointr_nofail(s[1]);
675
676 fd_cloexec(STDIN_FILENO, false);
677 fd_cloexec(STDOUT_FILENO, false);
678 fd_nonblock(STDIN_FILENO, false);
679 fd_nonblock(STDOUT_FILENO, false);
680
681 if (b->exec_argv)
682 execvp(b->exec_path, b->exec_argv);
683 else {
684 const char *argv[] = { b->exec_path, NULL };
685 execvp(b->exec_path, (char**) argv);
686 }
687
688 _exit(EXIT_FAILURE);
689 }
690
691 close_nointr_nofail(s[1]);
e82c9509 692 b->output_fd = b->input_fd = s[0];
a7e3212d
LP
693
694 return bus_socket_start_auth(b);
695}
696
697int bus_socket_take_fd(sd_bus *b) {
698 int r;
699 assert(b);
700
701 r = bus_socket_setup(b);
702 if (r < 0)
703 return r;
704
705 return bus_socket_start_auth(b);
706}
707
708int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
709 struct iovec *iov;
710 ssize_t k;
711 size_t n;
712 unsigned j;
713
714 assert(bus);
715 assert(m);
716 assert(idx);
717 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
718
719 if (*idx >= m->size)
720 return 0;
a7e3212d
LP
721
722 n = m->n_iovec * sizeof(struct iovec);
723 iov = alloca(n);
724 memcpy(iov, m->iovec, n);
725
726 j = 0;
727 iovec_advance(iov, &j, *idx);
728
15d5af81
LP
729 if (bus->prefer_writev)
730 k = writev(bus->output_fd, iov, m->n_iovec);
731 else {
732 struct msghdr mh;
733 zero(mh);
734
735 if (m->n_fds > 0) {
736 struct cmsghdr *control;
737 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
738
739 mh.msg_control = control;
740 control->cmsg_level = SOL_SOCKET;
741 control->cmsg_type = SCM_RIGHTS;
742 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
743 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
744 }
745
746 mh.msg_iov = iov;
747 mh.msg_iovlen = m->n_iovec;
748
749 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
750 if (k < 0 && errno == ENOTSOCK) {
751 bus->prefer_writev = true;
752 k = writev(bus->output_fd, iov, m->n_iovec);
753 }
754 }
a7e3212d 755
a7e3212d
LP
756 if (k < 0)
757 return errno == EAGAIN ? 0 : -errno;
758
759 *idx += (size_t) k;
760 return 1;
761}
762
763static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
764 uint32_t a, b;
765 uint8_t e;
766 uint64_t sum;
767
768 assert(bus);
769 assert(need);
770 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
771
772 if (bus->rbuffer_size < sizeof(struct bus_header)) {
773 *need = sizeof(struct bus_header) + 8;
774
775 /* Minimum message size:
776 *
777 * Header +
778 *
779 * Method Call: +2 string headers
780 * Signal: +3 string headers
781 * Method Error: +1 string headers
782 * +1 uint32 headers
783 * Method Reply: +1 uint32 headers
784 *
785 * A string header is at least 9 bytes
786 * A uint32 header is at least 8 bytes
787 *
788 * Hence the minimum message size of a valid message
789 * is header + 8 bytes */
790
791 return 0;
792 }
793
794 a = ((const uint32_t*) bus->rbuffer)[1];
795 b = ((const uint32_t*) bus->rbuffer)[3];
796
797 e = ((const uint8_t*) bus->rbuffer)[0];
798 if (e == SD_BUS_LITTLE_ENDIAN) {
799 a = le32toh(a);
800 b = le32toh(b);
801 } else if (e == SD_BUS_BIG_ENDIAN) {
802 a = be32toh(a);
803 b = be32toh(b);
804 } else
805 return -EBADMSG;
806
807 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
808 if (sum >= BUS_MESSAGE_SIZE_MAX)
809 return -ENOBUFS;
810
811 *need = (size_t) sum;
812 return 0;
813}
814
815static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) {
816 sd_bus_message *t;
817 void *b;
818 int r;
819
820 assert(bus);
821 assert(m);
822 assert(bus->rbuffer_size >= size);
823 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
824
825 if (bus->rbuffer_size > size) {
826 b = memdup((const uint8_t*) bus->rbuffer + size,
827 bus->rbuffer_size - size);
828 if (!b)
829 return -ENOMEM;
830 } else
831 b = NULL;
832
833 r = bus_message_from_malloc(bus->rbuffer, size,
834 bus->fds, bus->n_fds,
0f4b73c8
LP
835 bus->ucred_valid ? &bus->ucred : NULL,
836 bus->label[0] ? bus->label : NULL,
a7e3212d
LP
837 &t);
838 if (r < 0) {
839 free(b);
840 return r;
841 }
842
843 bus->rbuffer = b;
844 bus->rbuffer_size -= size;
845
846 bus->fds = NULL;
847 bus->n_fds = 0;
848
849 *m = t;
850 return 1;
851}
852
853int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
854 struct msghdr mh;
855 struct iovec iov;
856 ssize_t k;
857 size_t need;
858 int r;
859 void *b;
860 union {
861 struct cmsghdr cmsghdr;
862 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
863 CMSG_SPACE(sizeof(struct ucred)) +
864 CMSG_SPACE(NAME_MAX)]; /*selinux label */
865 } control;
866 struct cmsghdr *cmsg;
15d5af81 867 bool handle_cmsg;
a7e3212d
LP
868
869 assert(bus);
870 assert(m);
871 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
872
873 r = bus_socket_read_message_need(bus, &need);
874 if (r < 0)
875 return r;
876
877 if (bus->rbuffer_size >= need)
878 return bus_socket_make_message(bus, need, m);
879
880 b = realloc(bus->rbuffer, need);
881 if (!b)
882 return -ENOMEM;
883
884 bus->rbuffer = b;
885
886 zero(iov);
887 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
888 iov.iov_len = need - bus->rbuffer_size;
889
15d5af81
LP
890 if (bus->prefer_readv)
891 k = readv(bus->input_fd, &iov, 1);
892 else {
893 zero(mh);
894 mh.msg_iov = &iov;
895 mh.msg_iovlen = 1;
896 mh.msg_control = &control;
897 mh.msg_controllen = sizeof(control);
898
899 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
900 if (k < 0 && errno == ENOTSOCK) {
901 bus->prefer_readv = true;
902 k = readv(bus->input_fd, &iov, 1);
903 } else
904 handle_cmsg = true;
905 }
a7e3212d
LP
906 if (k < 0)
907 return errno == EAGAIN ? 0 : -errno;
908 if (k == 0)
909 return -ECONNRESET;
910
911 bus->rbuffer_size += k;
912
15d5af81
LP
913 if (handle_cmsg) {
914 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
915 if (cmsg->cmsg_level == SOL_SOCKET &&
916 cmsg->cmsg_type == SCM_RIGHTS) {
917 int n, *f;
918
919 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
920
921 if (!bus->can_fds) {
922 /* Whut? We received fds but this
923 * isn't actually enabled? Close them,
924 * and fail */
925
926 close_many((int*) CMSG_DATA(cmsg), n);
927 return -EIO;
928 }
929
930 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
931 if (!f) {
932 close_many((int*) CMSG_DATA(cmsg), n);
933 return -ENOMEM;
934 }
935
936 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
937 bus->fds = f;
938 bus->n_fds += n;
939 } else if (cmsg->cmsg_level == SOL_SOCKET &&
940 cmsg->cmsg_type == SCM_CREDENTIALS &&
941 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
942
943 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
944 bus->ucred_valid = true;
945
946 } else if (cmsg->cmsg_level == SOL_SOCKET &&
947 cmsg->cmsg_type == SCM_SECURITY) {
948
949 size_t l;
950 l = cmsg->cmsg_len - CMSG_LEN(0);
951 memcpy(&bus->label, CMSG_DATA(cmsg), l);
952 bus->label[l] = 0;
a7e3212d 953 }
a7e3212d
LP
954 }
955 }
956
957 r = bus_socket_read_message_need(bus, &need);
958 if (r < 0)
959 return r;
960
961 if (bus->rbuffer_size >= need)
962 return bus_socket_make_message(bus, need, m);
963
964 return 1;
965}
966
967int bus_socket_process_opening(sd_bus *b) {
968 int error = 0;
969 socklen_t slen = sizeof(error);
970 struct pollfd p;
971 int r;
972
973 assert(b);
974 assert(b->state == BUS_OPENING);
975
976 zero(p);
e82c9509 977 p.fd = b->output_fd;
a7e3212d
LP
978 p.events = POLLOUT;
979
980 r = poll(&p, 1, 0);
981 if (r < 0)
982 return -errno;
983
984 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
985 return 0;
986
e82c9509 987 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
988 if (r < 0)
989 b->last_connect_error = errno;
990 else if (error != 0)
991 b->last_connect_error = error;
992 else if (p.revents & (POLLERR|POLLHUP))
993 b->last_connect_error = ECONNREFUSED;
994 else
995 return bus_socket_start_auth(b);
996
997 return bus_next_address(b);
998}
999
1000int bus_socket_process_authenticating(sd_bus *b) {
1001 int r;
1002
1003 assert(b);
1004 assert(b->state == BUS_AUTHENTICATING);
1005
1006 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1007 return -ETIMEDOUT;
1008
1009 r = bus_socket_write_auth(b);
1010 if (r != 0)
1011 return r;
1012
1013 return bus_socket_read_auth(b);
1014}