Add client code back in

Client code basis back in, parsing of command line options as well.
Client does not do anything yet, though.
This commit is contained in:
Johannes Bauer 2019-10-23 20:13:25 +02:00
parent 9ea0a9695c
commit 425e2dcd66
16 changed files with 288 additions and 74 deletions

View File

@ -11,11 +11,12 @@ PYPGMOPTS := ../Python/pypgmopts/pypgmopts
LDFLAGS := `pkg-config --libs openssl` 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 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
parsers: parsers:
$(PYPGMOPTS) -n edit parsers/parser_edit.py $(PYPGMOPTS) -n edit parsers/parser_edit.py
$(PYPGMOPTS) -n server parsers/parser_server.py $(PYPGMOPTS) -n server parsers/parser_server.py
$(PYPGMOPTS) -n client parsers/parser_client.py
install: all install: all
cp luksrku $(INSTALL_PREFIX)sbin/ cp luksrku $(INSTALL_PREFIX)sbin/

186
argparse_client.c Normal file
View File

@ -0,0 +1,186 @@
/*
* This file was AUTO-GENERATED by pypgmopts.
*
* https://github.com/johndoe31415/pypgmopts
*
* Do not edit it by hand, your changes will be overwritten.
*
* Generated at: 2019-10-23 20:13:13
*/
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <stdarg.h>
#include <string.h>
#include "argparse_client.h"
static enum argparse_client_option_t last_parsed_option;
static char last_error_message[256];
static const char *option_texts[] = {
[ARG_CLIENT_PORT] = "-p / --port",
[ARG_CLIENT_VERBOSE] = "-v / --verbose",
[ARG_CLIENT_FILENAME] = "filename",
[ARG_CLIENT_HOSTNAME] = "hostname",
};
enum argparse_client_option_internal_t {
ARG_CLIENT_PORT_SHORT = 'p',
ARG_CLIENT_VERBOSE_SHORT = 'v',
ARG_CLIENT_PORT_LONG = 1000,
ARG_CLIENT_VERBOSE_LONG = 1001,
ARG_CLIENT_FILENAME_LONG = 1002,
ARG_CLIENT_HOSTNAME_LONG = 1003,
};
static void errmsg_callback(const char *errmsg, ...) {
va_list ap;
va_start(ap, errmsg);
vsnprintf(last_error_message, sizeof(last_error_message), errmsg, ap);
va_end(ap);
}
static void errmsg_option_callback(enum argparse_client_option_t error_option, const char *errmsg, ...) {
last_parsed_option = error_option;
va_list ap;
va_start(ap, errmsg);
vsnprintf(last_error_message, sizeof(last_error_message), errmsg, ap);
va_end(ap);
}
bool argparse_client_parse(int argc, char **argv, argparse_client_callback_t argument_callback, argparse_client_plausibilization_callback_t plausibilization_callback) {
last_parsed_option = ARGPARSE_CLIENT_NO_OPTION;
const char *short_options = "p:v";
struct option long_options[] = {
{ "port", required_argument, 0, ARG_CLIENT_PORT_LONG },
{ "verbose", no_argument, 0, ARG_CLIENT_VERBOSE_LONG },
{ "filename", required_argument, 0, ARG_CLIENT_FILENAME_LONG },
{ "hostname", required_argument, 0, ARG_CLIENT_HOSTNAME_LONG },
{ 0 }
};
while (true) {
int optval = getopt_long(argc, argv, short_options, long_options, NULL);
if (optval == -1) {
break;
}
last_error_message[0] = 0;
enum argparse_client_option_internal_t arg = (enum argparse_client_option_internal_t)optval;
switch (arg) {
case ARG_CLIENT_PORT_SHORT:
case ARG_CLIENT_PORT_LONG:
last_parsed_option = ARG_CLIENT_PORT;
if (!argument_callback(ARG_CLIENT_PORT, optarg, errmsg_callback)) {
return false;
}
break;
case ARG_CLIENT_VERBOSE_SHORT:
case ARG_CLIENT_VERBOSE_LONG:
last_parsed_option = ARG_CLIENT_VERBOSE;
if (!argument_callback(ARG_CLIENT_VERBOSE, optarg, errmsg_callback)) {
return false;
}
break;
default:
last_parsed_option = ARGPARSE_CLIENT_NO_OPTION;
errmsg_callback("unrecognized option supplied");
return false;
}
}
const int positional_argument_cnt = argc - optind;
const int flexible_positional_args_cnt = positional_argument_cnt - 1;
last_parsed_option = ARGPARSE_CLIENT_POSITIONAL_ARG;
if (positional_argument_cnt < 1) {
errmsg_callback("expected a minimum of 1 positional argument, but %d given.", positional_argument_cnt);
return false;
}
if (positional_argument_cnt > 2) {
errmsg_callback("expected a maximum of 2 positional arguments, but %d given.", positional_argument_cnt);
return false;
}
int positional_index = optind;
last_parsed_option = ARG_CLIENT_FILENAME;
if (!argument_callback(ARG_CLIENT_FILENAME, argv[positional_index++], errmsg_callback)) {
return false;
}
last_parsed_option = ARG_CLIENT_HOSTNAME;
for (int i = 0; i < flexible_positional_args_cnt; i++) {
if (!argument_callback(ARG_CLIENT_HOSTNAME, argv[positional_index++], errmsg_callback)) {
return false;
}
}
if (plausibilization_callback) {
if (!plausibilization_callback(errmsg_option_callback)) {
return false;
}
}
return true;
}
void argparse_client_show_syntax(void) {
fprintf(stderr, "usage: luksrku client [-p port] [-v] filename [hostname]\n");
fprintf(stderr, "\n");
fprintf(stderr, "Connects to a luksrku key server and unlocks local LUKS volumes.\n");
fprintf(stderr, "\n");
fprintf(stderr, "positional arguments:\n");
fprintf(stderr, " filename Exported database file to load TLS-PSKs and list of\n");
fprintf(stderr, " disks from.\n");
fprintf(stderr, " hostname When hostname is given, auto-searching for suitable\n");
fprintf(stderr, " servers is disabled and only a connection to the given\n");
fprintf(stderr, " hostname is attempted.\n");
fprintf(stderr, "\n");
fprintf(stderr, "optional arguments:\n");
fprintf(stderr, " -p port, --port port Port that is used for both UDP and TCP communication.\n");
fprintf(stderr, " Defaults to 23170.\n");
fprintf(stderr, " -v, --verbose Increase verbosity. Can be specified multiple times.\n");
}
void argparse_client_parse_or_quit(int argc, char **argv, argparse_client_callback_t argument_callback, argparse_client_plausibilization_callback_t plausibilization_callback) {
if (!argparse_client_parse(argc, argv, argument_callback, plausibilization_callback)) {
if (last_parsed_option > ARGPARSE_CLIENT_POSITIONAL_ARG) {
if (last_error_message[0]) {
fprintf(stderr, "luksrku client: error parsing argument %s -- %s\n", option_texts[last_parsed_option], last_error_message);
} else {
fprintf(stderr, "luksrku client: error parsing argument %s -- no details available\n", option_texts[last_parsed_option]);
}
} else if (last_parsed_option == ARGPARSE_CLIENT_POSITIONAL_ARG) {
fprintf(stderr, "luksrku client: error parsing optional arguments -- %s\n", last_error_message);
}
argparse_client_show_syntax();
exit(EXIT_FAILURE);
}
}
#ifdef __ARGPARSE_MAIN__
/* gcc -D __ARGPARSE_MAIN__ -O2 -Wall -o argparse argparse_client.c
*/
static const char *option_enum_to_str(enum argparse_client_option_t option) {
switch (option) {
case ARG_CLIENT_PORT: return "ARG_CLIENT_PORT";
case ARG_CLIENT_VERBOSE: return "ARG_CLIENT_VERBOSE";
case ARG_CLIENT_FILENAME: return "ARG_CLIENT_FILENAME";
case ARG_CLIENT_HOSTNAME: return "ARG_CLIENT_HOSTNAME";
}
return "UNKNOWN";
}
bool arg_print_callback(enum argparse_client_option_t option, const char *value, argparse_client_errmsg_callback_t errmsg_callback) {
fprintf(stderr, "%s = \"%s\"\n", option_enum_to_str(option), value);
return true;
}
int main(int argc, char **argv) {
argparse_client_parse_or_quit(argc, argv, arg_print_callback, NULL);
return 0;
}
#endif

