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/>.
35 #include "bus-socket.h"
36 #include "bus-internal.h"
37 #include "bus-message.h"
39 static void iovec_advance(struct iovec
*iov
, unsigned *idx
, size_t size
) {
42 struct iovec
*i
= iov
+ *idx
;
44 if (i
->iov_len
> size
) {
45 i
->iov_base
= (uint8_t*) i
->iov_base
+ size
;
59 static int bus_socket_write_auth(sd_bus
*b
) {
64 assert(b
->state
== BUS_AUTHENTICATING
);
66 if (b
->auth_index
>= ELEMENTSOF(b
->auth_iovec
))
69 if (b
->auth_timeout
== 0)
70 b
->auth_timeout
= now(CLOCK_MONOTONIC
) + BUS_DEFAULT_TIMEOUT
;
73 mh
.msg_iov
= b
->auth_iovec
+ b
->auth_index
;
74 mh
.msg_iovlen
= ELEMENTSOF(b
->auth_iovec
) - b
->auth_index
;
76 k
= sendmsg(b
->fd
, &mh
, MSG_DONTWAIT
|MSG_NOSIGNAL
);
78 return errno
== EAGAIN
? 0 : -errno
;
80 iovec_advance(b
->auth_iovec
, &b
->auth_index
, (size_t) k
);
85 static int bus_socket_auth_verify(sd_bus
*b
) {
91 /* We expect two response lines: "OK" and possibly
94 e
= memmem(b
->rbuffer
, b
->rbuffer_size
, "\r\n", 2);
98 if (b
->negotiate_fds
) {
99 f
= memmem(e
+ 2, b
->rbuffer_size
- (e
- (char*) b
->rbuffer
) - 2, "\r\n", 2);
109 /* Nice! We got all the lines we need. First check the OK
112 if (e
- (char*) b
->rbuffer
!= 3 + 32)
115 if (memcmp(b
->rbuffer
, "OK ", 3))
118 for (i
= 0; i
< 32; i
+= 2) {
121 x
= unhexchar(((char*) b
->rbuffer
)[3 + i
]);
122 y
= unhexchar(((char*) b
->rbuffer
)[3 + i
+ 1]);
127 peer
.bytes
[i
/2] = ((uint8_t) x
<< 4 | (uint8_t) y
);
130 if (!sd_id128_equal(b
->peer
, SD_ID128_NULL
) &&
131 !sd_id128_equal(b
->peer
, peer
))
136 /* And possibly check the second line, too */
140 (f
- e
== sizeof("\r\nAGREE_UNIX_FD") - 1) &&
141 memcmp(e
+ 2, "AGREE_UNIX_FD", sizeof("AGREE_UNIX_FD") - 1) == 0;
143 b
->rbuffer_size
-= (start
- (char*) b
->rbuffer
);
144 memmove(b
->rbuffer
, start
, b
->rbuffer_size
);
146 r
= bus_start_running(b
);
153 static int bus_socket_read_auth(sd_bus
*b
) {
163 r
= bus_socket_auth_verify(b
);
167 n
= MAX(3 + 32 + 2 + sizeof("AGREE_UNIX_FD") - 1 + 2, b
->rbuffer_size
* 2);
169 if (n
> BUS_AUTH_SIZE_MAX
)
170 n
= BUS_AUTH_SIZE_MAX
;
172 if (b
->rbuffer_size
>= n
)
175 p
= realloc(b
->rbuffer
, n
);
182 iov
.iov_base
= (uint8_t*) b
->rbuffer
+ b
->rbuffer_size
;
183 iov
.iov_len
= n
- b
->rbuffer_size
;
189 k
= recvmsg(b
->fd
, &mh
, MSG_DONTWAIT
|MSG_NOSIGNAL
);
191 return errno
== EAGAIN
? 0 : -errno
;
195 b
->rbuffer_size
+= k
;
197 r
= bus_socket_auth_verify(b
);
204 static int bus_socket_setup(sd_bus
*b
) {
209 /* Enable SO_PASSCRED + SO_PASSEC. We try this on any socket,
210 * just in case. This is actually irrelavant for */
212 setsockopt(b
->fd
, SOL_SOCKET
, SO_PASSCRED
, &one
, sizeof(one
));
213 setsockopt(b
->fd
, SOL_SOCKET
, SO_PASSSEC
, &one
, sizeof(one
));
215 /* Increase the buffers to a MB */
216 fd_inc_rcvbuf(b
->fd
, 1024*1024);
217 fd_inc_sndbuf(b
->fd
, 1024*1024);
222 static 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";
227 char text
[20 + 1]; /* enough space for a 64bit integer plus NUL */
229 const char *auth_suffix
;
235 b
->state
= BUS_AUTHENTICATING
;
238 r
= getsockopt(b
->fd
, SOL_SOCKET
, SO_DOMAIN
, &domain
, &sl
);
242 if (domain
!= AF_UNIX
)
243 b
->negotiate_fds
= false;
245 snprintf(text
, sizeof(text
), "%llu", (unsigned long long) geteuid());
249 b
->auth_uid
= hexmem(text
, l
);
253 auth_suffix
= b
->negotiate_fds
? auth_suffix_with_unix_fd
: auth_suffix_without_unix_fd
;
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;
263 return bus_socket_write_auth(b
);
266 int bus_socket_connect(sd_bus
*b
) {
271 assert(b
->sockaddr
.sa
.sa_family
!= AF_UNSPEC
);
273 b
->fd
= socket(b
->sockaddr
.sa
.sa_family
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
277 r
= bus_socket_setup(b
);
281 r
= connect(b
->fd
, &b
->sockaddr
.sa
, b
->sockaddr_size
);
283 if (errno
== EINPROGRESS
)
289 return bus_socket_start_auth(b
);
292 int bus_socket_exec(sd_bus
*b
) {
298 assert(b
->exec_path
);
300 b
->fd
= socketpair(AF_UNIX
, SOCK_STREAM
|SOCK_NONBLOCK
|SOCK_CLOEXEC
, 0, s
);
313 close_nointr_nofail(s
[0]);
315 assert_se(dup3(s
[1], STDIN_FILENO
, 0) == STDIN_FILENO
);
316 assert_se(dup3(s
[1], STDOUT_FILENO
, 0) == STDOUT_FILENO
);
318 if (s
[1] != STDIN_FILENO
&& s
[1] != STDOUT_FILENO
)
319 close_nointr_nofail(s
[1]);
321 fd_cloexec(STDIN_FILENO
, false);
322 fd_cloexec(STDOUT_FILENO
, false);
323 fd_nonblock(STDIN_FILENO
, false);
324 fd_nonblock(STDOUT_FILENO
, false);
327 execvp(b
->exec_path
, b
->exec_argv
);
329 const char *argv
[] = { b
->exec_path
, NULL
};
330 execvp(b
->exec_path
, (char**) argv
);
336 close_nointr_nofail(s
[1]);
339 return bus_socket_start_auth(b
);
342 int bus_socket_take_fd(sd_bus
*b
) {
346 r
= bus_socket_setup(b
);
350 return bus_socket_start_auth(b
);
353 int bus_socket_write_message(sd_bus
*bus
, sd_bus_message
*m
, size_t *idx
) {
363 assert(bus
->state
== BUS_RUNNING
|| bus
->state
== BUS_HELLO
);
370 struct cmsghdr
*control
;
371 control
= alloca(CMSG_SPACE(sizeof(int) * m
->n_fds
));
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
);
380 n
= m
->n_iovec
* sizeof(struct iovec
);
382 memcpy(iov
, m
->iovec
, n
);
385 iovec_advance(iov
, &j
, *idx
);
388 mh
.msg_iovlen
= m
->n_iovec
;
390 k
= sendmsg(bus
->fd
, &mh
, MSG_DONTWAIT
|MSG_NOSIGNAL
);
392 return errno
== EAGAIN
? 0 : -errno
;
398 static int bus_socket_read_message_need(sd_bus
*bus
, size_t *need
) {
405 assert(bus
->state
== BUS_RUNNING
|| bus
->state
== BUS_HELLO
);
407 if (bus
->rbuffer_size
< sizeof(struct bus_header
)) {
408 *need
= sizeof(struct bus_header
) + 8;
410 /* Minimum message size:
414 * Method Call: +2 string headers
415 * Signal: +3 string headers
416 * Method Error: +1 string headers
418 * Method Reply: +1 uint32 headers
420 * A string header is at least 9 bytes
421 * A uint32 header is at least 8 bytes
423 * Hence the minimum message size of a valid message
424 * is header + 8 bytes */
429 a
= ((const uint32_t*) bus
->rbuffer
)[1];
430 b
= ((const uint32_t*) bus
->rbuffer
)[3];
432 e
= ((const uint8_t*) bus
->rbuffer
)[0];
433 if (e
== SD_BUS_LITTLE_ENDIAN
) {
436 } else if (e
== SD_BUS_BIG_ENDIAN
) {
442 sum
= (uint64_t) sizeof(struct bus_header
) + (uint64_t) ALIGN_TO(b
, 8) + (uint64_t) a
;
443 if (sum
>= BUS_MESSAGE_SIZE_MAX
)
446 *need
= (size_t) sum
;
450 static int bus_socket_make_message(sd_bus
*bus
, size_t size
, sd_bus_message
**m
) {
457 assert(bus
->rbuffer_size
>= size
);
458 assert(bus
->state
== BUS_RUNNING
|| bus
->state
== BUS_HELLO
);
460 if (bus
->rbuffer_size
> size
) {
461 b
= memdup((const uint8_t*) bus
->rbuffer
+ size
,
462 bus
->rbuffer_size
- size
);
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
,
479 bus
->rbuffer_size
-= size
;
488 int bus_socket_read_message(sd_bus
*bus
, sd_bus_message
**m
) {
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 */
501 struct cmsghdr
*cmsg
;
505 assert(bus
->state
== BUS_RUNNING
|| bus
->state
== BUS_HELLO
);
507 r
= bus_socket_read_message_need(bus
, &need
);
511 if (bus
->rbuffer_size
>= need
)
512 return bus_socket_make_message(bus
, need
, m
);
514 b
= realloc(bus
->rbuffer
, need
);
521 iov
.iov_base
= (uint8_t*) bus
->rbuffer
+ bus
->rbuffer_size
;
522 iov
.iov_len
= need
- bus
->rbuffer_size
;
527 mh
.msg_control
= &control
;
528 mh
.msg_controllen
= sizeof(control
);
530 k
= recvmsg(bus
->fd
, &mh
, MSG_DONTWAIT
|MSG_NOSIGNAL
|MSG_CMSG_CLOEXEC
);
532 return errno
== EAGAIN
? 0 : -errno
;
536 bus
->rbuffer_size
+= k
;
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
) {
543 n
= (cmsg
->cmsg_len
- CMSG_LEN(0)) / sizeof(int);
545 f
= realloc(bus
->fds
, sizeof(int) + (bus
->n_fds
+ n
));
547 close_many((int*) CMSG_DATA(cmsg
), n
);
551 memcpy(f
+ bus
->n_fds
, CMSG_DATA(cmsg
), n
* sizeof(int));
554 } else if (cmsg
->cmsg_level
== SOL_SOCKET
&&
555 cmsg
->cmsg_type
== SCM_CREDENTIALS
&&
556 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct ucred
))) {
558 memcpy(&bus
->ucred
, CMSG_DATA(cmsg
), sizeof(struct ucred
));
559 bus
->ucred_valid
= true;
561 } else if (cmsg
->cmsg_level
== SOL_SOCKET
&&
562 cmsg
->cmsg_type
== SCM_SECURITY
) {
565 l
= cmsg
->cmsg_len
- CMSG_LEN(0);
566 memcpy(&bus
->label
, CMSG_DATA(cmsg
), l
);
571 r
= bus_socket_read_message_need(bus
, &need
);
575 if (bus
->rbuffer_size
>= need
)
576 return bus_socket_make_message(bus
, need
, m
);
581 int bus_socket_process_opening(sd_bus
*b
) {
583 socklen_t slen
= sizeof(error
);
588 assert(b
->state
== BUS_OPENING
);
598 if (!(p
.revents
& (POLLOUT
|POLLERR
|POLLHUP
)))
601 r
= getsockopt(b
->fd
, SOL_SOCKET
, SO_ERROR
, &error
, &slen
);
603 b
->last_connect_error
= errno
;
605 b
->last_connect_error
= error
;
606 else if (p
.revents
& (POLLERR
|POLLHUP
))
607 b
->last_connect_error
= ECONNREFUSED
;
609 return bus_socket_start_auth(b
);
611 return bus_next_address(b
);
614 int bus_socket_process_authenticating(sd_bus
*b
) {
618 assert(b
->state
== BUS_AUTHENTICATING
);
620 if (now(CLOCK_MONOTONIC
) >= b
->auth_timeout
)
623 r
= bus_socket_write_auth(b
);
627 return bus_socket_read_auth(b
);