]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-socket.c
bus: split socket related code into bus-socket.[ch], to prepare for kdbus backend
[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"
33
34#include "sd-bus.h"
35#include "bus-socket.h"
36#include "bus-internal.h"
37#include "bus-message.h"
38
39static void iovec_advance(struct iovec *iov, unsigned *idx, size_t size) {
40
41 while (size > 0) {
42 struct iovec *i = iov + *idx;
43
44 if (i->iov_len > size) {
45 i->iov_base = (uint8_t*) i->iov_base + size;
46 i->iov_len -= size;
47 return;
48 }
49
50 size -= i->iov_len;
51
52 i->iov_base = NULL;
53 i->iov_len = 0;
54
55 (*idx) ++;
56 }
57}
58
59static int bus_socket_write_auth(sd_bus *b) {
60 struct msghdr mh;
61 ssize_t k;
62
63 assert(b);
64 assert(b->state == BUS_AUTHENTICATING);
65
66 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
67 return 0;
68
69 if (b->auth_timeout == 0)
70 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
71
72 zero(mh);
73 mh.msg_iov = b->auth_iovec + b->auth_index;
74 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
75
76 k = sendmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
77 if (k < 0)
78 return errno == EAGAIN ? 0 : -errno;
79
80 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
81
82 return 1;
83}
84
85static int bus_socket_auth_verify(sd_bus *b) {
86 char *e, *f, *start;
87 sd_id128_t peer;
88 unsigned i;
89 int r;
90
91 /* We expect two response lines: "OK" and possibly
92 * "AGREE_UNIX_FD" */
93
94 e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2);
95 if (!e)
96 return 0;
97
98 if (b->negotiate_fds) {
99 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
100 if (!f)
101 return 0;
102
103 start = f + 2;
104 } else {
105 f = NULL;
106 start = e + 2;
107 }
108
109 /* Nice! We got all the lines we need. First check the OK
110 * line */
111
112 if (e - (char*) b->rbuffer != 3 + 32)
113 return -EPERM;
114
115 if (memcmp(b->rbuffer, "OK ", 3))
116 return -EPERM;
117
118 for (i = 0; i < 32; i += 2) {
119 int x, y;
120
121 x = unhexchar(((char*) b->rbuffer)[3 + i]);
122 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
123
124 if (x < 0 || y < 0)
125 return -EINVAL;
126
127 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
128 }
129
130 if (!sd_id128_equal(b->peer, SD_ID128_NULL) &&
131 !sd_id128_equal(b->peer, peer))
132 return -EPERM;
133
134 b->peer = peer;
135
136 /* And possibly check the second line, too */
137
138 if (f)
139 b->can_fds =
140 (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
141 memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
142
143 b->rbuffer_size -= (start - (char*) b->rbuffer);
144 memmove(b->rbuffer, start, b->rbuffer_size);
145
146 r = bus_start_running(b);
147 if (r < 0)
148 return r;
149
150 return 1;
151}
152
153static int bus_socket_read_auth(sd_bus *b) {
154 struct msghdr mh;
155 struct iovec iov;
156 size_t n;
157 ssize_t k;
158 int r;
159 void *p;
160
161 assert(b);
162
163 r = bus_socket_auth_verify(b);
164 if (r != 0)
165 return r;
166
167 n = MAX(3 + 32 + 2 + sizeof("AGREE_UNIX_FD") - 1 + 2, b->rbuffer_size * 2);
168
169 if (n > BUS_AUTH_SIZE_MAX)
170 n = BUS_AUTH_SIZE_MAX;
171
172 if (b->rbuffer_size >= n)
173 return -ENOBUFS;
174
175 p = realloc(b->rbuffer, n);
176 if (!p)
177 return -ENOMEM;
178
179 b->rbuffer = p;
180
181 zero(iov);
182 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
183 iov.iov_len = n - b->rbuffer_size;
184
185 zero(mh);
186 mh.msg_iov = &iov;
187 mh.msg_iovlen = 1;
188
189 k = recvmsg(b->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
190 if (k < 0)
191 return errno == EAGAIN ? 0 : -errno;
192 if (k == 0)
193 return -ECONNRESET;
194
195 b->rbuffer_size += k;
196
197 r = bus_socket_auth_verify(b);
198 if (r != 0)
199 return r;
200
201 return 1;
202}
203
204static int bus_socket_setup(sd_bus *b) {
205 int one;
206
207 assert(b);
208
209 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any socket,
210 * just in case. This is actually irrelavant for */
211 one = 1;
212 setsockopt(b->fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
213 setsockopt(b->fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
214
215 /* Increase the buffers to a MB */
216 fd_inc_rcvbuf(b->fd, 1024*1024);
217 fd_inc_sndbuf(b->fd, 1024*1024);
218
219 return 0;
220}
221
222static int bus_socket_start_auth(sd_bus *b) {
223 static const char auth_prefix[] = "\0AUTH EXTERNAL ";
224 static const char auth_suffix_with_unix_fd[] = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
225 static const char auth_suffix_without_unix_fd[] = "\r\nBEGIN\r\n";
226
227 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
228 size_t l;
229 const char *auth_suffix;
230 int domain = 0, r;
231 socklen_t sl;
232
233 assert(b);
234
235 b->state = BUS_AUTHENTICATING;
236
237 sl = sizeof(domain);
238 r = getsockopt(b->fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
239 if (r < 0)
240 return -errno;
241
242 if (domain != AF_UNIX)
243 b->negotiate_fds = false;
244
245 snprintf(text, sizeof(text), "%llu", (unsigned long long) geteuid());
246 char_array_0(text);
247
248 l = strlen(text);
249 b->auth_uid = hexmem(text, l);
250 if (!b->auth_uid)
251 return -ENOMEM;
252
253 auth_suffix = b->negotiate_fds ? auth_suffix_with_unix_fd : auth_suffix_without_unix_fd;
254
255 b->auth_iovec[0].iov_base = (void*) auth_prefix;
256 b->auth_iovec[0].iov_len = sizeof(auth_prefix) -1;
257 b->auth_iovec[1].iov_base = (void*) b->auth_uid;
258 b->auth_iovec[1].iov_len = l * 2;
259 b->auth_iovec[2].iov_base = (void*) auth_suffix;
260 b->auth_iovec[2].iov_len = strlen(auth_suffix);
261 b->auth_size = sizeof(auth_prefix) - 1 + l * 2 + sizeof(auth_suffix) - 1;
262
263 return bus_socket_write_auth(b);
264}
265
266int bus_socket_connect(sd_bus *b) {
267 int r;
268
269 assert(b);
270 assert(b->fd < 0);
271 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
272
273 b->fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
274 if (b->fd < 0)
275 return -errno;
276
277 r = bus_socket_setup(b);
278 if (r < 0)
279 return r;
280
281 r = connect(b->fd, &b->sockaddr.sa, b->sockaddr_size);
282 if (r < 0) {
283 if (errno == EINPROGRESS)
284 return 1;
285
286 return -errno;
287 }
288
289 return bus_socket_start_auth(b);
290}
291
292int bus_socket_exec(sd_bus *b) {
293 int s[2];
294 pid_t pid;
295
296 assert(b);
297 assert(b->fd < 0);
298 assert(b->exec_path);
299
300 b->fd = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
301 if (b->fd < 0)
302 return -errno;
303
304 pid = fork();
305 if (pid < 0) {
306 close_pipe(s);
307 return -errno;
308 }
309 if (pid == 0) {
310 /* Child */
311
312 close_all_fds(s, 2);
313 close_nointr_nofail(s[0]);
314
315 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
316 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
317
318 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
319 close_nointr_nofail(s[1]);
320
321 fd_cloexec(STDIN_FILENO, false);
322 fd_cloexec(STDOUT_FILENO, false);
323 fd_nonblock(STDIN_FILENO, false);
324 fd_nonblock(STDOUT_FILENO, false);
325
326 if (b->exec_argv)
327 execvp(b->exec_path, b->exec_argv);
328 else {
329 const char *argv[] = { b->exec_path, NULL };
330 execvp(b->exec_path, (char**) argv);
331 }
332
333 _exit(EXIT_FAILURE);
334 }
335
336 close_nointr_nofail(s[1]);
337 b->fd = s[0];
338
339 return bus_socket_start_auth(b);
340}
341
342int bus_socket_take_fd(sd_bus *b) {
343 int r;
344 assert(b);
345
346 r = bus_socket_setup(b);
347 if (r < 0)
348 return r;
349
350 return bus_socket_start_auth(b);
351}
352
353int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
354 struct msghdr mh;
355 struct iovec *iov;
356 ssize_t k;
357 size_t n;
358 unsigned j;
359
360 assert(bus);
361 assert(m);
362 assert(idx);
363 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
364
365 if (*idx >= m->size)
366 return 0;
367 zero(mh);
368
369 if (m->n_fds > 0) {
370 struct cmsghdr *control;
371 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
372
373 mh.msg_control = control;
374 control->cmsg_level = SOL_SOCKET;
375 control->cmsg_type = SCM_RIGHTS;
376 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
377 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
378 }
379
380 n = m->n_iovec * sizeof(struct iovec);
381 iov = alloca(n);
382 memcpy(iov, m->iovec, n);
383
384 j = 0;
385 iovec_advance(iov, &j, *idx);
386
387 mh.msg_iov = iov;
388 mh.msg_iovlen = m->n_iovec;
389
390 k = sendmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
391 if (k < 0)
392 return errno == EAGAIN ? 0 : -errno;
393
394 *idx += (size_t) k;
395 return 1;
396}
397
398static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
399 uint32_t a, b;
400 uint8_t e;
401 uint64_t sum;
402
403 assert(bus);
404 assert(need);
405 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
406
407 if (bus->rbuffer_size < sizeof(struct bus_header)) {
408 *need = sizeof(struct bus_header) + 8;
409
410 /* Minimum message size:
411 *
412 * Header +
413 *
414 * Method Call: +2 string headers
415 * Signal: +3 string headers
416 * Method Error: +1 string headers
417 * +1 uint32 headers
418 * Method Reply: +1 uint32 headers
419 *
420 * A string header is at least 9 bytes
421 * A uint32 header is at least 8 bytes
422 *
423 * Hence the minimum message size of a valid message
424 * is header + 8 bytes */
425
426 return 0;
427 }
428
429 a = ((const uint32_t*) bus->rbuffer)[1];
430 b = ((const uint32_t*) bus->rbuffer)[3];
431
432 e = ((const uint8_t*) bus->rbuffer)[0];
433 if (e == SD_BUS_LITTLE_ENDIAN) {
434 a = le32toh(a);
435 b = le32toh(b);
436 } else if (e == SD_BUS_BIG_ENDIAN) {
437 a = be32toh(a);
438 b = be32toh(b);
439 } else
440 return -EBADMSG;
441
442 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
443 if (sum >= BUS_MESSAGE_SIZE_MAX)
444 return -ENOBUFS;
445
446 *need = (size_t) sum;
447 return 0;
448}
449
450static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) {
451 sd_bus_message *t;
452 void *b;
453 int r;
454
455 assert(bus);
456 assert(m);
457 assert(bus->rbuffer_size >= size);
458 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
459
460 if (bus->rbuffer_size > size) {
461 b = memdup((const uint8_t*) bus->rbuffer + size,
462 bus->rbuffer_size - size);
463 if (!b)
464 return -ENOMEM;
465 } else
466 b = NULL;
467
468 r = bus_message_from_malloc(bus->rbuffer, size,
469 bus->fds, bus->n_fds,
470 bus->ucred_valid ? &bus->ucred : NULL,
471 bus->label[0] ? bus->label : NULL,
472 &t);
473 if (r < 0) {
474 free(b);
475 return r;
476 }
477
478 bus->rbuffer = b;
479 bus->rbuffer_size -= size;
480
481 bus->fds = NULL;
482 bus->n_fds = 0;
483
484 *m = t;
485 return 1;
486}
487
488int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
489 struct msghdr mh;
490 struct iovec iov;
491 ssize_t k;
492 size_t need;
493 int r;
494 void *b;
495 union {
496 struct cmsghdr cmsghdr;
497 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
498 CMSG_SPACE(sizeof(struct ucred)) +
499 CMSG_SPACE(NAME_MAX)]; /*selinux label */
500 } control;
501 struct cmsghdr *cmsg;
502
503 assert(bus);
504 assert(m);
505 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
506
507 r = bus_socket_read_message_need(bus, &need);
508 if (r < 0)
509 return r;
510
511 if (bus->rbuffer_size >= need)
512 return bus_socket_make_message(bus, need, m);
513
514 b = realloc(bus->rbuffer, need);
515 if (!b)
516 return -ENOMEM;
517
518 bus->rbuffer = b;
519
520 zero(iov);
521 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
522 iov.iov_len = need - bus->rbuffer_size;
523
524 zero(mh);
525 mh.msg_iov = &iov;
526 mh.msg_iovlen = 1;
527 mh.msg_control = &control;
528 mh.msg_controllen = sizeof(control);
529
530 k = recvmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
531 if (k < 0)
532 return errno == EAGAIN ? 0 : -errno;
533 if (k == 0)
534 return -ECONNRESET;
535
536 bus->rbuffer_size += k;
537
538 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
539 if (cmsg->cmsg_level == SOL_SOCKET &&
540 cmsg->cmsg_type == SCM_RIGHTS) {
541 int n, *f;
542
543 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
544
545 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
546 if (!f) {
547 close_many((int*) CMSG_DATA(cmsg), n);
548 return -ENOMEM;
549 }
550
551 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
552 bus->fds = f;
553 bus->n_fds += n;
554 } else if (cmsg->cmsg_level == SOL_SOCKET &&
555 cmsg->cmsg_type == SCM_CREDENTIALS &&
556 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
557
558 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
559 bus->ucred_valid = true;
560
561 } else if (cmsg->cmsg_level == SOL_SOCKET &&
562 cmsg->cmsg_type == SCM_SECURITY) {
563
564 size_t l;
565 l = cmsg->cmsg_len - CMSG_LEN(0);
566 memcpy(&bus->label, CMSG_DATA(cmsg), l);
567 bus->label[l] = 0;
568 }
569 }
570
571 r = bus_socket_read_message_need(bus, &need);
572 if (r < 0)
573 return r;
574
575 if (bus->rbuffer_size >= need)
576 return bus_socket_make_message(bus, need, m);
577
578 return 1;
579}
580
581int bus_socket_process_opening(sd_bus *b) {
582 int error = 0;
583 socklen_t slen = sizeof(error);
584 struct pollfd p;
585 int r;
586
587 assert(b);
588 assert(b->state == BUS_OPENING);
589
590 zero(p);
591 p.fd = b->fd;
592 p.events = POLLOUT;
593
594 r = poll(&p, 1, 0);
595 if (r < 0)
596 return -errno;
597
598 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
599 return 0;
600
601 r = getsockopt(b->fd, SOL_SOCKET, SO_ERROR, &error, &slen);
602 if (r < 0)
603 b->last_connect_error = errno;
604 else if (error != 0)
605 b->last_connect_error = error;
606 else if (p.revents & (POLLERR|POLLHUP))
607 b->last_connect_error = ECONNREFUSED;
608 else
609 return bus_socket_start_auth(b);
610
611 return bus_next_address(b);
612}
613
614int bus_socket_process_authenticating(sd_bus *b) {
615 int r;
616
617 assert(b);
618 assert(b->state == BUS_AUTHENTICATING);
619
620 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
621 return -ETIMEDOUT;
622
623 r = bus_socket_write_auth(b);
624 if (r != 0)
625 return r;
626
627 return bus_socket_read_auth(b);
628}