38
argparse_client.h Normal file
View File

@ -0,0 +1,38 @@
/*
* This file was AUTO-GENERATED by pypgmopts.
*
* https://github.com/johndoe31415/pypgmopts
*
* Do not edit it by hand, your changes will be overwritten.
*
* Generated at: 2019-10-23 20:13:13
*/
#ifndef __ARGPARSE_CLIENT_H__
#define __ARGPARSE_CLIENT_H__
#include <stdbool.h>
#define ARGPARSE_CLIENT_DEFAULT_PORT 23170
#define ARGPARSE_CLIENT_DEFAULT_VERBOSE 0
#define ARGPARSE_CLIENT_NO_OPTION 0
#define ARGPARSE_CLIENT_POSITIONAL_ARG 1
enum argparse_client_option_t {
ARG_CLIENT_PORT = 2,
ARG_CLIENT_VERBOSE = 3,
ARG_CLIENT_FILENAME = 4,
ARG_CLIENT_HOSTNAME = 5,
};
typedef void (*argparse_client_errmsg_callback_t)(const char *errmsg, ...);
typedef void (*argparse_client_errmsg_option_callback_t)(enum argparse_client_option_t error_option, const char *errmsg, ...);
typedef bool (*argparse_client_callback_t)(enum argparse_client_option_t option, const char *value, argparse_client_errmsg_callback_t errmsg_callback);
typedef bool (*argparse_client_plausibilization_callback_t)(argparse_client_errmsg_option_callback_t errmsg_callback);
bool argparse_client_parse(int argc, char **argv, argparse_client_callback_t argument_callback, argparse_client_plausibilization_callback_t plausibilization_callback);
void argparse_client_show_syntax(void);
void argparse_client_parse_or_quit(int argc, char **argv, argparse_client_callback_t argument_callback, argparse_client_plausibilization_callback_t plausibilization_callback);
#endif

