Client and server commnunication now works

We can send our little datagrams over and that works nicely. Need to
consolidate the PSK session establishment into one shared function.
This commit is contained in:
Johannes Bauer 2019-10-23 21:54:10 +02:00
parent 983217ffbd
commit 0e8e42d0ea
10 changed files with 151 additions and 11 deletions

View File

@ -11,7 +11,7 @@ PYPGMOPTS := ../Python/pypgmopts/pypgmopts
LDFLAGS := `pkg-config --libs openssl`
OBJS := luksrku.o editor.o util.o log.o keydb.o file_encryption.o uuid.o argparse_edit.o pgmopts.o openssl.o server.o argparse_server.o thread.o argparse_client.o client.o
OBJS := luksrku.o editor.o util.o log.o keydb.o file_encryption.o uuid.o argparse_edit.o pgmopts.o openssl.o server.o argparse_server.o thread.o argparse_client.o client.o signals.o
parsers:
$(PYPGMOPTS) -n edit parsers/parser_edit.py
@ -27,10 +27,10 @@ clean:
rm -f $(OBJS) $(OBJS_CFG) luksrku
test_s: luksrku
./luksrku server -vv base
./luksrku server -vv testdata/server.bin
test_c: luksrku
./luksrku client -vv export 127.0.0.1
./luksrku client -vv testdata/client.bin 127.0.0.1
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<

View File

