Server implementation seems to work

Rudimentary functionality of server (not including responding to
announcements over UDP) is working now.
This commit is contained in:
Johannes Bauer 2019-10-23 15:56:06 +02:00
parent 3e5c7d541c
commit 603e63876f
4 changed files with 44 additions and 35 deletions

View File

@ -449,7 +449,7 @@ static enum cmd_returncode_t cmd_rawdump(struct editor_context_t *ctx, const cha
fprintf(stderr, " Host %d / Volume %d:\n", i, j);
dump_hexline(stderr, " volume_uuid ", volume->volume_uuid, sizeof(volume->volume_uuid), false);
dump_hexline(stderr, " devmapper_name ", volume->devmapper_name, sizeof(volume->devmapper_name), true);
dump_hexline(stderr, " luks_passphrase ", volume->luks_passphrase, sizeof(volume->luks_passphrase), false);
dump_hexline(stderr, " luks_passphrase ", volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw), false);
}
}
}

10
keydb.c
View File

@ -67,7 +67,7 @@ struct keydb_t* keydb_export_public(struct host_entry_t *host) {
/* But remove all LUKS passphrases of course, this is for the luksrku client */
for (unsigned int i = 0; i < host->volume_count; i++) {
struct volume_entry_t *volume = &public_host->volumes[i];
memset(volume->luks_passphrase, 0, sizeof(volume->luks_passphrase));
memset(volume->luks_passphrase_raw, 0, sizeof(volume->luks_passphrase_raw));
}
return public_db;
@ -188,8 +188,8 @@ struct volume_entry_t* keydb_add_volume(struct host_entry_t *host, const char *d
struct volume_entry_t *volume = &host->volumes[host->volume_count];
memcpy(volume->volume_uuid, volume_uuid, 16);
strncpy(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1);
if (!buffer_randomize(volume->luks_passphrase, sizeof(volume->luks_passphrase))) {
log_msg(LLVL_ERROR, "Failed to produce %d bytes of entropy for LUKS passphrase.", sizeof(volume->luks_passphrase));
if (!buffer_randomize(volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw))) {
log_msg(LLVL_ERROR, "Failed to produce %d bytes of entropy for LUKS passphrase.", sizeof(volume->luks_passphrase_raw));
return NULL;
}
host->volume_count++;
@ -211,11 +211,11 @@ bool keydb_del_volume(struct host_entry_t *host, const char *devmapper_name) {
}
bool keydb_rekey_volume(struct volume_entry_t *volume) {
return buffer_randomize(volume->luks_passphrase, sizeof(volume->luks_passphrase));
return buffer_randomize(volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw));
}
bool keydb_get_volume_luks_passphrase(const struct volume_entry_t *volume, char *dest, unsigned int dest_buffer_size) {
return ascii_encode(dest, dest_buffer_size, volume->luks_passphrase, sizeof(volume->luks_passphrase));
return ascii_encode(dest, dest_buffer_size, volume->luks_passphrase_raw, sizeof(volume->luks_passphrase_raw));
}
bool keydb_write(const struct keydb_t *keydb, const char *filename, const char *passphrase) {

16
keydb.h
View File

@ -33,17 +33,17 @@
#define KEYDB_VERSION 2
struct volume_entry_t {
uint8_t volume_uuid[16]; /* UUID of crypt_LUKS volume */
char devmapper_name[MAX_DEVMAPPER_NAME_LENGTH]; /* dmsetup name when unlocked. Zero-terminated string. */
uint8_t luks_passphrase[LUKS_PASSPHRASE_RAW_SIZE_BYTES]; /* LUKS passphrase used to unlock volume; raw byte data */
uint8_t volume_uuid[16]; /* UUID of crypt_LUKS volume */
char devmapper_name[MAX_DEVMAPPER_NAME_LENGTH]; /* dmsetup name when unlocked. Zero-terminated string. */
uint8_t luks_passphrase_raw[LUKS_PASSPHRASE_RAW_SIZE_BYTES]; /* LUKS passphrase used to unlock volume; raw byte data */
};
struct host_entry_t {
uint8_t host_uuid[16]; /* Host UUID */
char host_name[MAX_HOST_NAME_LENGTH]; /* Descriptive name of host */
uint8_t tls_psk[PSK_SIZE_BYTES]; /* Raw byte data of TLS-PSK that is used */
unsigned int volume_count; /* Number of volumes of this host */
struct volume_entry_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */
uint8_t host_uuid[16]; /* Host UUID */
char host_name[MAX_HOST_NAME_LENGTH]; /* Descriptive name of host */
uint8_t tls_psk[PSK_SIZE_BYTES]; /* Raw byte data of TLS-PSK that is used */
unsigned int volume_count; /* Number of volumes of this host */
struct volume_entry_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */
};
struct keydb_t {

View File

@ -305,8 +305,16 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned
}
#endif
struct client_ctx_t {
struct generic_tls_ctx_t *gctx;
const struct keydb_t *keydb;
const struct host_entry_t *host;
int fd;
};
static int psk_server_callback(SSL *ssl, const unsigned char *identity, size_t identity_len, SSL_SESSION **sessptr) {
const struct keydb_t *keydb = (const struct keydb_t*)SSL_get_default_passwd_cb_userdata(ssl);
struct client_ctx_t *ctx = (struct client_ctx_t*)SSL_get_app_data(ssl);
if (identity_len != ASCII_UUID_CHARACTER_COUNT) {
log_msg(LLVL_WARNING, "Received client identity of length %d, cannot be a UUID.", identity_len);
@ -327,8 +335,8 @@ static int psk_server_callback(SSL *ssl, const unsigned char *identity, size_t i
return 0;
}
const struct host_entry_t *host = keydb_get_host_by_uuid(keydb, uuid);
if (!host) {
ctx->host = keydb_get_host_by_uuid(ctx->keydb, uuid);
if (!ctx->host) {
log_msg(LLVL_WARNING, "Client connected with client UUID %s, but not present in key database.", uuid_str);
return 0;
}
@ -346,7 +354,7 @@ static int psk_server_callback(SSL *ssl, const unsigned char *identity, size_t i
return 0;
}
if (!SSL_SESSION_set1_master_key(sess, (const unsigned char*)"\x00\x11\x22", 3)) {
if (!SSL_SESSION_set1_master_key(sess, ctx->host->tls_psk, PSK_SIZE_BYTES)) {
log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK master key.");
SSL_SESSION_free(sess);
return 0;
@ -368,34 +376,35 @@ static int psk_server_callback(SSL *ssl, const unsigned char *identity, size_t i
return 1;
}
struct client_ctx_t {
struct generic_tls_ctx_t *gctx;
const struct keydb_t *keydb;
int fd;
};
static void *client_handler_thread(void *vctx) {
struct client_ctx_t *client = (struct client_ctx_t*)vctx;
SSL *ssl = SSL_new(client->gctx->ctx);
SSL_set_fd(ssl, client->fd);
SSL_set_default_passwd_cb_userdata(ssl, (void*)client->keydb);
SSL_set_app_data(ssl, client);
if (SSL_accept(ssl) <= 0) {
ERR_print_errors_fp(stderr);
} else {
log_msg(LLVL_DEBUG, "Client connected, sending their data...");
/*
while (true) {
struct msg_t msg;
int rxlen = SSL_read(ssl, &msg, sizeof(msg));
if (rxlen != sizeof(msg)) {
log_msg(LLVL_WARNING, "Tried to read message of %d bytes, recevied %d. Severing connection to client.", sizeof(msg), rxlen);
break;
if (client->host) {
log_msg(LLVL_DEBUG, "Client \"%s\" connected, sending unlock data for %d volumes...", client->host->host_name, client->host->volume_count);
for (unsigned int i = 0; i < client->host->volume_count; i++) {
const struct volume_entry_t *volume = &client->host->volumes[i];
struct msg_t msg = { 0 };
memcpy(msg.volume_uuid, volume->volume_uuid, 16);
memcpy(msg.luks_passphrase_raw, volume->luks_passphrase_raw, LUKS_PASSPHRASE_RAW_SIZE_BYTES);
int txlen = SSL_write(ssl, &msg, sizeof(msg));
OPENSSL_cleanse(&msg, sizeof(msg));
if (txlen != sizeof(msg)) {
log_msg(LLVL_WARNING, "Tried to send message of %d bytes, but sent %d. Severing connection to client.", sizeof(msg), txlen);
break;
}
}
} else {
log_msg(LLVL_FATAL, "Client connected, but no host set.");
}
*/
fprintf(stderr, "done\n");
}
SSL_free(ssl);