From 7fcf69ce5f37136f974fbe8256e132e4fb418d15 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 14 Jan 2016 14:20:54 +0100 Subject: [PATCH] client: add keygen command Add a new command that will generate a random key from /dev/urandom with given ID, hash function and length. --- chrony.texi.in | 26 ++++++++++++++++++++++++++ client.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/chrony.texi.in b/chrony.texi.in index 4f643db..654071a 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -3373,6 +3373,7 @@ interface. * dump command:: Dump measurement histories to files * exit command:: Exit from chronyc * help command:: Generate help summary +* keygen command:: Generate key for key file * local command:: Let computer be a server when it is unsynchronised * makestep command:: Correct the system clock by stepping instead of slewing * manual command:: Enable/disable/configure options for settime @@ -3807,6 +3808,31 @@ The exit command exits from chronyc and returns the user to the shell @subsubsection help The help command displays a summary of the commands and their arguments. @c }}} +@c {{{ keygen +@node keygen command +@subsubsection keygen +The @code{keygen} command generates a key that can be added to the +key file (@pxref{keyfile directive}) to allow NTP authentication between +server and client, or peers. The key is generated from the @code{/dev/urandom} +device and it's printed to standard output. + +The first argument of the command is the key number, which will be specified +with the @code{key} option of the @code{server} or @code{peer} directives in +the configuration file. The second and third arguments are optional. They +specify the hash function (by default SHA1 or MD5 if SHA1 is not available) and +the number of bits the key should have between 80 and 4096 bits (by default 160 +bits). + +An example is + +@example +keygen 73 SHA1 256 +@end example + +which generates a 256-bit SHA-1 key with number 73. The printed line would +then be securely transferred and added to key files on both server and client, +or peers. +@c }}} @c {{{ local @node local command @subsubsection local diff --git a/client.c b/client.c index 5114cf4..af7258e 100644 --- a/client.c +++ b/client.c @@ -1255,6 +1255,7 @@ give_help(void) "dns -4|-6|-46\0Resolve hostnames only to IPv4/IPv6/both addresses\0" "timeout \0Set initial response timeout\0" "retries \0Set maximum number of retries\0" + "keygen [ []]\0Generate key for key file\0" "exit|quit\0Leave the program\0" "help\0Generate this help\0" "\0"; @@ -2413,6 +2414,42 @@ process_cmd_retries(const char *line) /* ================================================== */ +static int +process_cmd_keygen(char *line) +{ + char hash_name[17]; + unsigned char key[512]; + unsigned int i, length, id, bits = 160; + +#ifdef FEAT_SECHASH + snprintf(hash_name, sizeof (hash_name), "SHA1"); +#else + snprintf(hash_name, sizeof (hash_name), "MD5"); +#endif + + if (sscanf(line, "%u %16s %d", &id, hash_name, &bits) < 1) { + LOG(LOGS_ERR, LOGF_Client, "Invalid syntax for keygen command"); + return 0; + } + + length = CLAMP(10, (bits + 7) / 8, sizeof (key)); + if (HSH_GetHashId(hash_name) < 0) { + LOG(LOGS_ERR, LOGF_Client, "Unknown hash function %s", hash_name); + return 0; + } + + UTI_GetRandomBytesUrandom(key, length); + + printf("%u %s HEX:", id, hash_name); + for (i = 0; i < length; i++) + printf("%02hhX", key[i]); + printf("\n"); + + return 1; +} + +/* ================================================== */ + static int process_line(char *line) { @@ -2499,6 +2536,9 @@ process_line(char *line) do_normal_submit = 0; give_help(); ret = 1; + } else if (!strcmp(command, "keygen")) { + ret = process_cmd_keygen(line); + do_normal_submit = 0; } else if (!strcmp(command, "local")) { do_normal_submit = process_cmd_local(&tx_message, line); } else if (!strcmp(command, "makestep")) {