Add option to generate command key on start

With generatecommandkey directive, if no command key is found in the key
file on start, one will be generated automatically from /dev/urandom.
This commit is contained in:
Miroslav Lichvar 2013-05-21 13:58:52 +02:00
parent ea3672df4e
commit 1c901b82dc
6 changed files with 105 additions and 5 deletions

View file

@ -1177,6 +1177,7 @@ directives can occur in any order in the file.
* dumpdir directive:: Specify directory for dumping measurements
* dumponexit directive:: Dump measurements when daemon exits
* fallbackdrift directive:: Specify fallback drift intervals
* generatecommandkey directive:: Generate command key automatically
* include directive:: Include a configuration file
* initstepslew directive:: Trim the system clock on boot-up.
* keyfile directive:: Specify location of file containing keys
@ -1466,7 +1467,7 @@ In the key file (see the keyfile command) there should be a line of
the form
@example
20 foobar
20 MD5 HEX:B028F91EA5C38D06C2E140B26C7F41EC
@end example
When running the chronyc program to perform run-time configuration,
@ -1638,6 +1639,16 @@ By default (or if the specified maximum or minimum is 0), no fallbacks
will be used and the clock frequency will stay at the last value
calculated before synchronisation was lost.
@c }}}
@c {{{ generatecommandkey
@node generatecommandkey directive
@subsection generatecommandkey
With this directive, if the command key is not found on start in the file
specified by the @code{keyfile} directive, @code{chronyd} will generate a new
command key from the /dev/urandom file and write it to the key file.
The generated key will use SHA1 if @code{chronyd} is compiled with the support,
otherwise MD5 will be used.
@c }}}
@c {{{ include
@node include directive
@subsection include
@ -1744,8 +1755,9 @@ 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).
The ID for the chronyc authentication key is specified with the commandkey
command (see earlier). The command key can be generated automatically on
start with the @code{generatecommandkey} directive.
@c }}}
@c {{{ leapsectz
@node leapsectz directive

21
conf.c
View file

@ -73,6 +73,7 @@ static void parse_driftfile(char *);
static void parse_dumpdir(char *);
static void parse_dumponexit(char *);
static void parse_fallbackdrift(char *);
static void parse_generatecommandkey(char *);
static void parse_include(char *);
static void parse_initstepslew(char *);
static void parse_keyfile(char *);
@ -111,6 +112,7 @@ static void parse_user(char *);
/* Configuration variables */
static int restarted = 0;
static int generate_command_key = 0;
static char *rtc_device = "/dev/rtc";
static int acquisition_port = 0; /* 0 means let kernel choose port */
static int ntp_port = 123;
@ -386,6 +388,8 @@ CNF_ReadFile(const char *filename)
parse_dumponexit(p);
} else if (!strcasecmp(command, "fallbackdrift")) {
parse_fallbackdrift(p);
} else if (!strcasecmp(command, "generatecommandkey")) {
parse_generatecommandkey(p);
} else if (!strcasecmp(command, "include")) {
parse_include(p);
} else if (!strcasecmp(command, "initstepslew")) {
@ -999,6 +1003,15 @@ parse_fallbackdrift(char *line)
/* ================================================== */
static void
parse_generatecommandkey(char *line)
{
check_number_of_args(line, 0);
generate_command_key = 1;
}
/* ================================================== */
static void
parse_makestep(char *line)
{
@ -1563,6 +1576,14 @@ CNF_GetCommandKey(void)
/* ================================================== */
int
CNF_GetGenerateCommandKey(void)
{
return generate_command_key;
}
/* ================================================== */
int
CNF_GetDumpOnExit(void)
{

1
conf.h
View file

@ -56,6 +56,7 @@ extern int CNF_GetLogTempComp(void);
extern char *CNF_GetKeysFile(void);
extern char *CNF_GetRtcFile(void);
extern unsigned long CNF_GetCommandKey(void);
extern int CNF_GetGenerateCommandKey(void);
extern int CNF_GetDumpOnExit(void);
extern int CNF_GetManualEnabled(void);
extern int CNF_GetCommandPort(void);

2
configure vendored
View file

@ -518,6 +518,7 @@ if [ $try_nss = "1" ]; then
HASH_OBJ="hash_nss.o"
HASH_COMPILE="$test_cflags"
HASH_LINK="$test_link"
add_def GENERATE_SHA1_KEY
fi
fi
@ -528,6 +529,7 @@ if [ "x$HASH_LINK" = "x" ] && [ $try_tomcrypt = "1" ]; then
HASH_OBJ="hash_tomcrypt.o"
HASH_COMPILE="-I/usr/include/tomcrypt"
HASH_LINK="-ltomcrypt"
add_def GENERATE_SHA1_KEY
fi
fi

64
keys.c
View file

@ -62,6 +62,64 @@ static int cache_key_pos;
/* ================================================== */
static int
generate_key(unsigned long key_id)
{
#ifdef GENERATE_SHA1_KEY
unsigned char key[20];
const char *hashname = "SHA1";
#else
unsigned char key[16];
const char *hashname = "MD5";
#endif
const char *key_file, *rand_dev = "/dev/urandom";
FILE *f;
struct stat st;
int i;
key_file = CNF_GetKeysFile();
if (!key_file)
return 0;
f = fopen(rand_dev, "r");
if (!f || fread(key, sizeof (key), 1, f) != 1) {
if (f)
fclose(f);
LOG_FATAL(LOGF_Keys, "Could not read %s", rand_dev);
return 0;
}
fclose(f);
f = fopen(key_file, "a");
if (!f) {
LOG_FATAL(LOGF_Keys, "Could not open keyfile %s for writing", key_file);
return 0;
}
/* Make sure the keyfile is not world-readable */
if (stat(key_file, &st) || chmod(key_file, st.st_mode & 0770)) {
fclose(f);
LOG_FATAL(LOGF_Keys, "Could not change permissions of keyfile %s", key_file);
return 0;
}
fprintf(f, "\n%lu %s HEX:", key_id, hashname);
for (i = 0; i < sizeof (key); i++)
fprintf(f, "%02hhX", key[i]);
fprintf(f, "\n");
fclose(f);
/* Erase the key from stack */
memset(key, sizeof (key), 0);
LOG(LOGS_INFO, LOGF_Keys, "Generated key %lu", key_id);
return 1;
}
/* ================================================== */
void
KEY_Initialise(void)
{
@ -69,6 +127,12 @@ KEY_Initialise(void)
command_key_valid = 0;
cache_valid = 0;
KEY_Reload();
if (CNF_GetGenerateCommandKey() && !KEY_KeyKnown(KEY_GetCommandKey())) {
if (generate_key(KEY_GetCommandKey()))
KEY_Reload();
}
return;
}

4
main.c
View file

@ -88,13 +88,13 @@ MAI_CleanupAndExit(void)
TMC_Finalise();
MNL_Finalise();
ACQ_Finalise();
KEY_Finalise();
CLG_Finalise();
NSR_Finalise();
NCR_Finalise();
BRD_Finalise();
SST_Finalise();
REF_Finalise();
KEY_Finalise();
RCL_Finalise();
SRC_Finalise();
RTC_Finalise();
@ -383,6 +383,7 @@ int main
RTC_Initialise();
SRC_Initialise();
RCL_Initialise();
KEY_Initialise();
/* Command-line switch must have priority */
if (!sched_priority) {
@ -411,7 +412,6 @@ int main
NCR_Initialise();
NSR_Initialise();
CLG_Initialise();
KEY_Initialise();
ACQ_Initialise();
MNL_Initialise();
TMC_Initialise();