Refactor key parsing

This commit is contained in:
Miroslav Lichvar 2013-05-15 16:38:01 +02:00
parent 02524397c1
commit 9673a2726c
3 changed files with 89 additions and 58 deletions

View file

@ -248,3 +248,33 @@ CPS_SplitWord(char *line)
/* Return pointer to the next word or NUL */ /* Return pointer to the next word or NUL */
return q; 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;
}

View file

@ -61,4 +61,7 @@ extern void CPS_NormalizeLine(char *line);
/* Terminate first word and return pointer to the next word */ /* Terminate first word and return pointer to the next word */
extern char *CPS_SplitWord(char *line); 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 */ #endif /* GOT_CMDPARSE_H */

72
keys.c
View file

@ -33,6 +33,7 @@
#include <string.h> #include <string.h>
#include "keys.h" #include "keys.h"
#include "cmdparse.h"
#include "conf.h" #include "conf.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
@ -104,7 +105,7 @@ determine_hash_delay(int key_id)
} }
#if 0 #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 #endif
/* Add on a bit extra to allow for copying, conversions etc */ /* Add on a bit extra to allow for copying, conversions etc */
@ -133,56 +134,55 @@ compare_keys_by_id(const void *a, const void *b)
/* ================================================== */ /* ================================================== */
#define KEYLEN 2047
#define SKEYLEN "2047"
void void
KEY_Reload(void) KEY_Reload(void)
{ {
int i, len1, fields; int i, line_number;
char *key_file;
FILE *in; FILE *in;
unsigned long key_id; unsigned long key_id;
char line[KEYLEN+1], buf1[KEYLEN+1], buf2[KEYLEN+1]; char line[2048], *keyval, *key_file;
char *keyval, *hashname; const char *hashname;
for (i=0; i<n_keys; i++) { for (i=0; i<n_keys; i++) {
Free(keys[i].val); Free(keys[i].val);
} }
n_keys = 0; n_keys = 0;
command_key_valid = 0;
cache_valid = 0;
key_file = CNF_GetKeysFile(); key_file = CNF_GetKeysFile();
line_number = 0;
if (!key_file)
return;
if (key_file) {
in = fopen(key_file, "r"); in = fopen(key_file, "r");
if (in) { if (!in) {
while (fgets(line, sizeof(line), in)) { LOG(LOGS_WARN, LOGF_Keys, "Could not open keyfile %s", key_file);
len1 = strlen(line) - 1; return;
}
/* Guard against removing last character of the line while (fgets(line, sizeof (line), in)) {
* if the last line of the file is missing an end-of-line */ line_number++;
if (line[len1] == '\n') {
line[len1] = '\0'; CPS_NormalizeLine(line);
} if (!*line)
fields = sscanf(line, "%lu%" SKEYLEN "s%" SKEYLEN "s", &key_id, buf1, buf2); continue;
if (fields >= 2 && fields <= 3) {
if (fields == 3) { if (!CPS_ParseKey(line, &key_id, &hashname, &keyval)) {
hashname = buf1; LOG(LOGS_WARN, LOGF_Keys, "Could not parse key at line %d in file %s", line_number, key_file);
keyval = buf2; continue;
} else {
hashname = "MD5";
keyval = buf1;
} }
keys[n_keys].hash_id = HSH_GetHashId(hashname); keys[n_keys].hash_id = HSH_GetHashId(hashname);
if (keys[n_keys].hash_id < 0) { if (keys[n_keys].hash_id < 0) {
LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %d", key_id); LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %lu", key_id);
continue; continue;
} }
keys[n_keys].len = UTI_DecodePasswordFromText(keyval); keys[n_keys].len = UTI_DecodePasswordFromText(keyval);
if (!keys[n_keys].len) { if (!keys[n_keys].len) {
LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %d", key_id); LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %lu", key_id);
continue; continue;
} }
@ -191,7 +191,7 @@ KEY_Reload(void)
memcpy(keys[n_keys].val, keyval, keys[n_keys].len); memcpy(keys[n_keys].val, keyval, keys[n_keys].len);
n_keys++; n_keys++;
} }
}
fclose(in); fclose(in);
/* Sort keys into order. Note, if there's a duplicate, it is /* Sort keys into order. Note, if there's a duplicate, it is
@ -199,21 +199,19 @@ KEY_Reload(void)
more careful! */ more careful! */
qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id); qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id);
/* Erase the passwords from stack */ /* Check for duplicates */
memset(line, 0, sizeof (line)); for (i = 1; i < n_keys; i++) {
memset(buf1, 0, sizeof (buf1)); if (keys[i - 1].id == keys[i].id) {
memset(buf2, 0, sizeof (buf2)); LOG(LOGS_WARN, LOGF_Keys, "Detected duplicate key %lu", key_id);
} }
} }
command_key_valid = 0; /* Erase any passwords from stack */
cache_valid = 0; memset(line, 0, sizeof (line));
for (i=0; i<n_keys; i++) { for (i=0; i<n_keys; i++) {
keys[i].auth_delay = determine_hash_delay(keys[i].id); keys[i].auth_delay = determine_hash_delay(keys[i].id);
} }
return;
} }
/* ================================================== */ /* ================================================== */