1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
36 #include "bus-socket.h"
37 #include "bus-internal.h"
38 #include "bus-message.h"
40 static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) {
43 struct iovec *i = iov + *idx;
45 if (i->iov_len > size) {
46 i->iov_base = (uint8_t*) i->iov_base + size;
60 bool bus_socket_auth_needs_write(sd_bus *b) {
64 if (b->auth_index >= ELEMENTSOF(b->auth_iovec))
67 for (i = b->auth_index; i < ELEMENTSOF(b->auth_iovec); i++) {
68 struct iovec *j = b->auth_iovec + i;
77 static int bus_socket_write_auth(sd_bus *b) {
82 assert(b->state == BUS_AUTHENTICATING);
84 if (!bus_socket_auth_needs_write(b))
88 mh.msg_iov = b->auth_iovec + b->auth_index;
89 mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
91 k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
93 return errno == EAGAIN ? 0 : -errno;
95 iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k);
100 static int bus_socket_auth_verify_client(sd_bus *b) {
108 /* We expect two response lines: "OK" and possibly
111 e = memmem(b->rbuffer, b->rbuffer_size, "\r\n", 2);
115 if (b->negotiate_fds) {
116 f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
126 /* Nice! We got all the lines we need. First check the OK
129 if (e - (char*) b->rbuffer != 3 + 32)
132 if (memcmp(b->rbuffer, "OK ", 3))
135 b->auth = b->anonymous_auth ? BUS_AUTH_ANONYMOUS : BUS_AUTH_EXTERNAL;
137 for (i = 0; i < 32; i += 2) {
140 x = unhexchar(((char*) b->rbuffer)[3 + i]);
141 y = unhexchar(((char*) b->rbuffer)[3 + i + 1]);
146 peer.bytes[i/2] = ((uint8_t) x << 4 | (uint8_t) y);
149 if (!sd_id128_equal(b->server_id, SD_ID128_NULL) &&
150 !sd_id128_equal(b->server_id, peer))
155 /* And possibly check the second line, too */
159 (f - e == sizeof("\r\nAGREE_UNIX_FD") - 1) &&
160 memcmp(e + 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
162 b->rbuffer_size -= (start - (char*) b->rbuffer);
163 memmove(b->rbuffer, start, b->rbuffer_size);
165 r = bus_start_running(b);
172 static bool line_equals(const char *s, size_t m, const char *line) {
179 return memcmp(s, line, l) == 0;
182 static bool line_begins(const char *s, size_t m, const char *word) {
189 if (memcmp(s, word, l) != 0)
192 return m == l || (m > l && s[l] == ' ');
195 static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
196 _cleanup_free_ char *token = NULL;
198 if (!b->anonymous_auth)
209 token = unhexmem(p, l);
213 if (memchr(token, 0, l/2))
216 return !!utf8_is_valid(token);
219 static int verify_external_token(sd_bus *b, const char *p, size_t l) {
220 _cleanup_free_ char *token = NULL;
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. */
240 token = unhexmem(p, l);
244 if (memchr(token, 0, l/2))
247 r = parse_uid(token, &u);
251 if (u != b->ucred.uid)
257 static int bus_socket_auth_write(sd_bus *b, const char *t) {
264 /* We only make use of the first iovec */
265 assert(b->auth_index == 0 || b->auth_index == 1);
268 p = malloc(b->auth_iovec[0].iov_len + l);
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);
275 b->auth_iovec[0].iov_base = p;
276 b->auth_iovec[0].iov_len += l;
278 free(b->auth_buffer);
284 static int bus_socket_auth_write_ok(sd_bus *b) {
285 char t[3 + 32 + 2 + 1];
289 snprintf(t, sizeof(t), "OK " SD_ID128_FORMAT_STR "\r\n", SD_ID128_FORMAT_VAL(b->server_id));
292 return bus_socket_auth_write(b, t);
295 static int bus_socket_auth_verify_server(sd_bus *b) {
299 bool processed = false;
304 if (b->rbuffer_size < 3)
307 /* First char must be a NUL byte */
308 if (*(char*) b->rbuffer != 0)
311 /* Begin with the first line */
312 if (b->auth_rbegin <= 0)
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);
324 if (line_begins(line, l, "AUTH ANONYMOUS")) {
326 r = verify_anonymous_token(b, line + 14, l - 14);
330 r = bus_socket_auth_write(b, "REJECTED\r\n");
332 b->auth = BUS_AUTH_ANONYMOUS;
333 r = bus_socket_auth_write_ok(b);
336 } else if (line_begins(line, l, "AUTH EXTERNAL")) {
338 r = verify_external_token(b, line + 13, l - 13);
342 r = bus_socket_auth_write(b, "REJECTED\r\n");
344 b->auth = BUS_AUTH_EXTERNAL;
345 r = bus_socket_auth_write_ok(b);
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")) {
353 b->auth = _BUS_AUTH_INVALID;
354 r = bus_socket_auth_write(b, "REJECTED\r\n");
356 } else if (line_equals(line, l, "BEGIN")) {
358 if (b->auth == _BUS_AUTH_INVALID)
359 r = bus_socket_auth_write(b, "ERROR\r\n");
361 /* We can't leave from the auth phase
362 * before we haven't written
363 * everything queued, so let's check
366 if (bus_socket_auth_needs_write(b))
369 b->rbuffer_size -= (e + 2 - (char*) b->rbuffer);
370 memmove(b->rbuffer, e + 2, b->rbuffer_size);
371 return bus_start_running(b);
374 } else if (line_begins(line, l, "DATA")) {
376 if (b->auth == _BUS_AUTH_INVALID)
377 r = bus_socket_auth_write(b, "ERROR\r\n");
379 if (b->auth == BUS_AUTH_ANONYMOUS)
380 r = verify_anonymous_token(b, line + 4, l - 4);
382 r = verify_external_token(b, line + 4, l - 4);
387 b->auth = _BUS_AUTH_INVALID;
388 r = bus_socket_auth_write(b, "REJECTED\r\n");
390 r = bus_socket_auth_write_ok(b);
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");
397 r = bus_socket_auth_write(b, "AGREE_UNIX_FD\r\n");
400 r = bus_socket_auth_write(b, "ERROR\r\n");
405 b->auth_rbegin = e + 2 - (char*) b->rbuffer;
411 static int bus_socket_auth_verify(sd_bus *b) {
415 return bus_socket_auth_verify_server(b);
417 return bus_socket_auth_verify_client(b);
420 static int bus_socket_read_auth(sd_bus *b) {
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 */
433 struct cmsghdr *cmsg;
436 assert(b->state == BUS_AUTHENTICATING);
438 r = bus_socket_auth_verify(b);
442 n = MAX(256, b->rbuffer_size * 2);
444 if (n > BUS_AUTH_SIZE_MAX)
445 n = BUS_AUTH_SIZE_MAX;
447 if (b->rbuffer_size >= n)
450 p = realloc(b->rbuffer, n);
457 iov.iov_base = (uint8_t*) b->rbuffer + b->rbuffer_size;
458 iov.iov_len = n - b->rbuffer_size;
463 mh.msg_control = &control;
464 mh.msg_controllen = sizeof(control);
466 k = recvmsg(b->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
468 return errno == EAGAIN ? 0 : -errno;
472 b->rbuffer_size += k;
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) {
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);
486 } else if (cmsg->cmsg_level == SOL_SOCKET &&
487 cmsg->cmsg_type == SCM_CREDENTIALS &&
488 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
490 memcpy(&b->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
491 b->ucred_valid = true;
493 } else if (cmsg->cmsg_level == SOL_SOCKET &&
494 cmsg->cmsg_type == SCM_SECURITY) {
497 l = cmsg->cmsg_len - CMSG_LEN(0);
498 memcpy(&b->label, CMSG_DATA(cmsg), l);
503 r = bus_socket_auth_verify(b);
510 static int bus_socket_setup(sd_bus *b) {
515 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any
516 * socket, just in case. */
517 enable = !b->bus_client;
518 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
519 setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
521 /* Increase the buffers to a MB */
522 fd_inc_rcvbuf(b->input_fd, 1024*1024);
523 fd_inc_sndbuf(b->output_fd, 1024*1024);
528 static int bus_socket_start_auth_client(sd_bus *b) {
530 const char *auth_suffix, *auth_prefix;
534 if (b->anonymous_auth) {
535 auth_prefix = "\0AUTH ANONYMOUS ";
537 /* For ANONYMOUS auth we send some arbitrary "trace" string */
539 b->auth_buffer = hexmem("anonymous", l);
541 char text[20 + 1]; /* enough space for a 64bit integer plus NUL */
543 auth_prefix = "\0AUTH EXTERNAL ";
545 snprintf(text, sizeof(text), "%lu", (unsigned long) geteuid());
549 b->auth_buffer = hexmem(text, l);
555 if (b->negotiate_fds)
556 auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
558 auth_suffix = "\r\nBEGIN\r\n";
560 b->auth_iovec[0].iov_base = (void*) auth_prefix;
561 b->auth_iovec[0].iov_len = 1 + strlen(auth_prefix + 1);
562 b->auth_iovec[1].iov_base = (void*) b->auth_buffer;
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);
567 return bus_socket_write_auth(b);
570 static int bus_socket_start_auth(sd_bus *b) {
576 b->state = BUS_AUTHENTICATING;
577 b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
580 r = getsockopt(b->input_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
581 if (r < 0 || domain != AF_UNIX)
582 b->negotiate_fds = false;
584 if (b->output_fd != b->input_fd) {
585 r = getsockopt(b->output_fd, SOL_SOCKET, SO_DOMAIN, &domain, &sl);
586 if (r < 0 || domain != AF_UNIX)
587 b->negotiate_fds = false;
592 return bus_socket_read_auth(b);
594 return bus_socket_start_auth_client(b);
597 int bus_socket_connect(sd_bus *b) {
601 assert(b->input_fd < 0);
602 assert(b->output_fd < 0);
603 assert(b->sockaddr.sa.sa_family != AF_UNSPEC);
605 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
609 b->output_fd = b->input_fd;
611 r = bus_socket_setup(b);
615 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
617 if (errno == EINPROGRESS)
623 return bus_socket_start_auth(b);
626 int bus_socket_exec(sd_bus *b) {
631 assert(b->input_fd < 0);
632 assert(b->output_fd < 0);
633 assert(b->exec_path);
635 r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
647 reset_all_signal_handlers();
649 close_all_fds(s+1, 1);
651 assert_se(dup3(s[1], STDIN_FILENO, 0) == STDIN_FILENO);
652 assert_se(dup3(s[1], STDOUT_FILENO, 0) == STDOUT_FILENO);
654 if (s[1] != STDIN_FILENO && s[1] != STDOUT_FILENO)
655 close_nointr_nofail(s[1]);
657 fd_cloexec(STDIN_FILENO, false);
658 fd_cloexec(STDOUT_FILENO, false);
659 fd_nonblock(STDIN_FILENO, false);
660 fd_nonblock(STDOUT_FILENO, false);
663 execvp(b->exec_path, b->exec_argv);
665 const char *argv[] = { b->exec_path, NULL };
666 execvp(b->exec_path, (char**) argv);
672 close_nointr_nofail(s[1]);
673 b->output_fd = b->input_fd = s[0];
675 return bus_socket_start_auth(b);
678 int bus_socket_take_fd(sd_bus *b) {
682 r = bus_socket_setup(b);
686 return bus_socket_start_auth(b);
689 int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
699 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
706 struct cmsghdr *control;
707 control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
709 mh.msg_control = control;
710 control->cmsg_level = SOL_SOCKET;
711 control->cmsg_type = SCM_RIGHTS;
712 mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
713 memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
716 n = m->n_iovec * sizeof(struct iovec);
718 memcpy(iov, m->iovec, n);
721 iovec_advance(iov, &j, *idx);
724 mh.msg_iovlen = m->n_iovec;
726 k = sendmsg(bus->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
728 return errno == EAGAIN ? 0 : -errno;
734 static int bus_socket_read_message_need(sd_bus *bus, size_t *need) {
741 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
743 if (bus->rbuffer_size < sizeof(struct bus_header)) {
744 *need = sizeof(struct bus_header) + 8;
746 /* Minimum message size:
750 * Method Call: +2 string headers
751 * Signal: +3 string headers
752 * Method Error: +1 string headers
754 * Method Reply: +1 uint32 headers
756 * A string header is at least 9 bytes
757 * A uint32 header is at least 8 bytes
759 * Hence the minimum message size of a valid message
760 * is header + 8 bytes */
765 a = ((const uint32_t*) bus->rbuffer)[1];
766 b = ((const uint32_t*) bus->rbuffer)[3];
768 e = ((const uint8_t*) bus->rbuffer)[0];
769 if (e == SD_BUS_LITTLE_ENDIAN) {
772 } else if (e == SD_BUS_BIG_ENDIAN) {
778 sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
779 if (sum >= BUS_MESSAGE_SIZE_MAX)
782 *need = (size_t) sum;
786 static int bus_socket_make_message(sd_bus *bus, size_t size, sd_bus_message **m) {
793 assert(bus->rbuffer_size >= size);
794 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
796 if (bus->rbuffer_size > size) {
797 b = memdup((const uint8_t*) bus->rbuffer + size,
798 bus->rbuffer_size - size);
804 r = bus_message_from_malloc(bus->rbuffer, size,
805 bus->fds, bus->n_fds,
806 bus->ucred_valid ? &bus->ucred : NULL,
807 bus->label[0] ? bus->label : NULL,
815 bus->rbuffer_size -= size;
824 int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) {
832 struct cmsghdr cmsghdr;
833 uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX) +
834 CMSG_SPACE(sizeof(struct ucred)) +
835 CMSG_SPACE(NAME_MAX)]; /*selinux label */
837 struct cmsghdr *cmsg;
841 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
843 r = bus_socket_read_message_need(bus, &need);
847 if (bus->rbuffer_size >= need)
848 return bus_socket_make_message(bus, need, m);
850 b = realloc(bus->rbuffer, need);
857 iov.iov_base = (uint8_t*) bus->rbuffer + bus->rbuffer_size;
858 iov.iov_len = need - bus->rbuffer_size;
863 mh.msg_control = &control;
864 mh.msg_controllen = sizeof(control);
866 k = recvmsg(bus->input_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
868 return errno == EAGAIN ? 0 : -errno;
872 bus->rbuffer_size += k;
874 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
875 if (cmsg->cmsg_level == SOL_SOCKET &&
876 cmsg->cmsg_type == SCM_RIGHTS) {
879 n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
882 /* Whut? We received fds but this
883 * isn't actually enabled? Close them,
886 close_many((int*) CMSG_DATA(cmsg), n);
890 f = realloc(bus->fds, sizeof(int) + (bus->n_fds + n));
892 close_many((int*) CMSG_DATA(cmsg), n);
896 memcpy(f + bus->n_fds, CMSG_DATA(cmsg), n * sizeof(int));
899 } else if (cmsg->cmsg_level == SOL_SOCKET &&
900 cmsg->cmsg_type == SCM_CREDENTIALS &&
901 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
903 memcpy(&bus->ucred, CMSG_DATA(cmsg), sizeof(struct ucred));
904 bus->ucred_valid = true;
906 } else if (cmsg->cmsg_level == SOL_SOCKET &&
907 cmsg->cmsg_type == SCM_SECURITY) {
910 l = cmsg->cmsg_len - CMSG_LEN(0);
911 memcpy(&bus->label, CMSG_DATA(cmsg), l);
916 r = bus_socket_read_message_need(bus, &need);
920 if (bus->rbuffer_size >= need)
921 return bus_socket_make_message(bus, need, m);
926 int bus_socket_process_opening(sd_bus *b) {
928 socklen_t slen = sizeof(error);
933 assert(b->state == BUS_OPENING);
943 if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
946 r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
948 b->last_connect_error = errno;
950 b->last_connect_error = error;
951 else if (p.revents & (POLLERR|POLLHUP))
952 b->last_connect_error = ECONNREFUSED;
954 return bus_socket_start_auth(b);
956 return bus_next_address(b);
959 int bus_socket_process_authenticating(sd_bus *b) {
963 assert(b->state == BUS_AUTHENTICATING);
965 if (now(CLOCK_MONOTONIC) >= b->auth_timeout)
968 r = bus_socket_write_auth(b);
972 return bus_socket_read_auth(b);