nDPId decryption example

Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
This commit is contained in:
Toni Uhlig
2024-12-19 14:20:46 +01:00
parent 49b058d2d3
commit 2c81f116bf
4 changed files with 157 additions and 27 deletions

View File

@@ -1,15 +1,36 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include "config.h"
#include "ncrypt.h"
#include "nDPIsrvd.h"
#include "utils.h"
struct
{
struct nDPIsrvd_address parsed_listen_address;
struct cmdarg listen_address;
struct cmdarg local_private_key_file;
struct cmdarg remote_public_key_file;
} options = {.listen_address = CMDARG_STR("127.0.0.1:7443"),
.local_private_key_file = CMDARG_STR(NULL),
.remote_public_key_file = CMDARG_STR(NULL)};
struct confopt config_map[] = {CONFOPT(NULL, &options.listen_address),
CONFOPT(NULL, &options.local_private_key_file),
CONFOPT(NULL, &options.remote_public_key_file)};
static void print_usage(char const * const arg0)
{
static char const usage[] =
"Usage: %s "
"[-L listen-address] [-k private-key-file] [-K public-key-file]\n"
"\t \t"
"[-l] [-L listen-address] [-k private-key-file] [-K public-key-file]\n"
"\t \t"
"[-h]\n\n"
"\t-l\tLog all messages to stderr.\n"
"\t-L\tThe address on which this example will listen for incoming\n"
"\t \t(encrypted) UDP packets sent by nDPId\n"
"\t-k\tThe path to the local private X25519 key file (PEM format)\n"
@@ -23,19 +44,24 @@ static int parse_options(int argc, char ** argv)
{
int opt;
while ((opt = getopt(argc, argv, "hk:K:s:")) != -1)
while ((opt = getopt(argc, argv, "lL:k:K:h")) != -1)
{
switch (opt)
{
case 'h':
print_usage(argv[0]);
return 1;
case 'l':
enable_console_logger();
break;
case 'L':
set_cmdarg_string(&options.listen_address, optarg);
break;
case 'k':
set_cmdarg_string(&options.local_private_key_file, optarg);
break;
case 'K':
set_cmdarg_string(&options.remote_public_key_file, optarg);
break;
case 's':
break;
case 'h':
default:
print_usage(argv[0]);
return 1;
@@ -44,9 +70,12 @@ static int parse_options(int argc, char ** argv)
if (optind < argc)
{
if (optind > 0) {
if (optind > 0)
{
logger_early(1, "Unexpected argument(s) after %s\n\n", argv[optind]);
} else {
}
else
{
logger_early(1, "%s\n\n", "Unexpected argument(s)");
}
print_usage(argv[0]);
@@ -57,6 +86,34 @@ static int parse_options(int argc, char ** argv)
return 0;
}
int udp_server(struct ncrypt * const nc)
{
int sock_fd = socket(options.parsed_listen_address.raw.sa_family, SOCK_DGRAM, 0);
if (sock_fd < 0)
{
return 1;
}
if (bind(sock_fd, &options.parsed_listen_address.raw, options.parsed_listen_address.size) != 0)
{
return 1;
}
struct ncrypt_buffer read_buf = {};
for (;;)
{
int bytes_read = ncrypt_decrypt_recv(nc, sock_fd, &read_buf);
if (bytes_read <= 0)
{
break;
}
printf("read %d bytes\n", bytes_read);
}
return 0;
}
int main(int argc, char ** argv)
{
if (argc == 0 || argv == NULL || stdout == NULL || stderr == NULL)
@@ -68,7 +125,55 @@ int main(int argc, char ** argv)
if (parse_options(argc, argv) != 0)
{
return 1;
}
return 0;
set_config_defaults(&config_map[0], nDPIsrvd_ARRAY_LENGTH(config_map));
if (nDPIsrvd_setup_address(&options.parsed_listen_address, GET_CMDARG_STR(options.listen_address)) != 0)
{
logger_early(1, "Collector socket invalid listen address: `%s'", GET_CMDARG_STR(options.listen_address));
return 1;
}
if (IS_CMDARG_SET(options.local_private_key_file) == 0 || IS_CMDARG_SET(options.remote_public_key_file) == 0)
{
logger_early(1, "%s", "Arguments `-k' and `-K' are mandatory!");
return 1;
}
struct ncrypt nc;
{
int ret;
unsigned char priv_key[NCRYPT_X25519_KEYLEN];
unsigned char pub_key[NCRYPT_X25519_KEYLEN];
ret = ncrypt_load_privkey(GET_CMDARG_STR(options.local_private_key_file), priv_key);
if (ret != 0)
{
logger_early(1,
"Invalid PEM private key file `%s': %d (%s)",
GET_CMDARG_STR(options.local_private_key_file),
ret,
strerror(errno));
return 1;
}
ret = ncrypt_load_pubkey(GET_CMDARG_STR(options.remote_public_key_file), pub_key);
if (ret != 0)
{
logger_early(1,
"Invalid PEM public key file `%s': %d (%s)",
GET_CMDARG_STR(options.remote_public_key_file),
ret,
strerror(errno));
return 1;
}
ret = ncrypt_init(&nc, priv_key, pub_key);
if (ret != 0)
{
logger_early(1, "Crypto initialization failed: %d", ret);
return 1;
}
}
return udp_server(&nc);
}

View File

@@ -5551,6 +5551,12 @@ static void print_usage(char const * const arg0)
"\t \tDefault: disabled\n"
"\t-c\tPath to a UNIX socket (nDPIsrvd Collector) or a custom UDP endpoint.\n"
"\t \tDefault: `%s'\n"
#ifdef ENABLE_CRYPTO
"\t-k\tPath to the local private key file (PEM format)\n"
"\t \tDefault: disabled\n"
"\t-K\tPath to the remote public key file (PEM format)\n"
"\t \tDefault: disabled\n"
#endif
#ifdef ENABLE_EPOLL
"\t-e\tUse poll() instead of epoll().\n"
"\t \tDefault: epoll() on Linux, poll() otherwise\n"

36
utils.c
View File

@@ -45,7 +45,14 @@ void set_config_defaults(struct confopt * const co_array, size_t array_length)
switch (co_array[i].opt->type)
{
case CMDTYPE_INVALID:
logger_early(1, "BUG: Config option `%s' has CMDTYPE_INVALID!", co_array[i].key);
if (co_array[i].key != NULL)
{
logger_early(1, "BUG: Config option `%s' has CMDTYPE_INVALID!", co_array[i].key);
}
else
{
logger_early(1, "%s", "BUG: Config option has CMDTYPE_INVALID!");
}
break;
case CMDTYPE_STRING:
if (co_array[i].opt->string.default_value == NULL)
@@ -97,7 +104,14 @@ int set_config_from(struct confopt * const co, char const * const from)
}
else
{
logger_early(1, "Config key `%s' has a value not of type bool: `%s'", co->key, from);
if (co->key != NULL)
{
logger_early(1, "Config key `%s' has a value not of type bool: `%s'", co->key, from);
}
else
{
logger_early(1, "Config key has a value not of type bool: `%s'", from);
}
return 1;
}
set_cmdarg_boolean(co->opt, enabled);
@@ -110,12 +124,26 @@ int set_config_from(struct confopt * const co, char const * const from)
if (from == endptr)
{
logger_early(1, "Subopt `%s': Value `%s' is not a valid number.", co->key, from);
if (co->key != NULL)
{
logger_early(1, "Subopt `%s': Value `%s' is not a valid number.", co->key, from);
}
else
{
logger_early(1, "Subopt: Value `%s' is not a valid number.", from);
}
return 1;
}
if (errno == ERANGE)
{
logger_early(1, "Subopt `%s': Number too large.", co->key);
if (co->key != NULL)
{
logger_early(1, "Subopt `%s': Number too large.", co->key);
}
else
{
logger_early(1, "%s", "Subopt: Number too large.");
}
return 1;
}
set_cmdarg_ull(co->opt, value_llu);

17
utils.h
View File

@@ -11,21 +11,12 @@
#define INI_MAX_NAME 50
#define CMDARG_STR(_default_value) \
{ \
.is_set = 0, .type = CMDTYPE_STRING, .string.value = NULL, .string.default_value = (_default_value) \
}
{.is_set = 0, .type = CMDTYPE_STRING, .string.value = NULL, .string.default_value = (_default_value)}
#define CMDARG_BOOL(_default_value) \
{ \
.is_set = 0, .type = CMDTYPE_BOOLEAN, .boolean.value = 0, .boolean.default_value = (_default_value) \
}
{.is_set = 0, .type = CMDTYPE_BOOLEAN, .boolean.value = 0, .boolean.default_value = (_default_value)}
#define CMDARG_ULL(_default_value) \
{ \
.is_set = 0, .type = CMDTYPE_ULL, .ull.value = 0ull, .ull.default_value = (_default_value) \
}
#define CONFOPT(_key, _opt) \
{ \
.key = _key, .opt = _opt \
}
{.is_set = 0, .type = CMDTYPE_ULL, .ull.value = 0ull, .ull.default_value = (_default_value)}
#define CONFOPT(_key, _opt) {.key = _key, .opt = _opt}
#define GET_CMDARG_STR(cmdarg) ((cmdarg).string.value)
#define GET_CMDARG_BOOL(cmdarg) ((cmdarg).boolean.value)
#define GET_CMDARG_ULL(cmdarg) ((cmdarg).ull.value)