From b1f47355e3e9fdb0df5d0c482e67cb0108dc009e Mon Sep 17 00:00:00 2001 From: "Fabio M. Di Nitto" Date: Wed, 26 Sep 2012 09:52:04 +0200 Subject: [PATCH] kronosnetd: add knet-keygen Signed-off-by: Fabio M. Di Nitto --- .gitignore | 1 + kronosnetd/Makefile.am | 13 +++- kronosnetd/keygen.c | 169 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 kronosnetd/keygen.c diff --git a/.gitignore b/.gitignore index c24a837..d2ea9ce 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ missing libtool autoscan.log kronosnetd/kronosnetd +kronosnetd/knet-keygen *.swp *_test *_bench diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am index 4e630bf..1130cf8 100644 --- a/kronosnetd/Makefile.am +++ b/kronosnetd/Makefile.am @@ -10,7 +10,8 @@ noinst_HEADERS = \ vty_cli_cmds.h \ vty_utils.h -sbin_PROGRAMS = kronosnetd +sbin_PROGRAMS = kronosnetd \ + knet-keygen kronosnetd_SOURCES = \ cfg.c \ @@ -33,3 +34,13 @@ kronosnetd_LDADD = \ $(top_builddir)/libknet/libknet.la \ $(top_builddir)/libtap/libtap.la \ $(LIBQB_LIBS) + +knet_keygen_SOURCES = keygen.c + +install-exec-local: + $(INSTALL) -d -m 0700 $(DESTDIR)/$(DEFAULT_CONFIG_DIR) + $(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/cryptokeys.d + +uninstall-local: + rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/cryptokeys.d || :; + rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR) || :; diff --git a/kronosnetd/keygen.c b/kronosnetd/keygen.c new file mode 100644 index 0000000..5a9d443 --- /dev/null +++ b/kronosnetd/keygen.c @@ -0,0 +1,169 @@ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static char *output_file = NULL; +static ssize_t keylen = 4096; + +static void print_usage(void) +{ + printf("\nUsage:\n\n"); + printf("knet-keygen -o [-s ]\n\n"); +}; + +#define OPTION_STRING "ho:s:" + +static int read_arguments(int argc, char **argv) +{ + int cont = 1; + int optchar; + + while (cont) { + optchar = getopt(argc, argv, OPTION_STRING); + + switch (optchar) { + + case 'o': + output_file = strdup(optarg); + if (!output_file) { + fprintf(stderr, "Error: Unable to allocate memory\n"); + return -1; + } + if (strlen(output_file) > PATH_MAX) { + fprintf(stderr, "Seriously? WTF\n"); + return -1; + } + break; + + case 's': + keylen = atoi(optarg); + if ((keylen < 1024) || (keylen > 4096)) { + fprintf(stderr, "Error: Key size should be a value between 1024 and 4096 (default) included\n"); + return -1; + } + break; + + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + + case EOF: + cont = 0; + break; + + default: + fprintf(stderr, "Error: unknown option: %c\n", optchar); + print_usage(); + return -1; + break; + + } + } + if (!output_file) { + fprintf(stderr, "Error: no output file specified\n"); + print_usage(); + return -1; + } + return 0; +} + +int main (int argc, char *argv[]) +{ + int ret = 0; + int fd = -1; + ssize_t res; + ssize_t bytes_read = 0; + char *keybuf = NULL; + + printf (PACKAGE " key generator.\n"); + + if (read_arguments(argc, argv) < 0) { + goto exit_error; + } + + if (geteuid() != 0) { + fprintf(stderr, "Error: Authorization key must be generated as root user.\n"); + goto exit_error; + } + + fd = open ("/dev/random", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Error: Unable to open /dev/random\n"); + goto exit_error; + } + + keybuf = malloc(keylen); + if (!keybuf) { + fprintf(stderr, "Error: Unable to allocate memory for key\n"); + goto exit_error; + } + + printf("Gathering %zu bytes for key from /dev/random.\n", keylen); + printf("This process might take a long time due the amount on entropy required\n"); + printf("Press keys on your keyboard, perform any kind of disk I/O and/or network to generate entropy faster.\n"); + +keep_reading: + res = read(fd, &keybuf[bytes_read], keylen - bytes_read); + if (res == -1) { + fprintf(stderr, "Error: Unable to read from /dev/random.\n"); + goto exit_error; + } + bytes_read += res; + if (bytes_read != keylen) { + printf("bytes read = %zu, missing = %zu.\n", bytes_read, keylen - bytes_read); + goto keep_reading; + } + close (fd); + fd = -1; + + fd = open (output_file, O_CREAT|O_WRONLY, 600); + if (fd == -1) { + fprintf(stderr, "Error: Could not create %s\n", output_file); + goto exit_error; + } + + /* + * Make sure file is owned by root and mode 0400 + */ + if (fchown(fd, 0, 0)) { + fprintf(stderr, "Error: Could not set uid 0 (root) and gid 0 (root) on keyfile %s\n", output_file); + goto exit_error; + } + if (fchmod(fd, 0400)) { + fprintf(stderr, "Error: Could not set read-only permissions on keyfile %s\n", output_file); + goto exit_error; + } + + printf("Writing private key to %s\n", output_file); + + if (write(fd, keybuf, keylen) != keylen) { + fprintf(stderr, "Error: Could not write key to file %s\n", output_file); + goto exit_error; + } + + printf("Done.\n"); + printf("Please copy this file in " DEFAULT_CONFIG_DIR "/cryptokeys.d/\n"); + printf("on all nodes participating in the same kronosnet instance\n"); + +exit_clean: + if (output_file) + free(output_file); + if (keybuf) + free(keybuf); + if (fd > -1) + close(fd); + + return ret; + +exit_error: + ret = -1; + goto exit_clean; +} -- 2.39.5