diff --git a/src/kdbus.c b/src/kdbus.c index 1d0052a5..7526c3a8 100644 --- a/src/kdbus.c +++ b/src/kdbus.c @@ -33,8 +33,13 @@ #include "linux/kdbus.h" #include "src/kdbus.h" +#define POOL_SIZE (16 * 1024LU * 1024LU) + static int kdbus_control = -1; +static int kdbus_conn = -1; +static uint8_t kdbus_id128[16]; + bool kdbus_create_bus(void) { struct { @@ -71,7 +76,7 @@ bool kdbus_create_bus(void) "%u-iwd", getuid()); bus_make.name_size = 16 + strlen(bus_make.name_param) + 1; bus_make.name_type = KDBUS_ITEM_MAKE_NAME; - + /* bus make head */ bus_make.head.size = sizeof(bus_make.head) + bus_make.bloom_size + bus_make.name_size; bus_make.head.flags = KDBUS_MAKE_ACCESS_WORLD; @@ -93,6 +98,13 @@ bool kdbus_destroy_bus(void) if (kdbus_control < 0) return false; + if (kdbus_conn >= 0) { + l_debug("Closing bus endpoint"); + + close(kdbus_conn); + kdbus_conn = -1; + } + l_debug("Closing kdbus control interface"); close(kdbus_control); @@ -123,3 +135,115 @@ char *kdbus_lookup_bus(void) return path; } + +static bool name_acquire(const char *name) +{ + struct { + struct kdbus_cmd_name head; + char param[64]; + } cmd_name; + + if (!name) + return true; + + memset(&cmd_name, 0, sizeof(cmd_name)); + /* cmd name head */ + snprintf(cmd_name.param, sizeof(cmd_name.param), "%s", name); + cmd_name.head.size = sizeof(cmd_name.head) + strlen(cmd_name.param) + 1; + + l_debug("Aquiring name %s", cmd_name.param); + + if (ioctl(kdbus_conn, KDBUS_CMD_NAME_ACQUIRE, &cmd_name) < 0) { + l_error("Failed to acquire name: %m"); + return false; + } + + return true; +} + +bool kdbus_open_bus(const char *path, const char *name, const char *conn_name) +{ + struct { + struct kdbus_cmd_hello head; + /* conn name item */ + uint64_t name_size; + uint64_t name_type; + char name_param[16]; + } cmd_hello; + + if (kdbus_conn >= 0) + return false; + + l_debug("Opening %s", path); + + kdbus_conn = open(path, O_RDWR | O_CLOEXEC); + if (kdbus_conn < 0) { + l_error("Failed to open bus endpoint: %m"); + return false; + } + + memset(&cmd_hello, 0, sizeof(cmd_hello)); + /* conn name item */ + snprintf(cmd_hello.name_param, sizeof(cmd_hello.name_param), + "%s", conn_name); + cmd_hello.name_size = 16 + strlen(cmd_hello.name_param) + 1; + cmd_hello.name_type = KDBUS_ITEM_CONN_NAME; + /* cmd hello head */ + cmd_hello.head.size = sizeof(cmd_hello.head) + cmd_hello.name_size; + cmd_hello.head.conn_flags = KDBUS_HELLO_ACCEPT_FD; + cmd_hello.head.attach_flags = KDBUS_ATTACH_TIMESTAMP | + KDBUS_ATTACH_CREDS | + KDBUS_ATTACH_NAMES | + KDBUS_ATTACH_COMM | + KDBUS_ATTACH_EXE | + KDBUS_ATTACH_CMDLINE | + KDBUS_ATTACH_CAPS | + KDBUS_ATTACH_CGROUP | + KDBUS_ATTACH_SECLABEL | + KDBUS_ATTACH_AUDIT | + KDBUS_ATTACH_CONN_NAME; + cmd_hello.head.pool_size = POOL_SIZE; + + l_debug("Sending hello message for %s", cmd_hello.name_param); + + if (ioctl(kdbus_conn, KDBUS_CMD_HELLO, &cmd_hello) < 0) { + l_error("Failed to send hello: %m"); + close(kdbus_conn); + kdbus_conn = -1; + return false; + } + + memcpy(kdbus_id128, cmd_hello.head.id128, sizeof(kdbus_id128)); + + l_debug("UUID: %02x%02x%02x%02x-%02x%02x%02x%02x-" + "%02x%02x%02x%02x-%02x%02x%02x%02x", + kdbus_id128[0], kdbus_id128[1], + kdbus_id128[2], kdbus_id128[3], + kdbus_id128[4], kdbus_id128[5], + kdbus_id128[6], kdbus_id128[7], + kdbus_id128[8], kdbus_id128[9], + kdbus_id128[10], kdbus_id128[11], + kdbus_id128[12], kdbus_id128[13], + kdbus_id128[14], kdbus_id128[15]); + + if (!name_acquire(name)) { + close(kdbus_conn); + kdbus_conn = -1; + return false; + } + + return true; +}; + +bool kdbus_close_bus(void) +{ + if (kdbus_conn < 0) + return false; + + l_debug("Closing bus endpoint"); + + close(kdbus_conn); + kdbus_conn = -1; + + return true; +} diff --git a/src/kdbus.h b/src/kdbus.h index a704cab7..e0ef54d4 100644 --- a/src/kdbus.h +++ b/src/kdbus.h @@ -26,3 +26,5 @@ bool kdbus_create_bus(void); bool kdbus_destroy_bus(void); char *kdbus_lookup_bus(void); +bool kdbus_open_bus(const char *path, const char *name, const char *conn_name); +bool kdbus_close_bus(void);