]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: when reading a message from the socket, make sure to note down the size
[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
238 if (!b->ucred_valid)
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
261 if (u != b->ucred.uid)
262 return 0;
263
264 return 1;
265}
266
267static int bus_socket_auth_write(sd_bus *b, const char *t) {
268 char *p;
269 size_t l;
270
271 assert(b);
272 assert(t);
273
274 /* We only make use of the first iovec */
275 assert(b->auth_index == 0 || b->auth_index == 1);
276
277 l = strlen(t);
278 p = malloc(b->auth_iovec[0].iov_len + l);
279 if (!p)
280 return -ENOMEM;
281
282 memcpy(p, b->auth_iovec[0].iov_base, b->auth_iovec[0].iov_len);
283 memcpy(p + b->auth_iovec[0].iov_len, t, l);
284
285 b->auth_iovec[0].iov_base = p;
286 b->auth_iovec[0].iov_len += l;
287
288 free(b->auth_buffer);
289 b->auth_buffer = p;
290 b->auth_index = 0;
291 return 0;
292}
293
294static int bus_socket_auth_write_ok(sd_bus *b) {
295 char t[3 + 32 + 2 + 1];
296
297 assert(b);
298
98178d39 299 snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
2181a7f5
LP
300 char_array_0(t);
301
302 return bus_socket_auth_write(b, t);
303}
304
305static int bus_socket_auth_verify_server(sd_bus *b) {
306 char *e;
307 const char *line;
308 size_t l;
309 bool processed = false;
310 int r;
311
312 assert(b);
313
314 if (b->rbuffer_size < 3)
315 return 0;
316
317 /* First char must be a NUL byte */
318 if (*(char*) b->rbuffer != 0)
319 return -EIO;
320
321 /* Begin with the first line */
322 if (b->auth_rbegin <= 0)
323 b->auth_rbegin = 1;
324
325 for (;;) {
326 /* Check if line is complete */
327 line = (char*) b->rbuffer + b->auth_rbegin;
328 e = memmem(line, b->rbuffer_size - b->auth_rbegin, "\r\n", 2);
329 if (!e)
330 return processed;
331
332 l = e - line;
333
334 if (line_begins(line, l, "AUTH ANONYMOUS")) {
335
336 r = verify_anonymous_token(b, line + 14, l - 14);
337 if (r < 0)
338 return r;
339 if (r == 0)
340 r = bus_socket_auth_write(b, "REJECTED\r\n");
341 else {
342 b->auth = BUS_AUTH_ANONYMOUS;
343 r = bus_socket_auth_write_ok(b);
344 }
345
346 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
347
348 r = verify_external_token(b, line + 13, l - 13);
349 if (r < 0)
350 return r;
351 if (r == 0)
352 r = bus_socket_auth_write(b, "REJECTED\r\n");
353 else {
354 b->auth = BUS_AUTH_EXTERNAL;
355 r = bus_socket_auth_write_ok(b);
356 }
357
358 } else if (line_begins(line, l, "AUTH"))
359 r = bus_socket_auth_write(b, "REJECTED EXTERNAL ANONYMOUS\r\n");
360 else if (line_equals(line, l, "CANCEL") ||
361 line_begins(line, l, "ERROR")) {
362
363 b->auth = _BUS_AUTH_INVALID;
364 r = bus_socket_auth_write(b, "REJECTED\r\n");
365
366 } else if (line_equals(line, l, "BEGIN")) {
367
368 if (b->auth == _BUS_AUTH_INVALID)
369 r = bus_socket_auth_write(b, "ERROR\r\n");
370 else {
371 /* We can't leave from the auth phase
372 * before we haven't written
373 * everything queued, so let's check
374 * that */
375
376 if (bus_socket_auth_needs_write(b))
377 return 1;
378
379 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
380 memmove(b->rbuffer, e + 2, b->rbuffer_size);
381 return bus_start_running(b);
382 }
383
384 } else if (line_begins(line, l, "DATA")) {
385
386 if (b->auth == _BUS_AUTH_INVALID)
387 r = bus_socket_auth_write(b, "ERROR\r\n");
388 else {
389 if (b->auth == BUS_AUTH_ANONYMOUS)
390 r = verify_anonymous_token(b, line + 4, l - 4);
391 else
392 r = verify_external_token(b, line + 4, l - 4);
393
394 if (r < 0)
395 return r;
396 if (r == 0) {
397 b->auth = _BUS_AUTH_INVALID;
398 r = bus_socket_auth_write(b, "REJECTED\r\n");
399 } else
400 r = bus_socket_auth_write_ok(b);
401 }
402 } else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
403 if (b->auth == _BUS_AUTH_INVALID || !b->negotiate_fds)
404 r = bus_socket_auth_write(b, "ERROR\r\n");
405 else {
406 b->can_fds = true;
407 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
408 }
409 } else
410 r = bus_socket_auth_write(b, "ERROR\r\n");
411
412 if (r < 0)
413 return r;
414
415 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
416
417 processed = true;
418 }
419}
420
421static int bus_socket_auth_verify(sd_bus *b) {
422 assert(b);
423
424 if (b->is_server)
425 return bus_socket_auth_verify_server(b);
426 else
427 return bus_socket_auth_verify_client(b);
428}
429
a7e3212d
LP
430static int bus_socket_read_auth(sd_bus *b) {
431 struct msghdr mh;
432 struct iovec iov;
433 size_t n;
434 ssize_t k;
435 int r;
436 void *p;
2181a7f5
LP
437 union {
438 struct cmsghdr cmsghdr;
439 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
440 CMSG_SPACE(sizeof(struct ucred)) +
441 CMSG_SPACE(NAME_MAX)]; /*selinux label */
442 } control;
443 struct cmsghdr *cmsg;
15d5af81 444 bool handle_cmsg = false;
a7e3212d
LP
445
446 assert(b);
2181a7f5 447 assert(b->state == BUS_AUTHENTICATING);
a7e3212d
LP
448
449 r = bus_socket_auth_verify(b);
450 if (r != 0)
451 return r;
452
2181a7f5 453 n = MAX(256, b->rbuffer_size * 2);
a7e3212d
LP
454
455 if (n > BUS_AUTH_SIZE_MAX)
456 n = BUS_AUTH_SIZE_MAX;
457
458 if (b->rbuffer_size >= n)
459 return -ENOBUFS;
460
461 p = realloc(b->rbuffer, n);
462 if (!p)
463 return -ENOMEM;
464
465 b->rbuffer = p;
466
467 zero(iov);
468 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
469 iov.iov_len = n - b->rbuffer_size;
470
15d5af81
LP
471 if (b->prefer_readv)
472 k = readv(b->input_fd, &iov, 1);
473 else {
474 zero(mh);
475 mh.msg_iov = &iov;
476 mh.msg_iovlen = 1;
477 mh.msg_control = &control;
478 mh.msg_controllen = sizeof(control);
479
480 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
481 if (k < 0 && errno == ENOTSOCK) {
482 b->prefer_readv = true;
483 k = readv(b->input_fd, &iov, 1);
484 } else
485 handle_cmsg = true;
486 }
a7e3212d
LP
487 if (k < 0)
488 return errno == EAGAIN ? 0 : -errno;
489 if (k == 0)
490 return -ECONNRESET;
491
492 b->rbuffer_size += k;
493
15d5af81
LP
494 if (handle_cmsg) {
495 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
496 if (cmsg->cmsg_level == SOL_SOCKET &&
497 cmsg->cmsg_type == SCM_RIGHTS) {
498 int j;
499
500 /* Whut? We received fds during the auth
501 * protocol? Somebody is playing games with
502 * us. Close them all, and fail */
503 j = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
504 close_many((int*) CMSG_DATA(cmsg), j);
505 return -EIO;
2181a7f5 506
15d5af81
LP
507 } else if (cmsg->cmsg_level == SOL_SOCKET &&
508 cmsg->cmsg_type == SCM_CREDENTIALS &&
509 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
2181a7f5 510
15d5af81
LP
511 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
512 b->ucred_valid = true;
2181a7f5 513
15d5af81
LP
514 } else if (cmsg->cmsg_level == SOL_SOCKET &&
515 cmsg->cmsg_type == SCM_SECURITY) {
2181a7f5 516
15d5af81
LP
517 size_t l;
518 l = cmsg->cmsg_len - CMSG_LEN(0);
519 memcpy(&b->label, CMSG_DATA(cmsg), l);
520 b->label[l] = 0;
521 }
2181a7f5
LP
522 }
523 }
524
a7e3212d
LP
525 r = bus_socket_auth_verify(b);
526 if (r != 0)
527 return r;
528
529 return 1;
530}
531
532static int bus_socket_setup(sd_bus *b) {
0f4b73c8 533 int enable;
a7e3212d
LP
534
535 assert(b);
536
d65ddaa4
LP
537 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
538 * socket, just in case. */
0f4b73c8 539 enable = !b->bus_client;
e82c9509
LP
540 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
541 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
a7e3212d
LP
542
543 /* Increase the buffers to a MB */
e82c9509
LP
544 fd_inc_rcvbuf(b->input_fd, 1024*1024);
545 fd_inc_sndbuf(b->output_fd, 1024*1024);
a7e3212d
LP
546
547 return 0;
548}
549
2181a7f5 550static int bus_socket_start_auth_client(sd_bus *b) {
a7e3212d 551 size_t l;
2181a7f5 552 const char *auth_suffix, *auth_prefix;
a7e3212d
LP
553
554 assert(b);
555
2181a7f5
LP
556 if (b->anonymous_auth) {
557 auth_prefix = "\0AUTH ANONYMOUS ";
a7e3212d 558
2181a7f5
LP
559 /* For ANONYMOUS auth we send some arbitrary "trace" string */
560 l = 9;
561 b->auth_buffer = hexmem("anonymous", l);
562 } else {
563 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
a7e3212d 564
2181a7f5 565 auth_prefix = "\0AUTH EXTERNAL ";
a7e3212d 566
2181a7f5
LP
567 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
568 char_array_0(text);
a7e3212d 569
2181a7f5
LP
570 l = strlen(text);
571 b->auth_buffer = hexmem(text, l);
572 }
573
574 if (!b->auth_buffer)
a7e3212d
LP
575 return -ENOMEM;
576
2181a7f5
LP
577 if (b->negotiate_fds)
578 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
579 else
580 auth_suffix = "\r\nBEGIN\r\n";
a7e3212d
LP
581
582 b->auth_iovec[0].iov_base = (void*) auth_prefix;
2181a7f5
LP
583 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
584 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
a7e3212d
LP
585 b->auth_iovec[1].iov_len = l * 2;
586 b->auth_iovec[2].iov_base = (void*) auth_suffix;
587 b->auth_iovec[2].iov_len = strlen(auth_suffix);
a7e3212d
LP
588
589 return bus_socket_write_auth(b);
590}
591
2181a7f5 592static int bus_socket_start_auth(sd_bus *b) {
2181a7f5
LP
593 assert(b);
594
595 b->state = BUS_AUTHENTICATING;
596 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
597
9ab32f9d 598 if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
2181a7f5
LP
599 b->negotiate_fds = false;
600
9ab32f9d
LP
601 if (b->output_fd != b->input_fd)
602 if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
e82c9509 603 b->negotiate_fds = false;
e82c9509 604
2181a7f5
LP
605 if (b->is_server)
606 return bus_socket_read_auth(b);
607 else
608 return bus_socket_start_auth_client(b);
609}
610
a7e3212d
LP
611int bus_socket_connect(sd_bus *b) {
612 int r;
613
614 assert(b);
e82c9509
LP
615 assert(b->input_fd < 0);
616 assert(b->output_fd < 0);
a7e3212d
LP
617 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
618
e82c9509
LP
619 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
620 if (b->input_fd < 0)
a7e3212d
LP
621 return -errno;
622
e82c9509
LP
623 b->output_fd = b->input_fd;
624
a7e3212d
LP
625 r = bus_socket_setup(b);
626 if (r < 0)
627 return r;
628
e82c9509 629 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
a7e3212d
LP
630 if (r < 0) {
631 if (errno == EINPROGRESS)
632 return 1;
633
634 return -errno;
635 }
636
637 return bus_socket_start_auth(b);
638}
639
640int bus_socket_exec(sd_bus *b) {
e82c9509 641 int s[2], r;
a7e3212d
LP
642 pid_t pid;
643
644 assert(b);
e82c9509
LP
645 assert(b->input_fd < 0);
646 assert(b->output_fd < 0);
a7e3212d
LP
647 assert(b->exec_path);
648
e82c9509
LP
649 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
650 if (r < 0)
a7e3212d
LP
651 return -errno;
652
653 pid = fork();
654 if (pid < 0) {
655 close_pipe(s);
656 return -errno;
657 }
658 if (pid == 0) {
659 /* Child */
660
e82c9509
LP
661 reset_all_signal_handlers();
662
663 close_all_fds(s+1, 1);
a7e3212d
LP
664
665 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
666 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
667
668 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
669 close_nointr_nofail(s[1]);
670
671 fd_cloexec(STDIN_FILENO, false);
672 fd_cloexec(STDOUT_FILENO, false);
673 fd_nonblock(STDIN_FILENO, false);
674 fd_nonblock(STDOUT_FILENO, false);
675
676 if (b->exec_argv)
677 execvp(b->exec_path, b->exec_argv);
678 else {
679 const char *argv[] = { b->exec_path, NULL };
680 execvp(b->exec_path, (char**) argv);
681 }
682
683 _exit(EXIT_FAILURE);
684 }
685
686 close_nointr_nofail(s[1]);
e82c9509 687 b->output_fd = b->input_fd = s[0];
a7e3212d
LP
688
689 return bus_socket_start_auth(b);
690}
691
692int bus_socket_take_fd(sd_bus *b) {
693 int r;
694 assert(b);
695
696 r = bus_socket_setup(b);
697 if (r < 0)
698 return r;
699
700 return bus_socket_start_auth(b);
701}
702
703int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
a7e3212d
LP
704 struct iovec *iov;
705 ssize_t k;
706 size_t n;
707 unsigned j;
708
709 assert(bus);
710 assert(m);
711 assert(idx);
712 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
713
714 if (*idx >= m->size)
715 return 0;
a7e3212d
LP
716
717 n = m->n_iovec * sizeof(struct iovec);
718 iov = alloca(n);
719 memcpy(iov, m->iovec, n);
720
721 j = 0;
722 iovec_advance(iov, &j, *idx);
723
15d5af81
LP
724 if (bus->prefer_writev)
725 k = writev(bus->output_fd, iov, m->n_iovec);
726 else {
727 struct msghdr mh;
728 zero(mh);
729
730 if (m->n_fds > 0) {
731 struct cmsghdr *control;
732 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
733
734 mh.msg_control = control;
735 control->cmsg_level = SOL_SOCKET;
736 control->cmsg_type = SCM_RIGHTS;
737 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
738 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
739 }
740
741 mh.msg_iov = iov;
742 mh.msg_iovlen = m->n_iovec;
743
744 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
745 if (k < 0 && errno == ENOTSOCK) {
746 bus->prefer_writev = true;
747 k = writev(bus->output_fd, iov, m->n_iovec);
748 }
749 }
a7e3212d 750
a7e3212d
LP
751 if (k < 0)
752 return errno == EAGAIN ? 0 : -errno;
753
754 *idx += (size_t) k;
755 return 1;
756}
757
758static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
759 uint32_t a, b;
760 uint8_t e;
761 uint64_t sum;
762
763 assert(bus);
764 assert(need);
765 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
766
767 if (bus->rbuffer_size < sizeof(struct bus_header)) {
768 *need = sizeof(struct bus_header) + 8;
769
770 /* Minimum message size:
771 *
772 * Header +
773 *
774 * Method Call: +2 string headers
775 * Signal: +3 string headers
776 * Method Error: +1 string headers
777 * +1 uint32 headers
778 * Method Reply: +1 uint32 headers
779 *
780 * A string header is at least 9 bytes
781 * A uint32 header is at least 8 bytes
782 *
783 * Hence the minimum message size of a valid message
784 * is header + 8 bytes */
785
786 return 0;
787 }
788
789 a = ((const uint32_t*) bus->rbuffer)[1];
790 b = ((const uint32_t*) bus->rbuffer)[3];
791
792 e = ((const uint8_t*) bus->rbuffer)[0];
793 if (e == SD_BUS_LITTLE_ENDIAN) {
794 a = le32toh(a);
795 b = le32toh(b);
796 } else if (e == SD_BUS_BIG_ENDIAN) {
797 a = be32toh(a);
798 b = be32toh(b);
799 } else
800 return -EBADMSG;
801
802 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
803 if (sum >= BUS_MESSAGE_SIZE_MAX)
804 return -ENOBUFS;
805
806 *need = (size_t) sum;
807 return 0;
808}
809
810static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) {
811 sd_bus_message *t;
812 void *b;
813 int r;
814
815 assert(bus);
816 assert(m);
817 assert(bus->rbuffer_size >= size);
818 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
819
820 if (bus->rbuffer_size > size) {
821 b = memdup((const uint8_t*) bus->rbuffer + size,
822 bus->rbuffer_size - size);
823 if (!b)
824 return -ENOMEM;
825 } else
826 b = NULL;
827
828 r = bus_message_from_malloc(bus->rbuffer, size,
829 bus->fds, bus->n_fds,
0f4b73c8
LP
830 bus->ucred_valid ? &bus->ucred : NULL,
831 bus->label[0] ? bus->label : NULL,
a7e3212d
LP
832 &t);
833 if (r < 0) {
834 free(b);
835 return r;
836 }
837
838 bus->rbuffer = b;
839 bus->rbuffer_size -= size;
840
841 bus->fds = NULL;
842 bus->n_fds = 0;
843
844 *m = t;
845 return 1;
846}
847
848int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
849 struct msghdr mh;
850 struct iovec iov;
851 ssize_t k;
852 size_t need;
853 int r;
854 void *b;
855 union {
856 struct cmsghdr cmsghdr;
857 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
858 CMSG_SPACE(sizeof(struct ucred)) +
859 CMSG_SPACE(NAME_MAX)]; /*selinux label */
860 } control;
861 struct cmsghdr *cmsg;
15d5af81 862 bool handle_cmsg;
a7e3212d
LP
863
864 assert(bus);
865 assert(m);
866 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
867
868 r = bus_socket_read_message_need(bus, &need);
869 if (r < 0)
870 return r;
871
872 if (bus->rbuffer_size >= need)
873 return bus_socket_make_message(bus, need, m);
874
875 b = realloc(bus->rbuffer, need);
876 if (!b)
877 return -ENOMEM;
878
879 bus->rbuffer = b;
880
881 zero(iov);
882 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
883 iov.iov_len = need - bus->rbuffer_size;
884
15d5af81
LP
885 if (bus->prefer_readv)
886 k = readv(bus->input_fd, &iov, 1);
887 else {
888 zero(mh);
889 mh.msg_iov = &iov;
890 mh.msg_iovlen = 1;
891 mh.msg_control = &control;
892 mh.msg_controllen = sizeof(control);
893
894 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
895 if (k < 0 && errno == ENOTSOCK) {
896 bus->prefer_readv = true;
897 k = readv(bus->input_fd, &iov, 1);
898 } else
899 handle_cmsg = true;
900 }
a7e3212d
LP
901 if (k < 0)
902 return errno == EAGAIN ? 0 : -errno;
903 if (k == 0)
904 return -ECONNRESET;
905
906 bus->rbuffer_size += k;
907
15d5af81
LP
908 if (handle_cmsg) {
909 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
910 if (cmsg->cmsg_level == SOL_SOCKET &&
911 cmsg->cmsg_type == SCM_RIGHTS) {
912 int n, *f;
913
914 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
915
916 if (!bus->can_fds) {
917 /* Whut? We received fds but this
918 * isn't actually enabled? Close them,
919 * and fail */
920
921 close_many((int*) CMSG_DATA(cmsg), n);
922 return -EIO;
923 }
924
925 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
926 if (!f) {
927 close_many((int*) CMSG_DATA(cmsg), n);
928 return -ENOMEM;
929 }
930
931 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
932 bus->fds = f;
933 bus->n_fds += n;
934 } else if (cmsg->cmsg_level == SOL_SOCKET &&
935 cmsg->cmsg_type == SCM_CREDENTIALS &&
936 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
937
938 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
939 bus->ucred_valid = true;
940
941 } else if (cmsg->cmsg_level == SOL_SOCKET &&
942 cmsg->cmsg_type == SCM_SECURITY) {
943
944 size_t l;
945 l = cmsg->cmsg_len - CMSG_LEN(0);
946 memcpy(&bus->label, CMSG_DATA(cmsg), l);
947 bus->label[l] = 0;
a7e3212d 948 }
a7e3212d
LP
949 }
950 }
951
952 r = bus_socket_read_message_need(bus, &need);
953 if (r < 0)
954 return r;
955
956 if (bus->rbuffer_size >= need)
957 return bus_socket_make_message(bus, need, m);
958
959 return 1;
960}
961
962int bus_socket_process_opening(sd_bus *b) {
963 int error = 0;
964 socklen_t slen = sizeof(error);
965 struct pollfd p;
966 int r;
967
968 assert(b);
969 assert(b->state == BUS_OPENING);
970
971 zero(p);
e82c9509 972 p.fd = b->output_fd;
a7e3212d
LP
973 p.events = POLLOUT;
974
975 r = poll(&p, 1, 0);
976 if (r < 0)
977 return -errno;
978
979 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
980 return 0;
981
e82c9509 982 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
a7e3212d
LP
983 if (r < 0)
984 b->last_connect_error = errno;
985 else if (error != 0)
986 b->last_connect_error = error;
987 else if (p.revents & (POLLERR|POLLHUP))
988 b->last_connect_error = ECONNREFUSED;
989 else
990 return bus_socket_start_auth(b);
991
992 return bus_next_address(b);
993}
994
995int bus_socket_process_authenticating(sd_bus *b) {
996 int r;
997
998 assert(b);
999 assert(b->state == BUS_AUTHENTICATING);
1000
1001 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
1002 return -ETIMEDOUT;
1003
1004 r = bus_socket_write_auth(b);
1005 if (r != 0)
1006 return r;
1007
1008 return bus_socket_read_auth(b);
1009}