keys: allocate keys dynamically
This removes the limit on maximum number of keys in the key file.
This commit is contained in:
parent
ba875fc04a
commit
cd27860e55
1 changed files with 70 additions and 59 deletions
129
keys.c
129
keys.c
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue