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); 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, " 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, " 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 */ /* But remove all LUKS passphrases of course, this is for the luksrku client */
for (unsigned int i = 0; i < host->volume_count; i++) { for (unsigned int i = 0; i < host->volume_count; i++) {
struct volume_entry_t *volume = &public_host->volumes[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; 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]; struct volume_entry_t *volume = &host->volumes[host->volume_count];
memcpy(volume->volume_uuid, volume_uuid, 16); memcpy(volume->volume_uuid, volume_uuid, 16);
strncpy(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1); strncpy(volume->devmapper_name, devmapper_name, sizeof(volume->devmapper_name) - 1);
if (!buffer_randomize(volume->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)); log_msg(LLVL_ERROR, "Failed to produce %d bytes of entropy for LUKS passphrase.", sizeof(volume->luks_passphrase_raw));
return NULL; return NULL;
} }
host->volume_count++; 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) { 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) { 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) { 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 #define KEYDB_VERSION 2
struct volume_entry_t { struct volume_entry_t {
uint8_t volume_uuid[16]; /* UUID of crypt_LUKS volume */ uint8_t volume_uuid[16]; /* UUID of crypt_LUKS volume */
char devmapper_name[MAX_DEVMAPPER_NAME_LENGTH]; /* dmsetup name when unlocked. Zero-terminated string. */ 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 luks_passphrase_raw[LUKS_PASSPHRASE_RAW_SIZE_BYTES]; /* LUKS passphrase used to unlock volume; raw byte data */
}; };
struct host_entry_t { struct host_entry_t {
uint8_t host_uuid[16]; /* Host UUID */ uint8_t host_uuid[16]; /* Host UUID */
char host_name[MAX_HOST_NAME_LENGTH]; /* Descriptive name of host */ 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 */ 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 */ unsigned int volume_count; /* Number of volumes of this host */
struct volume_entry_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */ struct volume_entry_t volumes[MAX_VOLUMES_PER_HOST]; /* Volumes of this host */
}; };
struct keydb_t { struct keydb_t {

View File

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