@ -41,6 +41,7 @@
#include "client.h"
#include "blacklist.h"
#include "keydb.h"
#include "uuid.h"
#if 0
static const struct keydb_t *client_keydb;
@ -216,11 +217,53 @@ struct keyclient_t {
const struct pgmopts_client_t *opts;
struct keydb_t *keydb;
bool volume_unlocked[MAX_VOLUMES_PER_HOST];
unsigned char identifier[ASCII_UUID_BUFSIZE];
};
static int psk_client_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id, size_t *idlen, SSL_SESSION **sess) {
fprintf(stderr, "CLIENT CALLBACK\n");
return 0;
static int psk_client_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id, size_t *idlen, SSL_SESSION **sessptr) {
struct keyclient_t *key_client = (struct keyclient_t*)SSL_get_app_data(ssl);
*id = key_client->identifier;
*idlen = ASCII_UUID_CHARACTER_COUNT;
SSL_SESSION *sess = SSL_SESSION_new();
if (!sess) {
log_openssl(LLVL_ERROR, "Failed to create SSL_SESSION context for client.");
return 0;
}
const uint8_t tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };
const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id);
if (!cipher) {
log_openssl(LLVL_ERROR, "Unable to look up SSL_CIPHER for TLSv1.3-PSK");
return 0;
}
int return_value = 1;
do {
if (!SSL_SESSION_set1_master_key(sess, key_client->keydb->hosts[0].tls_psk, PSK_SIZE_BYTES)) {
log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK master key.");
return_value = 0;
break;
}
if (!SSL_SESSION_set_cipher(sess, cipher)) {
log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK cipher.");
return_value = 0;
break;
}
if (!SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION)) {
log_openssl(LLVL_ERROR, "Failed to set TLSv1.3-PSK protocol version.");
return_value = 0;
break;
}
} while (false);
if (return_value) {
*sessptr = sess;
}
return return_value;
}
static bool contact_keyserver_socket(struct keyclient_t *keyclient, int sd) {
@ -237,7 +280,24 @@ static bool contact_keyserver_socket(struct keyclient_t *keyclient, int sd) {
SSL_set_app_data(ssl, keyclient);
if (SSL_connect(ssl) == 1) {
fprintf(stderr, "OK\n");
struct msg_t msg;
while (true) {
int bytes_read = SSL_read(ssl, &msg, sizeof(msg));
if (bytes_read == 0) {
/* Server closed the connection. */
break;
}
if (bytes_read != sizeof(msg)) {
log_openssl(LLVL_FATAL, "SSL_read returned %d bytes when we expected to read %d", bytes_read, sizeof(msg));
break;
}
if (should_log(LLVL_TRACE)) {
char uuid_str[ASCII_UUID_BUFSIZE];
sprintf_uuid(uuid_str, msg.volume_uuid);
log_msg(LLVL_TRACE, "Received LUKS key to unlock volume with UUID %s", uuid_str);
}
}
OPENSSL_cleanse(&msg, sizeof(msg));
} else {
log_openssl(LLVL_FATAL, "SSL_connect failed");
}
@ -292,7 +352,7 @@ static bool contact_keyserver_hostname(struct keyclient_t *keyclient, const char
}
struct sockaddr_in *sin_address = (struct sockaddr_in*)result->ai_addr;
log_msg(LLVL_DEBUG, "Resolved %s to %d.%d.%d.%d", hostname, PRINTF_FORMAT_IP(sin_address));
log_msg(LLVL_TRACE, "Resolved %s to %d.%d.%d.%d", hostname, PRINTF_FORMAT_IP(sin_address));
bool success = contact_keyserver_ipv4(keyclient, sin_address, keyclient->opts->port);
@ -334,6 +394,9 @@ bool keyclient_start(const struct pgmopts_client_t *opts) {
break;
}
/* Transcribe the host UUID to ASCII so we only have to do this once */
sprintf_uuid((char*)keyclient.identifier, host->host_uuid);
log_msg(LLVL_DEBUG, "Attempting to unlock %d volumes of host \"%s\".", host->volume_count, host->host_name);
if (opts->hostname) {
if (!contact_keyserver_hostname(&keyclient, opts->hostname)) {

View File

@ -74,8 +74,10 @@ struct keydb_t* keydb_export_public(struct host_entry_t *host) {
}
void keydb_free(struct keydb_t *keydb) {
OPENSSL_cleanse(keydb, keydb_getsize(keydb));
free(keydb);
if (keydb) {
OPENSSL_cleanse(keydb, keydb_getsize(keydb));
free(keydb);
}
}
static int keydb_get_volume_index_by_name(struct host_entry_t *host, const char *devmapper_name) {

1
log.c
View File

@ -37,6 +37,7 @@ static const char *loglvl_names[] = {
[LLVL_WARNING] = "WARNING",
[LLVL_INFO] = "INFO",
[LLVL_DEBUG] = "DEBUG",
[LLVL_TRACE] = "TRACE",
};
void log_setlvl(enum loglvl_t level) {

3
log.h
View File

@ -31,7 +31,8 @@ enum loglvl_t {
LLVL_ERROR = 1,
LLVL_WARNING = 2,
LLVL_INFO = 3,
LLVL_DEBUG = 4
LLVL_DEBUG = 4,
LLVL_TRACE = 5,
};
/*************** AUTO GENERATED SECTION FOLLOWS ***************/

View File

@ -30,6 +30,7 @@
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <signal.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
@ -45,6 +46,7 @@
#include "uuid.h"
#include "thread.h"
#include "keydb.h"
#include "signals.h"
static int create_tcp_server_socket(int port) {
int s;
@ -370,6 +372,9 @@ bool keyserver_start(const struct pgmopts_server_t *opts) {
struct keydb_t* keydb = NULL;
struct generic_tls_ctx_t gctx = { 0 };
do {
/* We ignore SIGPIPE or the server will die when clients disconnect suddenly */
ignore_signal(SIGPIPE);
/* Load key database first */
keydb = keydb_read(opts->filename);
if (!keydb) {

35
signals.c Normal file
View File

@ -0,0 +1,35 @@
/*
luksrku - Tool to remotely unlock LUKS disks using TLS.
Copyright (C) 2016-2016 Johannes Bauer
This file is part of luksrku.
luksrku is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; this program is ONLY licensed under
version 3 of the License, later versions are explicitly excluded.
luksrku is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with luksrku; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Johannes Bauer <JohannesBauer@gmx.de>
*/
#include <stddef.h>
#include <signal.h>
#include "signals.h"
bool ignore_signal(int signum) {
struct sigaction action = {
.sa_handler = SIG_IGN,
.sa_flags = SA_RESTART,
};
sigemptyset(&action.sa_mask);
return sigaction(signum, &action, NULL) == 0;
}

33
signals.h Normal file
View File

@ -0,0 +1,33 @@
/*
luksrku - Tool to remotely unlock LUKS disks using TLS.
Copyright (C) 2016-2016 Johannes Bauer
This file is part of luksrku.
luksrku is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; this program is ONLY licensed under
version 3 of the License, later versions are explicitly excluded.
luksrku is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with luksrku; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Johannes Bauer <JohannesBauer@gmx.de>
*/
#ifndef __SIGNALS_H__
#define __SIGNALS_H__
#include <stdbool.h>
/*************** AUTO GENERATED SECTION FOLLOWS ***************/
bool ignore_signal(int signum);
/*************** AUTO GENERATED SECTION ENDS ***************/
#endif

BIN
testdata/client.bin vendored Normal file

Binary file not shown.

BIN
testdata/server.bin vendored Normal file

Binary file not shown.