diff --git a/client.c b/client.c index 425cb25..d38793f 100644 --- a/client.c +++ b/client.c @@ -152,6 +152,54 @@ static bool contact_keyserver_hostname(struct keyclient_t *keyclient, const char return success; } +static int create_udp_socket(void) { + int sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) { + log_libc(LLVL_ERROR, "Unable to create UDP server socket(2)"); + return -1; + } + { + int value = 1; + if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value))) { + log_libc(LLVL_ERROR, "Unable to set UDP socket in broadcast mode using setsockopt(2)"); + close(sd); + return -1; + } + } + return sd; +} + +static bool send_udp_broadcast_message(int sd, unsigned int port, const void *data, unsigned int length) { + struct sockaddr_in destination; + memset(&destination, 0, sizeof(struct sockaddr_in)); + destination.sin_family = AF_INET; + destination.sin_port = htons(port); + destination.sin_addr.s_addr = htonl(INADDR_BROADCAST); + + if (sendto(sd, data, length, 0, (struct sockaddr *)&destination, sizeof(struct sockaddr_in)) < 0) { + log_libc(LLVL_ERROR, "Unable to sendto(2)"); + return false; + } + return true; +} + + +static bool broadcast_for_keyserver(struct keyclient_t *keyclient) { + int sd = create_udp_socket(); + if (sd == -1) { + return false; + } + + struct udp_query_t query; + memcpy(query.magic, UDP_MESSAGE_MAGIC, sizeof(query.magic)); + memcpy(query.host_uuid, keyclient->keydb->hosts[0].host_uuid, 16); + while (true) { + send_udp_broadcast_message(sd, keyclient->opts->port, &query, sizeof(query)); + sleep(1); + } + return true; +} + bool keyclient_start(const struct pgmopts_client_t *opts) { /* Load key database first */ struct keyclient_t keyclient = { @@ -197,7 +245,11 @@ bool keyclient_start(const struct pgmopts_client_t *opts) { break; } } else { - /* TODO: Loop until keyserver found */ + if (!broadcast_for_keyserver(&keyclient)) { + log_msg(LLVL_ERROR, "Failed to find key server using UDP broadcast."); + success = false; + break; + } } } while (false); diff --git a/global.h b/global.h index ebc3b37..3d6541b 100644 --- a/global.h +++ b/global.h @@ -25,10 +25,9 @@ #define __GLOBAL_H__ /* Magic is the prefix of announcement packages. It is the MD5SUM over the - * CLIENT_PSK_IDENTITY. This only changes when the protocol that is spoken + * string "luksrku v2". This only changes when the protocol that is spoken * changes. */ -#define CLIENT_PSK_IDENTITY "luksrku v2" -#define CLIENT_ANNOUNCE_MAGIC { 0x46, 0xf2, 0xf6, 0xc6, 0x63, 0x12, 0x2e, 0x00, 0xa0, 0x8a, 0xae, 0x42, 0x0c, 0x51, 0xf5, 0x65 } +#define UDP_MESSAGE_MAGIC (const uint8_t[]){ 0x46, 0xf2, 0xf6, 0xc6, 0x63, 0x12, 0x2e, 0x00, 0xa0, 0x8a, 0xae, 0x42, 0x0c, 0x51, 0xf5, 0x65 } /* Size in bytes of the PSK that is used for TLS */ #define PSK_SIZE_BYTES 32 diff --git a/msg.h b/msg.h index 46d8a80..c937df4 100644 --- a/msg.h +++ b/msg.h @@ -27,11 +27,15 @@ #include #include "global.h" -struct announcement_t { +struct udp_query_t { uint8_t magic[16]; uint8_t host_uuid[16]; } __attribute__ ((packed)); +struct udp_response_t { + uint8_t magic[16]; +} __attribute__ ((packed)); + struct msg_t { uint8_t volume_uuid[16]; uint8_t luks_passphrase_raw[LUKS_PASSPHRASE_RAW_SIZE_BYTES];