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