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