Implemented proper query response on server side

The server now checks the host database and responds correctly, but the
client still does not know how to get that response.
This commit is contained in:
Johannes Bauer 2019-10-25 10:21:29 +02:00
parent 8c7c0e5870
commit 05e112065e
8 changed files with 52 additions and 28 deletions

View File

@ -15,6 +15,7 @@ OBJS := \
argparse_client.o \ argparse_client.o \
argparse_edit.o \ argparse_edit.o \
argparse_server.o \ argparse_server.o \
blacklist.o \
client.o \ client.o \
editor.o \ editor.o \
file_encryption.o \ file_encryption.o \

View File

@ -1,6 +1,6 @@
/* /*
luksrku - Tool to remotely unlock LUKS disks using TLS. luksrku - Tool to remotely unlock LUKS disks using TLS.
Copyright (C) 2016-2016 Johannes Bauer Copyright (C) 2016-2019 Johannes Bauer
This file is part of luksrku. This file is part of luksrku.
@ -30,25 +30,23 @@
static struct blacklist_entry_t blacklist[BLACKLIST_ENTRY_COUNT]; static struct blacklist_entry_t blacklist[BLACKLIST_ENTRY_COUNT];
static double gettime(void) { static double now(void) {
struct timeval tv; struct timeval tv;
if (gettimeofday(&tv, NULL)) { if (gettimeofday(&tv, NULL)) {
return 0; return 0;
} }
double now = tv.tv_sec + (tv.tv_usec * 1e-6); return tv.tv_sec + (tv.tv_usec * 1e-6);
return now;
} }
static bool blacklist_entry_expired(int index) { static bool blacklist_entry_expired(int index) {
double now = gettime(); return now() > blacklist[index].entered + BLACKLIST_ENTRY_TIMEOUT_SECS;
return now > blacklist[index].entered + BLACKLIST_ENTRY_TIMEOUT_SECS;
} }
void blacklist_ip(uint32_t ip) { void blacklist_ip(uint32_t ip) {
for (int i = 0; i < BLACKLIST_ENTRY_COUNT; i++) { for (int i = 0; i < BLACKLIST_ENTRY_COUNT; i++) {
if (blacklist_entry_expired(i)) { if (blacklist_entry_expired(i)) {
blacklist[i].ip = ip; blacklist[i].ip = ip;
blacklist[i].entered = gettime(); blacklist[i].entered = now();
return; return;
} }
} }
@ -62,4 +60,3 @@ bool is_ip_blacklisted(uint32_t ip) {
} }
return false; return false;
} }

View File

@ -1,6 +1,6 @@
/* /*
luksrku - Tool to remotely unlock LUKS disks using TLS. luksrku - Tool to remotely unlock LUKS disks using TLS.
Copyright (C) 2016-2016 Johannes Bauer Copyright (C) 2016-2019 Johannes Bauer
This file is part of luksrku. This file is part of luksrku.
@ -27,6 +27,9 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define BLACKLIST_ENTRY_COUNT 32
#define BLACKLIST_ENTRY_TIMEOUT_SECS 60
struct blacklist_entry_t { struct blacklist_entry_t {
uint32_t ip; uint32_t ip;
double entered; double entered;

View File

@ -51,9 +51,6 @@
/* In what interval the server should broadcast that it's waiting for unlocking */ /* In what interval the server should broadcast that it's waiting for unlocking */
#define WAITING_MESSAGE_BROADCAST_INTERVAL_MILLISECONDS 1000 #define WAITING_MESSAGE_BROADCAST_INTERVAL_MILLISECONDS 1000
#define BLACKLIST_ENTRY_COUNT 16
#define BLACKLIST_ENTRY_TIMEOUT_SECS 120
#define staticassert(cond) _Static_assert((cond), #cond) #define staticassert(cond) _Static_assert((cond), #cond)
#endif #endif

View File

@ -48,6 +48,7 @@
#include "keydb.h" #include "keydb.h"
#include "signals.h" #include "signals.h"
#include "udp.h" #include "udp.h"
#include "blacklist.h"
struct keyserver_t { struct keyserver_t {
struct keydb_t* keydb; struct keydb_t* keydb;
@ -178,7 +179,23 @@ static void udp_handler_thread(void *vctx) {
if (!wait_udp_query(client->udp_sd, client->port, &rx_msg, &origin, 1000)) { if (!wait_udp_query(client->udp_sd, client->port, &rx_msg, &origin, 1000)) {
continue; continue;
} }
fprintf(stderr, "RXED! query\n");
log_msg(LLVL_TRACE, "Recevied UDP query message from %d.%d.%d.%d:%d", PRINTF_FORMAT_IP(&origin), ntohs(origin.sin_port));
/* Ensure that we only reply to this host once every minute */
const uint32_t ipv4 = origin.sin_addr.s_addr;
if (is_ip_blacklisted(ipv4)) {
continue;
}
blacklist_ip(ipv4);
/* Check if we have this host in our database */
if (keydb_get_host_by_uuid(client->keydb, rx_msg.host_uuid)) {
/* Yes, it is. Notify the client who's asking that we have their key. */
struct udp_response_t tx_msg;
memcpy(tx_msg.magic, UDP_MESSAGE_MAGIC, UDP_MESSAGE_MAGIC_SIZE);
send_udp_message(client->udp_sd, &origin, &tx_msg, sizeof(tx_msg), true);
}
} }
} }

