mirror of
https://github.com/systemd/systemd.git
synced 2025-01-28 21:47:38 +03:00
bus: add APIs for negotiating what is attached to messages
This commit is contained in:
parent
45fbe937d7
commit
264ad849a4
2
TODO
2
TODO
@ -35,14 +35,12 @@ Features:
|
||||
* libsystemd-bus:
|
||||
- default policy (allow uid == 0 and our own uid)
|
||||
- enforce alignment of pointers passed in
|
||||
- negotiation for attach attributes
|
||||
- when kdbus doesn't take our message without memfds, try again with memfds
|
||||
- kdbus: generate correct bloom filter for matches
|
||||
- implement translator service
|
||||
- port systemd to new library
|
||||
- implement busname unit type in systemd
|
||||
- move to gvariant
|
||||
- keep the connection fds around as long as the bus is open
|
||||
- merge busctl into systemctl or so?
|
||||
- synthesize sd_bus_message objects from kernel messages
|
||||
|
||||
|
@ -99,7 +99,6 @@ struct sd_bus {
|
||||
int message_version;
|
||||
|
||||
bool is_kernel:1;
|
||||
bool negotiate_fds:1;
|
||||
bool can_fds:1;
|
||||
bool bus_client:1;
|
||||
bool ucred_valid:1;
|
||||
@ -181,6 +180,8 @@ struct sd_bus {
|
||||
unsigned n_memfd_cache;
|
||||
|
||||
pid_t original_pid;
|
||||
|
||||
uint64_t hello_flags;
|
||||
};
|
||||
|
||||
static inline void bus_unrefp(sd_bus **b) {
|
||||
|
@ -345,15 +345,7 @@ int bus_kernel_take_fd(sd_bus *b) {
|
||||
}
|
||||
|
||||
hello->size = sizeof(h);
|
||||
hello->conn_flags =
|
||||
KDBUS_HELLO_ACCEPT_FD|
|
||||
KDBUS_HELLO_ATTACH_COMM|
|
||||
KDBUS_HELLO_ATTACH_EXE|
|
||||
KDBUS_HELLO_ATTACH_CMDLINE|
|
||||
KDBUS_HELLO_ATTACH_CGROUP|
|
||||
KDBUS_HELLO_ATTACH_CAPS|
|
||||
KDBUS_HELLO_ATTACH_SECLABEL|
|
||||
KDBUS_HELLO_ATTACH_AUDIT;
|
||||
hello->conn_flags = b->hello_flags;
|
||||
|
||||
hello->items[0].type = KDBUS_HELLO_POOL;
|
||||
hello->items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec);
|
||||
@ -378,7 +370,7 @@ int bus_kernel_take_fd(sd_bus *b) {
|
||||
|
||||
b->is_kernel = true;
|
||||
b->bus_client = true;
|
||||
b->can_fds = true;
|
||||
b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
|
||||
|
||||
r = bus_start_running(b);
|
||||
if (r < 0)
|
||||
|
@ -181,7 +181,7 @@ static int bus_socket_auth_verify_client(sd_bus *b) {
|
||||
if (!e)
|
||||
return 0;
|
||||
|
||||
if (b->negotiate_fds) {
|
||||
if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD) {
|
||||
f = memmem(e + 2, b->rbuffer_size - (e - (char*) b->rbuffer) - 2, "\r\n", 2);
|
||||
if (!f)
|
||||
return 0;
|
||||
@ -464,7 +464,7 @@ static int bus_socket_auth_verify_server(sd_bus *b) {
|
||||
r = bus_socket_auth_write_ok(b);
|
||||
}
|
||||
} else if (line_equals(line, l, "NEGOTIATE_UNIX_FD")) {
|
||||
if (b->auth == _BUS_AUTH_INVALID || !b->negotiate_fds)
|
||||
if (b->auth == _BUS_AUTH_INVALID || !(b->hello_flags & KDBUS_HELLO_ACCEPT_FD))
|
||||
r = bus_socket_auth_write(b, "ERROR\r\n");
|
||||
else {
|
||||
b->can_fds = true;
|
||||
@ -610,6 +610,8 @@ static int bus_socket_setup(sd_bus *b) {
|
||||
* socket, just in case. */
|
||||
enable = !b->bus_client;
|
||||
setsockopt(b->input_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable));
|
||||
|
||||
enable = !b->bus_client && (b->hello_flags & KDBUS_HELLO_ATTACH_SECLABEL);
|
||||
setsockopt(b->input_fd, SOL_SOCKET, SO_PASSSEC, &enable, sizeof(enable));
|
||||
|
||||
/* Increase the buffers to a MB */
|
||||
@ -651,7 +653,7 @@ static int bus_socket_start_auth_client(sd_bus *b) {
|
||||
if (!b->auth_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
if (b->negotiate_fds)
|
||||
if (b->hello_flags & KDBUS_HELLO_ACCEPT_FD)
|
||||
auth_suffix = "\r\nNEGOTIATE_UNIX_FD\r\nBEGIN\r\n";
|
||||
else
|
||||
auth_suffix = "\r\nBEGIN\r\n";
|
||||
@ -673,11 +675,11 @@ static int bus_socket_start_auth(sd_bus *b) {
|
||||
b->auth_timeout = now(CLOCK_MONOTONIC) + BUS_DEFAULT_TIMEOUT;
|
||||
|
||||
if (sd_is_socket(b->input_fd, AF_UNIX, 0, 0) <= 0)
|
||||
b->negotiate_fds = false;
|
||||
b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
|
||||
|
||||
if (b->output_fd != b->input_fd)
|
||||
if (sd_is_socket(b->output_fd, AF_UNIX, 0, 0) <= 0)
|
||||
b->negotiate_fds = false;
|
||||
b->hello_flags &= ~KDBUS_HELLO_ACCEPT_FD;
|
||||
|
||||
if (b->is_server)
|
||||
return bus_socket_read_auth(b);
|
||||
|
@ -125,7 +125,7 @@ int sd_bus_new(sd_bus **ret) {
|
||||
r->n_ref = REFCNT_INIT;
|
||||
r->input_fd = r->output_fd = -1;
|
||||
r->message_version = 1;
|
||||
r->negotiate_fds = true;
|
||||
r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
|
||||
r->original_pid = getpid();
|
||||
|
||||
assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
|
||||
@ -226,7 +226,7 @@ int sd_bus_set_bus_client(sd_bus *bus, int b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_set_negotiate_fds(sd_bus *bus, int b) {
|
||||
int sd_bus_negotiate_fds(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
@ -234,7 +234,91 @@ int sd_bus_set_negotiate_fds(sd_bus *bus, int b) {
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
bus->negotiate_fds = !!b;
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_comm(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_exe(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_caps(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_bus_negotiate_attach_audit(sd_bus *bus, int b) {
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (bus->state != BUS_UNSET)
|
||||
return -EPERM;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1015,7 +1099,7 @@ int sd_bus_can_send(sd_bus *bus, char type) {
|
||||
return -ECHILD;
|
||||
|
||||
if (type == SD_BUS_TYPE_UNIX_FD) {
|
||||
if (!bus->negotiate_fds)
|
||||
if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
|
||||
return 0;
|
||||
|
||||
r = bus_ensure_running(bus);
|
||||
|
@ -60,6 +60,22 @@ int main(int argc, char *argv[]) {
|
||||
r = sd_bus_set_address(b, address);
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_se(sd_bus_negotiate_attach_comm(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_exe(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cmdline(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cgroup(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_caps(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_selinux_context(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_audit(a, 1) >= 0);
|
||||
|
||||
assert_se(sd_bus_negotiate_attach_comm(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_exe(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cmdline(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cgroup(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_caps(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_selinux_context(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_audit(b, 1) >= 0);
|
||||
|
||||
r = sd_bus_start(a);
|
||||
assert_se(r >= 0);
|
||||
|
||||
|
@ -55,8 +55,8 @@ static void *server(void *p) {
|
||||
assert_se(sd_bus_new(&bus) >= 0);
|
||||
assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
|
||||
assert_se(sd_bus_set_server(bus, 1, id) >= 0);
|
||||
assert_se(sd_bus_set_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
|
||||
assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
|
||||
assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
|
||||
assert_se(sd_bus_start(bus) >= 0);
|
||||
|
||||
while (!quit) {
|
||||
@ -134,7 +134,7 @@ static int client(struct context *c) {
|
||||
|
||||
assert_se(sd_bus_new(&bus) >= 0);
|
||||
assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
|
||||
assert_se(sd_bus_set_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
|
||||
assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
|
||||
assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
|
||||
assert_se(sd_bus_start(bus) >= 0);
|
||||
|
||||
|
@ -284,4 +284,7 @@ do { \
|
||||
sizeof(type) <= 4 ? 10 : \
|
||||
sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
|
||||
|
||||
#define SET_FLAG(v, flag, b) \
|
||||
(v) = (b) ? ((v) | (flag)) : ((v) & ~(flag))
|
||||
|
||||
#include "log.h"
|
||||
|
@ -68,7 +68,7 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = sd_bus_set_negotiate_fds(a, is_unix);
|
||||
r = sd_bus_negotiate_fds(a, is_unix);
|
||||
if (r < 0) {
|
||||
log_error("Failed to set FD negotiation: %s", strerror(-r));
|
||||
goto finish;
|
||||
@ -104,7 +104,7 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = sd_bus_set_negotiate_fds(b, is_unix);
|
||||
r = sd_bus_negotiate_fds(b, is_unix);
|
||||
if (r < 0) {
|
||||
log_error("Failed to set FD negotiation: %s", strerror(-r));
|
||||
goto finish;
|
||||
|
@ -64,7 +64,14 @@ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]);
|
||||
int sd_bus_set_bus_client(sd_bus *bus, int b);
|
||||
int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id);
|
||||
int sd_bus_set_anonymous(sd_bus *bus, int b);
|
||||
int sd_bus_set_negotiate_fds(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_fds(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_comm(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_exe(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_caps(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_audit(sd_bus *bus, int b);
|
||||
int sd_bus_start(sd_bus *ret);
|
||||
|
||||
void sd_bus_close(sd_bus *bus);
|
||||
|
Loading…
x
Reference in New Issue
Block a user