From d77356837a08c765d7ac3b829140334db9b59117 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 9 Feb 2012 16:44:43 +0100 Subject: [PATCH] Support passwords encoded in HEX --- chrony.texi | 17 +++++++++++------ client.c | 13 ++++++++++--- keys.c | 15 ++++++++++++--- util.c | 30 ++++++++++++++++++++++++++++++ util.h | 3 +++ 5 files changed, 66 insertions(+), 12 deletions(-) diff --git a/chrony.texi b/chrony.texi index 2ef766f..f45cdde 100644 --- a/chrony.texi +++ b/chrony.texi @@ -1727,8 +1727,8 @@ pairs. The format of the file is shown below @example 10 tulip 11 hyacinth -20 MD5 crocus -25 SHA1 iris +20 MD5 ASCII:crocus +25 SHA1 HEX:1dc764e0791b11fa67efc7ecbc4b0d73f68a070c ... @end example @@ -1737,7 +1737,9 @@ and a password. The ID can be any unsigned integer in the range 0 through 2**32-1. The hash function is MD5 by default, depending on how was @code{chronyd} compiled other allowed hash functions may be SHA1, SHA256, SHA384, SHA512, RMD128, RMD160, RMD256, RMD320, TIGER and WHIRLPOOL. The -password can be any string of characters not containing a space. +password can be encoded as a string of characters not containing a space with +optional @code{ASCII:} prefix or as a hexadecimal number with @code{HEX:} +prefix. The ID for the chronyc authentication key is specified with the commandkey command (see earlier). @@ -3766,6 +3768,8 @@ password on the command line is as follows @example password xyzzy +password ASCII:xyzzy +password HEX:78797a7a79 @end example To enter the password without it being echoed, enter @@ -3779,9 +3783,10 @@ should enter the password and press return. (Note that the no-echo mode is limited to 8 characters on SunOS 4.1 due to limitations in the system library. Other systems do not have this restriction.) -The password is any string of characters not containing whitespace. It -has to match @code{chronyd's} currently defined command key (@pxref{commandkey -directive}). +The password can be encoded as a string of characters not containing a space +with optional @code{ASCII:} prefix or as a hexadecimal number with @code{HEX:} +prefix. It has to match @code{chronyd's} currently defined command key +(@pxref{commandkey directive}). @c }}} @c {{{ polltarget @node polltarget command diff --git a/client.c b/client.c index c7bc458..e8fcc19 100644 --- a/client.c +++ b/client.c @@ -1096,6 +1096,7 @@ process_cmd_delete(CMD_Request *msg, char *line) static char *password; static int password_seen = 0; +static int password_length; static int auth_hash_id; /* ================================================== */ @@ -1125,7 +1126,13 @@ process_cmd_password(CMD_Request *msg, char *line) if (!*password) { password_seen = 0; } else { - password_seen = 1; + password_length = UTI_DecodePasswordFromText(password); + if (password_length > 0) { + password_seen = 1; + } else { + password_seen = 0; + fprintf(stderr, "Could not decode password\n"); + } } if (gettimeofday(&now, NULL) < 0) { @@ -1149,7 +1156,7 @@ generate_auth(CMD_Request *msg) assert(auth_hash_id >= 0); - return UTI_GenerateNTPAuth(auth_hash_id, (unsigned char *)password, strlen(password), + return UTI_GenerateNTPAuth(auth_hash_id, (unsigned char *)password, password_length, (unsigned char *)msg, data_len, ((unsigned char *)msg) + data_len, sizeof (msg->auth)); } @@ -1164,7 +1171,7 @@ check_reply_auth(CMD_Reply *msg, int len) assert(auth_hash_id >= 0); - return UTI_CheckNTPAuth(auth_hash_id, (unsigned char *)password, strlen(password), + return UTI_CheckNTPAuth(auth_hash_id, (unsigned char *)password, password_length, (unsigned char *)msg, data_len, ((unsigned char *)msg) + data_len, len - data_len); } diff --git a/keys.c b/keys.c index 36fd56b..1f816db 100644 --- a/keys.c +++ b/keys.c @@ -179,10 +179,15 @@ KEY_Reload(void) continue; } + keys[n_keys].len = UTI_DecodePasswordFromText(keyval); + if (!keys[n_keys].len) { + LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %d", key_id); + continue; + } + keys[n_keys].id = key_id; - keys[n_keys].len = strlen(keyval); - keys[n_keys].val = MallocArray(char, 1 + keys[n_keys].len); - strcpy(keys[n_keys].val, keyval); + keys[n_keys].val = MallocArray(char, keys[n_keys].len); + memcpy(keys[n_keys].val, keyval, keys[n_keys].len); n_keys++; } } @@ -193,6 +198,10 @@ KEY_Reload(void) more careful! */ qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id); + /* Erase the passwords from stack */ + memset(line, 0, sizeof (line)); + memset(buf1, 0, sizeof (buf1)); + memset(buf2, 0, sizeof (buf2)); } } diff --git a/util.c b/util.c index 29fbb65..b658a92 100644 --- a/util.c +++ b/util.c @@ -639,3 +639,33 @@ UTI_CheckNTPAuth(int hash_id, const unsigned char *key, int key_len, return UTI_GenerateNTPAuth(hash_id, key, key_len, data, data_len, buf, sizeof (buf)) == auth_len && !memcmp(buf, auth, auth_len); } + +/* ================================================== */ + +int +UTI_DecodePasswordFromText(char *key) +{ + int i, j, len = strlen(key); + char buf[3], *p; + + if (!strncmp(key, "ASCII:", 6)) { + memmove(key, key + 6, len - 6); + return len - 6; + } else if (!strncmp(key, "HEX:", 4)) { + if ((len - 4) % 2) + return 0; + + for (i = 0, j = 4; j + 1 < len; i++, j += 2) { + buf[0] = key[j], buf[1] = key[j + 1], buf[2] = '\0'; + key[i] = strtol(buf, &p, 16); + + if (p != buf + 2) + return 0; + } + + return i; + } else { + /* assume ASCII */ + return len; + } +} diff --git a/util.h b/util.h index dfcbd73..e2014b8 100644 --- a/util.h +++ b/util.h @@ -107,6 +107,9 @@ extern int UTI_GenerateNTPAuth(int hash_id, const unsigned char *key, int key_le extern int UTI_CheckNTPAuth(int hash_id, const unsigned char *key, int key_len, const unsigned char *data, int data_len, const unsigned char *auth, int auth_len); +/* Decode password encoded in ASCII or HEX */ +extern int UTI_DecodePasswordFromText(char *key); + #if defined (INLINE_UTILITIES) #define INLINE_STATIC inline static #include "util.c"