34
udp.c
View File

@ -62,26 +62,34 @@ int create_udp_socket(unsigned int listen_port, bool send_broadcast) {
return sd; return sd;
} }
bool wait_udp_message(int sd, int port, void *data, unsigned int max_length, struct sockaddr_in *source, unsigned int timeout_millis) { bool wait_udp_message(int sd, int port, void *data, unsigned int length, struct sockaddr_in *source, unsigned int timeout_millis) {
fprintf(stderr, "RECV...\n"); fprintf(stderr, "RECV...\n");
socklen_t socklen = sizeof(struct sockaddr_in); socklen_t socklen = sizeof(struct sockaddr_in);
ssize_t rx_bytes = recvfrom(sd,data, max_length, 0, (struct sockaddr*)source, &socklen); ssize_t rx_bytes = recvfrom(sd,data, length, 0, (struct sockaddr*)source, &socklen);
fprintf(stderr, "RECV %ld\n", rx_bytes); fprintf(stderr, "RECV %ld\n", rx_bytes);
return rx_bytes == length;
}
bool send_udp_message(int sd, struct sockaddr_in *destination, const void *data, unsigned int length, bool is_response) {
int flags = is_response ? MSG_CONFIRM : 0;
ssize_t tx_bytes = sendto(sd, data, length, flags, (struct sockaddr*)destination, sizeof(struct sockaddr_in));
if (tx_bytes < 0) {
log_libc(LLVL_ERROR, "Unable to sendto(2)");
return false;
} else if (tx_bytes != length) {
log_libc(LLVL_ERROR, "Unable to sendto(2) the complete message, %d bytes sent, but %u requested.", tx_bytes, length);
return false;
}
return true; return true;
} }
bool send_udp_broadcast_message(int sd, int port, const void *data, unsigned int length) { bool send_udp_broadcast_message(int sd, int port, const void *data, unsigned int length) {
struct sockaddr_in destination; struct sockaddr_in destination = {
memset(&destination, 0, sizeof(struct sockaddr_in)); .sin_family = AF_INET,
destination.sin_family = AF_INET; .sin_port = htons(port),
destination.sin_port = htons(port); .sin_addr.s_addr = htonl(INADDR_BROADCAST),
destination.sin_addr.s_addr = htonl(INADDR_BROADCAST); };
return send_udp_message(sd, &destination, data, length, false);
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;
} }
bool wait_udp_query(int sd, int port, struct udp_query_t *query, struct sockaddr_in *source, unsigned int timeout_millis) { bool wait_udp_query(int sd, int port, struct udp_query_t *query, struct sockaddr_in *source, unsigned int timeout_millis) {

3
udp.h
View File

@ -29,7 +29,8 @@
/*************** AUTO GENERATED SECTION FOLLOWS ***************/ /*************** AUTO GENERATED SECTION FOLLOWS ***************/
int create_udp_socket(unsigned int listen_port, bool send_broadcast); int create_udp_socket(unsigned int listen_port, bool send_broadcast);
bool wait_udp_message(int sd, int port, void *data, unsigned int max_length, struct sockaddr_in *source, unsigned int timeout_millis); bool wait_udp_message(int sd, int port, void *data, unsigned int length, struct sockaddr_in *source, unsigned int timeout_millis);
bool send_udp_message(int sd, struct sockaddr_in *destination, const void *data, unsigned int length, bool is_response);
bool send_udp_broadcast_message(int sd, int port, const void *data, unsigned int length); bool send_udp_broadcast_message(int sd, int port, const void *data, unsigned int length);
bool wait_udp_query(int sd, int port, struct udp_query_t *query, struct sockaddr_in *source, unsigned int timeout_millis); bool wait_udp_query(int sd, int port, struct udp_query_t *query, struct sockaddr_in *source, unsigned int timeout_millis);
/*************** AUTO GENERATED SECTION ENDS ***************/ /*************** AUTO GENERATED SECTION ENDS ***************/

2
util.h
View File

@ -28,7 +28,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define PRINTF_FORMAT_IP(saddrptr) (saddrptr->sin_addr.s_addr >> 0) & 0xff, (saddrptr->sin_addr.s_addr >> 8) & 0xff, (saddrptr->sin_addr.s_addr >> 16) & 0xff, (saddrptr->sin_addr.s_addr >> 24) & 0xff #define PRINTF_FORMAT_IP(saddrptr) ((saddrptr)->sin_addr.s_addr >> 0) & 0xff, ((saddrptr)->sin_addr.s_addr >> 8) & 0xff, ((saddrptr)->sin_addr.s_addr >> 16) & 0xff, ((saddrptr)->sin_addr.s_addr >> 24) & 0xff
/*************** AUTO GENERATED SECTION FOLLOWS ***************/ /*************** AUTO GENERATED SECTION FOLLOWS ***************/
bool query_passphrase(const char *prompt, char *passphrase, unsigned int passphrase_maxsize); bool query_passphrase(const char *prompt, char *passphrase, unsigned int passphrase_maxsize);