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