]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
client: add keygen command
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 14 Jan 2016 13:20:54 +0000 (14:20 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 14 Jan 2016 13:45:52 +0000 (14:45 +0100)
Add a new command that will generate a random key from /dev/urandom with
given ID, hash function and length.

chrony.texi.in
client.c

index 4f643db9012d996822b44a454b0f36a5d231074e..654071a33eb8d1ae7d33c2e2c4db654c76849fc9 100644 (file)
@@ -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
index 5114cf431b72b7c0f4551098bc537429ea311529..af7258eaf7459ed5bb770a4060f48fa450ebf6c4 100644 (file)
--- 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 <milliseconds>\0Set initial response timeout\0"
     "retries <retries>\0Set maximum number of retries\0"
+    "keygen <id> [<type> [<bits>]]\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")) {