keys: allocate keys dynamically

This removes the limit on maximum number of keys in the key file.
This commit is contained in:
Miroslav Lichvar 2014-09-24 13:47:52 +02:00
parent ba875fc04a
commit cd27860e55

129
keys.c
View file

@ -30,6 +30,7 @@
#include "sysincl.h" #include "sysincl.h"
#include "array.h"
#include "keys.h" #include "keys.h"
#include "cmdparse.h" #include "cmdparse.h"
#include "conf.h" #include "conf.h"
@ -47,10 +48,7 @@ typedef struct {
int auth_delay; int auth_delay;
} Key; } Key;
#define MAX_KEYS 256 static ARR_Instance keys;
static int n_keys;
static Key keys[MAX_KEYS];
static int command_key_valid; static int command_key_valid;
static int command_key_id; static int command_key_id;
@ -118,10 +116,25 @@ generate_key(unsigned long key_id)
/* ================================================== */ /* ================================================== */
static void
free_keys(void)
{
unsigned int i;
for (i = 0; i < ARR_GetSize(keys); i++)
Free(((Key *)ARR_GetElement(keys, i))->val);
ARR_SetSize(keys, 0);
command_key_valid = 0;
cache_valid = 0;
}
/* ================================================== */
void void
KEY_Initialise(void) KEY_Initialise(void)
{ {
n_keys = 0; keys = ARR_CreateInstance(sizeof (Key));
command_key_valid = 0; command_key_valid = 0;
cache_valid = 0; cache_valid = 0;
KEY_Reload(); KEY_Reload();
@ -137,11 +150,16 @@ KEY_Initialise(void)
void void
KEY_Finalise(void) KEY_Finalise(void)
{ {
int i; free_keys();
ARR_DestroyInstance(keys);
}
for (i=0; i<n_keys; i++) { /* ================================================== */
Free(keys[i].val);
} static Key *
get_key(unsigned int index)
{
return ((Key *)ARR_GetElements(keys)) + index;
} }
/* ================================================== */ /* ================================================== */
@ -200,18 +218,14 @@ compare_keys_by_id(const void *a, const void *b)
void void
KEY_Reload(void) KEY_Reload(void)
{ {
int i, line_number; unsigned int i, line_number;
FILE *in; FILE *in;
unsigned long key_id; unsigned long key_id;
char line[2048], *keyval, *key_file; char line[2048], *keyval, *key_file;
const char *hashname; const char *hashname;
Key key;
for (i=0; i<n_keys; i++) { free_keys();
Free(keys[i].val);
}
n_keys = 0;
command_key_valid = 0;
cache_valid = 0;
key_file = CNF_GetKeysFile(); key_file = CNF_GetKeysFile();
line_number = 0; line_number = 0;
@ -237,22 +251,22 @@ KEY_Reload(void)
continue; continue;
} }
keys[n_keys].hash_id = HSH_GetHashId(hashname); key.hash_id = HSH_GetHashId(hashname);
if (keys[n_keys].hash_id < 0) { if (key.hash_id < 0) {
LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %lu", key_id); LOG(LOGS_WARN, LOGF_Keys, "Unknown hash function in key %lu", key_id);
continue; continue;
} }
keys[n_keys].len = UTI_DecodePasswordFromText(keyval); key.len = UTI_DecodePasswordFromText(keyval);
if (!keys[n_keys].len) { if (!key.len) {
LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %lu", key_id); LOG(LOGS_WARN, LOGF_Keys, "Could not decode password in key %lu", key_id);
continue; continue;
} }
keys[n_keys].id = key_id; key.id = key_id;
keys[n_keys].val = MallocArray(char, keys[n_keys].len); key.val = MallocArray(char, key.len);
memcpy(keys[n_keys].val, keyval, keys[n_keys].len); memcpy(key.val, keyval, key.len);
n_keys++; ARR_AppendElement(keys, &key);
} }
fclose(in); fclose(in);
@ -260,21 +274,19 @@ KEY_Reload(void)
/* Sort keys into order. Note, if there's a duplicate, it is /* Sort keys into order. Note, if there's a duplicate, it is
arbitrary which one we use later - the user should have been arbitrary which one we use later - the user should have been
more careful! */ more careful! */
qsort((void *) keys, n_keys, sizeof(Key), compare_keys_by_id); qsort(ARR_GetElements(keys), ARR_GetSize(keys), sizeof (Key), compare_keys_by_id);
/* Check for duplicates */ /* Check for duplicates */
for (i = 1; i < n_keys; i++) { for (i = 1; i < ARR_GetSize(keys); i++) {
if (keys[i - 1].id == keys[i].id) { if (get_key(i - 1)->id == get_key(i)->id)
LOG(LOGS_WARN, LOGF_Keys, "Detected duplicate key %lu", keys[i].id); LOG(LOGS_WARN, LOGF_Keys, "Detected duplicate key %lu", get_key(i - 1)->id);
}
} }
/* Erase any passwords from stack */ /* Erase any passwords from stack */
memset(line, 0, sizeof (line)); memset(line, 0, sizeof (line));
for (i=0; i<n_keys; i++) { for (i = 0; i < ARR_GetSize(keys); i++)
keys[i].auth_delay = determine_hash_delay(keys[i].id); get_key(i)->auth_delay = determine_hash_delay(get_key(i)->id);
}
} }
/* ================================================== */ /* ================================================== */
@ -282,28 +294,30 @@ KEY_Reload(void)
static int static int
lookup_key(unsigned long id) lookup_key(unsigned long id)
{ {
Key specimen, *where; Key specimen, *where, *keys_ptr;
int pos; int pos;
keys_ptr = ARR_GetElements(keys);
specimen.id = id; specimen.id = id;
where = (Key *) bsearch((void *)&specimen, (void *)keys, n_keys, sizeof(Key), compare_keys_by_id); where = (Key *)bsearch((void *)&specimen, keys_ptr, ARR_GetSize(keys),
sizeof (Key), compare_keys_by_id);
if (!where) { if (!where) {
return -1; return -1;
} else { } else {
pos = where - keys; pos = where - keys_ptr;
return pos; return pos;
} }
} }
/* ================================================== */ /* ================================================== */
static int static Key *
get_key_pos(unsigned long key_id) get_key_by_id(unsigned long key_id)
{ {
int position; int position;
if (cache_valid && key_id == cache_key_id) if (cache_valid && key_id == cache_key_id)
return cache_key_pos; return get_key(cache_key_pos);
position = lookup_key(key_id); position = lookup_key(key_id);
@ -311,9 +325,11 @@ get_key_pos(unsigned long key_id)
cache_valid = 1; cache_valid = 1;
cache_key_pos = position; cache_key_pos = position;
cache_key_id = key_id; cache_key_id = key_id;
return get_key(position);
} }
return position; return NULL;
} }
/* ================================================== */ /* ================================================== */
@ -333,7 +349,7 @@ KEY_GetCommandKey(void)
int int
KEY_KeyKnown(unsigned long key_id) KEY_KeyKnown(unsigned long key_id)
{ {
return get_key_pos(key_id) >= 0; return get_key_by_id(key_id) != NULL;
} }
/* ================================================== */ /* ================================================== */
@ -341,15 +357,14 @@ KEY_KeyKnown(unsigned long key_id)
int int
KEY_GetAuthDelay(unsigned long key_id) KEY_GetAuthDelay(unsigned long key_id)
{ {
int key_pos; Key *key;
key_pos = get_key_pos(key_id); key = get_key_by_id(key_id);
if (key_pos < 0) { if (!key)
return 0; return 0;
}
return keys[key_pos].auth_delay; return key->auth_delay;
} }
/* ================================================== */ /* ================================================== */
@ -358,17 +373,15 @@ int
KEY_GenerateAuth(unsigned long key_id, const unsigned char *data, int data_len, KEY_GenerateAuth(unsigned long key_id, const unsigned char *data, int data_len,
unsigned char *auth, int auth_len) unsigned char *auth, int auth_len)
{ {
int key_pos; Key *key;
key_pos = get_key_pos(key_id); key = get_key_by_id(key_id);
if (key_pos < 0) { if (!key)
return 0; return 0;
}
return UTI_GenerateNTPAuth(keys[key_pos].hash_id, return UTI_GenerateNTPAuth(key->hash_id, (unsigned char *)key->val,
(unsigned char *)keys[key_pos].val, keys[key_pos].len, key->len, data, data_len, auth, auth_len);
data, data_len, auth, auth_len);
} }
/* ================================================== */ /* ================================================== */
@ -377,15 +390,13 @@ int
KEY_CheckAuth(unsigned long key_id, const unsigned char *data, int data_len, KEY_CheckAuth(unsigned long key_id, const unsigned char *data, int data_len,
const unsigned char *auth, int auth_len) const unsigned char *auth, int auth_len)
{ {
int key_pos; Key *key;
key_pos = get_key_pos(key_id); key = get_key_by_id(key_id);
if (key_pos < 0) { if (!key)
return 0; return 0;
}
return UTI_CheckNTPAuth(keys[key_pos].hash_id, return UTI_CheckNTPAuth(key->hash_id, (unsigned char *)key->val,
(unsigned char *)keys[key_pos].val, keys[key_pos].len, key->len, data, data_len, auth, auth_len);
data, data_len, auth, auth_len);
} }