View File

@ -5,7 +5,7 @@
* *
* Do not edit it by hand, your changes will be overwritten. * Do not edit it by hand, your changes will be overwritten.
* *
* Generated at: 2019-10-23 10:06:43 * Generated at: 2019-10-23 20:13:13
*/ */
#include <stdint.h> #include <stdint.h>

View File

@ -5,7 +5,7 @@
* *
* Do not edit it by hand, your changes will be overwritten. * Do not edit it by hand, your changes will be overwritten.
* *
* Generated at: 2019-10-23 10:06:43 * Generated at: 2019-10-23 20:13:13
*/ */
#ifndef __ARGPARSE_EDIT_H__ #ifndef __ARGPARSE_EDIT_H__

View File

@ -5,7 +5,7 @@
* *
* Do not edit it by hand, your changes will be overwritten. * Do not edit it by hand, your changes will be overwritten.
* *
* Generated at: 2019-10-23 10:06:43 * Generated at: 2019-10-23 20:13:13
*/ */
#include <stdint.h> #include <stdint.h>
@ -127,7 +127,7 @@ bool argparse_server_parse(int argc, char **argv, argparse_server_callback_t arg
void argparse_server_show_syntax(void) { void argparse_server_show_syntax(void) {
fprintf(stderr, "usage: luksrku server [-p port] [-s] [-v] filename\n"); fprintf(stderr, "usage: luksrku server [-p port] [-s] [-v] filename\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Starts an luksrku key server.\n"); fprintf(stderr, "Starts a luksrku key server.\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "positional arguments:\n"); fprintf(stderr, "positional arguments:\n");
fprintf(stderr, " filename Database file to load keys from.\n"); fprintf(stderr, " filename Database file to load keys from.\n");

View File

@ -5,7 +5,7 @@
* *
* Do not edit it by hand, your changes will be overwritten. * Do not edit it by hand, your changes will be overwritten.
* *
* Generated at: 2019-10-23 10:06:43 * Generated at: 2019-10-23 20:13:13
*/ */
#ifndef __ARGPARSE_SERVER_H__ #ifndef __ARGPARSE_SERVER_H__

View File

@ -32,13 +32,12 @@
#include "log.h" #include "log.h"
#include "openssl.h" #include "openssl.h"
#include "keyfile.h"
#include "util.h" #include "util.h"
#include "cmdline.h"
#include "msg.h" #include "msg.h"
#include "client.h" #include "client.h"
#include "blacklist.h" #include "blacklist.h"
#if 0
static const struct keydb_t *client_keydb; static const struct keydb_t *client_keydb;
static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) { static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) {
@ -166,7 +165,7 @@ static bool parse_announcement(const struct options_t *options, const struct soc
return true; return true;
} }
bool tls_client(const struct keydb_t *keydb, const struct options_t *options) { static bool tls_client(const struct keydb_t *keydb, const struct options_t *options) {
client_keydb = keydb; client_keydb = keydb;
int sd = socket(AF_INET, SOCK_DGRAM, 0); int sd = socket(AF_INET, SOCK_DGRAM, 0);
@ -206,3 +205,8 @@ bool tls_client(const struct keydb_t *keydb, const struct options_t *options) {
return true; return true;
} }
#endif
bool keyclient_start(const struct pgmopts_client_t *opts) {
return true;
}

View File

@ -24,11 +24,11 @@
#ifndef __CLIENT_H__ #ifndef __CLIENT_H__
#define __CLIENT_H__ #define __CLIENT_H__
#include "keyfile.h" #include <stdbool.h>
#include "cmdline.h" #include "pgmopts.h"
/*************** AUTO GENERATED SECTION FOLLOWS ***************/ /*************** AUTO GENERATED SECTION FOLLOWS ***************/
bool dtls_client(const struct keydb_t *keydb, const struct options_t *options); bool keyclient_start(const struct pgmopts_client_t *opts);
/*************** AUTO GENERATED SECTION ENDS ***************/ /*************** AUTO GENERATED SECTION ENDS ***************/
#endif #endif

View File

@ -31,6 +31,7 @@
#include "editor.h" #include "editor.h"
#include "openssl.h" #include "openssl.h"
#include "server.h" #include "server.h"
#include "client.h"
#if OPENSSL_VERSION_NUMBER < 0x010100000 #if OPENSSL_VERSION_NUMBER < 0x010100000
#error "luksrku requires at least OpenSSL v1.1 to work." #error "luksrku requires at least OpenSSL v1.1 to work."
@ -47,7 +48,8 @@ static int main_server(const struct pgmopts_server_t *opts) {
} }
static int main_client(const struct pgmopts_client_t *opts) { static int main_client(const struct pgmopts_client_t *opts) {
return 0; log_setlvl(LOGLEVEL_DEFAULT + opts->verbosity);
return keyclient_start(opts) ? 0 : 1;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {

6
parsers/parser_client.py Executable file
View File

@ -0,0 +1,6 @@
import argparse
parser = argparse.ArgumentParser(prog = "luksrku client", description = "Connects to a luksrku key server and unlocks local LUKS volumes.", add_help = False)
parser.add_argument("-p", "--port", metavar = "port", default = 23170, help = "Port that is used for both UDP and TCP communication. Defaults to %(default)d.")
parser.add_argument("-v", "--verbose", action = "count", default = 0, help = "Increase verbosity. Can be specified multiple times.")
parser.add_argument("filename", metavar = "filename", help = "Exported database file to load TLS-PSKs and list of disks from.")
parser.add_argument("hostname", metavar = "hostname", nargs = "?", help = "When hostname is given, auto-searching for suitable servers is disabled and only a connection to the given hostname is attempted.")

View File

@ -1,5 +1,5 @@
import argparse import argparse
parser = argparse.ArgumentParser(prog = "luksrku server", description = "Starts an luksrku key server.", add_help = False) parser = argparse.ArgumentParser(prog = "luksrku server", description = "Starts a luksrku key server.", add_help = False)
parser.add_argument("-p", "--port", metavar = "port", default = 23170, help = "Port that is used for both UDP and TCP communication. Defaults to %(default)d.") parser.add_argument("-p", "--port", metavar = "port", default = 23170, help = "Port that is used for both UDP and TCP communication. Defaults to %(default)d.")
parser.add_argument("-s", "--silent", action = "store_true", help = "Do not answer UDP queries for clients trying to find a key server, only serve key database using TCP.") parser.add_argument("-s", "--silent", action = "store_true", help = "Do not answer UDP queries for clients trying to find a key server, only serve key database using TCP.")
parser.add_argument("-v", "--verbose", action = "count", default = 0, help = "Increase verbosity. Can be specified multiple times.") parser.add_argument("-v", "--verbose", action = "count", default = 0, help = "Increase verbosity. Can be specified multiple times.")

View File

@ -29,6 +29,7 @@
#include "pgmopts.h" #include "pgmopts.h"
#include "argparse_edit.h" #include "argparse_edit.h"
#include "argparse_server.h" #include "argparse_server.h"
#include "argparse_client.h"
static struct pgmopts_t pgmopts_rw; static struct pgmopts_t pgmopts_rw;
const struct pgmopts_t *pgmopts = &pgmopts_rw; const struct pgmopts_t *pgmopts = &pgmopts_rw;
@ -80,6 +81,27 @@ static bool server_callback(enum argparse_server_option_t option, const char *va
return true; return true;
} }
static bool client_callback(enum argparse_client_option_t option, const char *value, argparse_client_errmsg_callback_t errmsg_callback) {
switch (option) {
case ARG_CLIENT_FILENAME:
pgmopts_rw.client.filename = value;
break;
case ARG_CLIENT_HOSTNAME:
pgmopts_rw.client.hostname = value;
break;
case ARG_CLIENT_PORT:
pgmopts_rw.client.port = atoi(value);
break;
case ARG_CLIENT_VERBOSE:
pgmopts_rw.client.verbosity++;
break;
}
return true;
}
static void parse_pgmopts_edit(int argc, char **argv) { static void parse_pgmopts_edit(int argc, char **argv) {
pgmopts_rw.edit = (struct pgmopts_edit_t){ pgmopts_rw.edit = (struct pgmopts_edit_t){
.verbosity = ARGPARSE_EDIT_DEFAULT_VERBOSE, .verbosity = ARGPARSE_EDIT_DEFAULT_VERBOSE,
@ -96,6 +118,14 @@ static void parse_pgmopts_server(int argc, char **argv) {
argparse_server_parse_or_quit(argc - 1, argv + 1, server_callback, NULL); argparse_server_parse_or_quit(argc - 1, argv + 1, server_callback, NULL);
} }
static void parse_pgmopts_client(int argc, char **argv) {
pgmopts_rw.client = (struct pgmopts_client_t){
.port = ARGPARSE_SERVER_DEFAULT_PORT,
.verbosity = ARGPARSE_SERVER_DEFAULT_VERBOSE,
};
argparse_client_parse_or_quit(argc - 1, argv + 1, client_callback, NULL);
}
void parse_pgmopts_or_quit(int argc, char **argv) { void parse_pgmopts_or_quit(int argc, char **argv) {
if (argc < 2) { if (argc < 2) {
show_syntax("no command supplied", argc, argv); show_syntax("no command supplied", argc, argv);
@ -109,6 +139,9 @@ void parse_pgmopts_or_quit(int argc, char **argv) {
} else if (!strcasecmp(command, "server")) { } else if (!strcasecmp(command, "server")) {
pgmopts_rw.pgm = PGM_SERVER; pgmopts_rw.pgm = PGM_SERVER;
parse_pgmopts_server(argc, argv); parse_pgmopts_server(argc, argv);
} else if (!strcasecmp(command, "client")) {
pgmopts_rw.pgm = PGM_CLIENT;
parse_pgmopts_client(argc, argv);
} else { } else {
show_syntax("unsupported command supplied", argc, argv); show_syntax("unsupported command supplied", argc, argv);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -45,6 +45,9 @@ struct pgmopts_server_t {
}; };
struct pgmopts_client_t { struct pgmopts_client_t {
const char *filename;
const char *hostname;
unsigned int port;
unsigned int verbosity; unsigned int verbosity;
}; };

View File

@ -44,6 +44,7 @@
#include "pgmopts.h" #include "pgmopts.h"
#include "uuid.h" #include "uuid.h"
#include "thread.h" #include "thread.h"
#include "keydb.h"
static int create_tcp_server_socket(int port) { static int create_tcp_server_socket(int port) {
int s; int s;
@ -82,65 +83,6 @@ static const struct keyentry_t *server_key;
/* Wait for the socket to become acceptable or time out after given number of
* milliseconds. Return true if acceptable socket is present or false if
* timeout occured. */
static bool socket_wait_acceptable(int sd, int timeout_millis) {
struct timeval tv;
memset(&tv, 0, sizeof(tv));
tv.tv_usec = timeout_millis * 1000;
fd_set fds;
FD_ZERO(&fds);
FD_SET(sd, &fds);
int result = select(sd + 1, &fds, NULL, NULL, &tv);
return result != 0;
}
static int create_udp_socket(void) {
int sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0) {
log_libc(LLVL_ERROR, "Unable to create UDP server socket(2)");
return -1;
}
{
int value = 1;
if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value))) {
log_libc(LLVL_ERROR, "Unable to set UDP socket in broadcast mode using setsockopt(2)");
close(sd);
return -1;
}
}
return sd;
}
static bool send_udp_broadcast_message(int sd, int port, const void *data, int length) {
struct sockaddr_in destination;
memset(&destination, 0, sizeof(struct sockaddr_in));
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
destination.sin_addr.s_addr = htonl(INADDR_BROADCAST);
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;
}
static bool announce_waiting_message(int sd, int port, const struct keyentry_t *key) {
struct announcement_t msg;
const uint8_t magic[16] = CLIENT_ANNOUNCE_MAGIC;
memset(&msg, 0, sizeof(msg));
memcpy(msg.magic, magic, 16);
memcpy(msg.host_uuid, key->host_uuid, 16);
return send_udp_broadcast_message(sd, port, &msg, sizeof(msg));
}
static bool unlock_disk(const struct diskentry_t *disk, const uint8_t *passphrase, int passphrase_length) { static bool unlock_disk(const struct diskentry_t *disk, const uint8_t *passphrase, int passphrase_length) {
char ascii_uuid[40]; char ascii_uuid[40];
sprintf_uuid(ascii_uuid, disk->disk_uuid); sprintf_uuid(ascii_uuid, disk->disk_uuid);

View File

@ -25,7 +25,6 @@
#define __SERVER_H__ #define __SERVER_H__
#include <stdbool.h> #include <stdbool.h>
#include "keydb.h"
#include "pgmopts.h" #include "pgmopts.h"
/*************** AUTO GENERATED SECTION FOLLOWS ***************/ /*************** AUTO GENERATED SECTION FOLLOWS ***************/