Commit 2181a7f5 authored by Lennart Poettering's avatar Lennart Poettering

bus: implement server mode, and anonymous authentication

parent a3de5ae1
......@@ -1693,7 +1693,8 @@ noinst_LTLIBRARIES += \
noinst_tests += \
test-bus-marshal \
test-bus-signature \
test-bus-chat
test-bus-chat \
test-bus-server
noinst_PROGRAMS += \
busctl
......@@ -1731,6 +1732,18 @@ test_bus_chat_LDADD = \
libsystemd-bus.la \
libsystemd-id128-internal.la
test_bus_server_SOURCES = \
src/libsystemd-bus/test-bus-server.c
test_bus_server_CFLAGS = \
$(AM_CFLAGS) \
-pthread
test_bus_server_LDADD = \
libsystemd-shared.la \
libsystemd-bus.la \
libsystemd-id128-internal.la
busctl_SOURCES = \
src/libsystemd-bus/busctl.c
......
......@@ -64,6 +64,12 @@ enum bus_state {
BUS_RUNNING
};
enum bus_auth {
_BUS_AUTH_INVALID,
BUS_AUTH_EXTERNAL,
BUS_AUTH_ANONYMOUS
};
struct sd_bus {
unsigned n_ref;
enum bus_state state;
......@@ -74,6 +80,8 @@ struct sd_bus {
bool can_fds:1;
bool bus_client:1;
bool ucred_valid:1;
bool is_server:1;
bool anonymous_auth:1;
void *rbuffer;
size_t rbuffer_size;
......@@ -109,10 +117,11 @@ struct sd_bus {
int last_connect_error;
enum bus_auth auth;
size_t auth_rbegin;
struct iovec auth_iovec[3];
unsigned auth_index;
size_t auth_size;
char *auth_uid;
char *auth_buffer;
usec_t auth_timeout;
struct ucred ucred;
......
This diff is collapsed.
......@@ -32,3 +32,5 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m);
int bus_socket_process_opening(sd_bus *b);
int bus_socket_process_authenticating(sd_bus *b);
bool bus_socket_auth_needs_write(sd_bus *b);
......@@ -52,7 +52,7 @@ static void bus_free(sd_bus *b) {
free(b->rbuffer);
free(b->unique_name);
free(b->auth_uid);
free(b->auth_buffer);
free(b->address);
free(b->exec_path);
......@@ -197,6 +197,29 @@ int sd_bus_set_negotiate_fds(sd_bus *bus, int b) {
return 0;
}
int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server) {
if (!bus)
return -EINVAL;
if (!b && !sd_id128_equal(server, SD_ID128_NULL))
return -EINVAL;
if (bus->state != BUS_UNSET)
return -EPERM;
bus->is_server = !!b;
bus->peer = server;
return 0;
}
int sd_bus_set_anonymous(sd_bus *bus, int b) {
if (!bus)
return -EINVAL;
if (bus->state != BUS_UNSET)
return -EPERM;
bus->anonymous_auth = !!b;
return 0;
}
static int hello_callback(sd_bus *bus, int error, sd_bus_message *reply, void *userdata) {
const char *s;
int r;
......@@ -716,6 +739,9 @@ int sd_bus_start(sd_bus *bus) {
bus->state = BUS_OPENING;
if (bus->is_server && bus->bus_client)
return -EINVAL;
if (bus->fd >= 0)
r = bus_start_fd(bus);
else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path)
......@@ -1350,7 +1376,7 @@ int sd_bus_get_events(sd_bus *bus) {
flags |= POLLOUT;
else if (bus->state == BUS_AUTHENTICATING) {
if (bus->auth_index < ELEMENTSOF(bus->auth_iovec))
if (bus_socket_auth_needs_write(bus))
flags |= POLLOUT;
flags |= POLLIN;
......@@ -1426,8 +1452,8 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) {
/* Let's make sure the first message on the bus is the HELLO
* reply. But note that we don't actually parse the message
* here (we leave that to the usual reply handling), we just
* verify we don't let any earlier msg through. */
* here (we leave that to the usual handling), we just verify
* we don't let any earlier msg through. */
if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_RETURN &&
m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
......
......@@ -33,9 +33,7 @@ extern "C" {
#endif
/* TODO:
* - server side
* - allow installing match callbacks
* - anonymous auth
*
* Later:
* - add page donation logic
......@@ -66,6 +64,8 @@ int sd_bus_set_fd(sd_bus *bus, int fd);
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_negotiate_fds(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_start(sd_bus *ret);
void sd_bus_close(sd_bus *bus);
......
......@@ -564,9 +564,15 @@ int main(int argc, char *argv[]) {
q = pthread_join(c1, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
q = pthread_join(c2, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
if (r < 0)
return EXIT_FAILURE;
......
......@@ -1069,6 +1069,32 @@ char *hexmem(const void *p, size_t l) {
return r;
}
void *unhexmem(const char *p, size_t l) {
uint8_t *r, *z;
const char *x;
assert(p);
z = r = malloc((l + 1) / 2 + 1);
if (!r)
return NULL;
for (x = p; x < p + l; x += 2) {
int a, b;
a = unhexchar(x[0]);
if (x+1 < p + l)
b = unhexchar(x[1]);
else
b = 0;
*(z++) = (uint8_t) a << 4 | (uint8_t) b;
}
*z = 0;
return r;
}
char octchar(int x) {
return '0' + (x & 7);
}
......
......@@ -609,5 +609,7 @@ static inline void *mempset(void *s, int c, size_t n) {
}
char *hexmem(const void *p, size_t l);
void *unhexmem(const char *p, size_t l);
char *strextend(char **x, ...);
char *strrep(const char *s, unsigned n);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment