From 603e63876fbf25bcaaef318a93ba42d6674d9c1b Mon Sep 17 00:00:00 2001 From: Johannes Bauer Date: Wed, 23 Oct 2019 15:56:06 +0200 Subject: [PATCH] Server implementation seems to work Rudimentary functionality of server (not including responding to announcements over UDP) is working now. --- editor.c | 2 +- keydb.c | 10 +++++----- keydb.h | 16 ++++++++-------- server.c | 51 ++++++++++++++++++++++++++++++--------------------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/editor.c b/editor.c index 3e82dc4..2419e75 100644 --- a/editor.c +++ b/editor.c @@ -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); } } } diff --git a/keydb.c b/keydb.c index 97fc7a7..b6b0f3e 100644 --- a/keydb.c +++ b/keydb.c @@ -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) { diff --git a/keydb.h b/keydb.h index 9e461df..2ec4c65 100644 --- a/keydb.h +++ b/keydb.h @@ -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 { diff --git a/server.c b/server.c index dd33fe7..6d713a2 100644 --- a/server.c +++ b/server.c @@ -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);