From 9673a2726cc9322872402bcf60ab680138cb2588 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 15 May 2013 16:38:01 +0200 Subject: [PATCH] Refactor key parsing --- cmdparse.c | 30 ++++++++++++++ cmdparse.h | 3 ++ keys.c | 114 ++++++++++++++++++++++++++--------------------------- 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/cmdparse.c b/cmdparse.c index 80fd09c..0ff2d75 100644 --- a/cmdparse.c +++ b/cmdparse.c @@ -248,3 +248,33 @@ CPS_SplitWord(char *line) /* Return pointer to the next word or NUL */ return q; } + +/* ================================================== */ + +int +CPS_ParseKey(char *line, unsigned long *id, const char **hash, char **key) +{ + char *s1, *s2, *s3, *s4; + + s1 = line; + s2 = CPS_SplitWord(s1); + s3 = CPS_SplitWord(s2); + s4 = CPS_SplitWord(s3); + + /* Require two or three words */ + if (!*s2 || *s4) + return 0; + + if (sscanf(s1, "%lu", id) != 1) + return 0; + + if (*s3) { + *hash = s2; + *key = s3; + } else { + *hash = "MD5"; + *key = s2; + } + + return 1; +} diff --git a/cmdparse.h b/cmdparse.h index 3c0a256..e62c0ad 100644 --- a/cmdparse.h +++ b/cmdparse.h @@ -61,4 +61,7 @@ extern void CPS_NormalizeLine(char *line); /* Terminate first word and return pointer to the next word */ extern char *CPS_SplitWord(char *line); +/* Parse a key from keyfile */ +extern int CPS_ParseKey(char *line, unsigned long *id, const char **hash, char **key); + #endif /* GOT_CMDPARSE_H */ diff --git a/keys.c b/keys.c index c116ba9..edb9935 100644 --- a/keys.c +++ b/keys.c @@ -33,6 +33,7 @@ #include #include "keys.h" +#include "cmdparse.h" #include "conf.h" #include "memory.h" #include "util.h" @@ -104,7 +105,7 @@ determine_hash_delay(int key_id) } #if 0 - LOG(LOGS_INFO, LOGF_Keys, "authentication delay for key %d: %d useconds", key_id, min_usecs); + LOG(LOGS_INFO, LOGF_Keys, "authentication delay for key %lu: %d useconds", key_id, min_usecs); #endif /* Add on a bit extra to allow for copying, conversions etc */ @@ -133,87 +134,84 @@ compare_keys_by_id(const void *a, const void *b) /* ================================================== */ - -#define KEYLEN 2047 -#define SKEYLEN "2047" - void KEY_Reload(void) { - int i, len1, fields; - char *key_file; + int i, line_number; FILE *in; unsigned long key_id; - char line[KEYLEN+1], buf1[KEYLEN+1], buf2[KEYLEN+1]; - char *keyval, *hashname; + char line[2048], *keyval, *key_file; + const char *hashname; for (i=0; i= 2 && fields <= 3) { - if (fields == 3) { - hashname = buf1; - keyval = buf2; - } else { - hashname = "MD5"; - keyval = buf1; - } - keys[n_keys].hash_id = HSH_GetHashId(hashname); - if (keys[n_keys].hash_id < 0) { - LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %d", key_id); - continue; - } + in = fopen(key_file, "r"); + if (!in) { + LOG(LOGS_WARN, LOGF_Keys, "Could not open keyfile %s", key_file); + return; + } - 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; - } + while (fgets(line, sizeof (line), in)) { + line_number++; - keys[n_keys].id = key_id; - keys[n_keys].val = MallocArray(char, keys[n_keys].len); - memcpy(keys[n_keys].val, keyval, keys[n_keys].len); - n_keys++; - } - } - fclose(in); - - /* Sort keys into order. Note, if there's a duplicate, it is - arbitrary which one we use later - the user should have been - more careful! */ - qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id); + CPS_NormalizeLine(line); + if (!*line) + continue; - /* Erase the passwords from stack */ - memset(line, 0, sizeof (line)); - memset(buf1, 0, sizeof (buf1)); - memset(buf2, 0, sizeof (buf2)); + if (!CPS_ParseKey(line, &key_id, &hashname, &keyval)) { + LOG(LOGS_WARN, LOGF_Keys, "Could not parse key at line %d in file %s", line_number, key_file); + continue; + } + + keys[n_keys].hash_id = HSH_GetHashId(hashname); + if (keys[n_keys].hash_id < 0) { + LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %lu", key_id); + continue; + } + + keys[n_keys].len = UTI_DecodePasswordFromText(keyval); + if (!keys[n_keys].len) { + LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %lu", key_id); + continue; + } + + keys[n_keys].id = key_id; + keys[n_keys].val = MallocArray(char, keys[n_keys].len); + memcpy(keys[n_keys].val, keyval, keys[n_keys].len); + n_keys++; + } + + fclose(in); + + /* Sort keys into order. Note, if there's a duplicate, it is + arbitrary which one we use later - the user should have been + more careful! */ + qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id); + + /* Check for duplicates */ + for (i = 1; i < n_keys; i++) { + if (keys[i - 1].id == keys[i].id) { + LOG(LOGS_WARN, LOGF_Keys, "Detected duplicate key %lu", key_id); } } - command_key_valid = 0; - cache_valid = 0; + /* Erase any passwords from stack */ + memset(line, 0, sizeof (line)); for (i=0; i