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