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:
parent
ea3672df4e
commit
1c901b82dc
6 changed files with 105 additions and 5 deletions
|
@ -1177,6 +1177,7 @@ directives can occur in any order in the file.
|
||||||
* dumpdir directive:: Specify directory for dumping measurements
|
* dumpdir directive:: Specify directory for dumping measurements
|
||||||
* dumponexit directive:: Dump measurements when daemon exits
|
* dumponexit directive:: Dump measurements when daemon exits
|
||||||
* fallbackdrift directive:: Specify fallback drift intervals
|
* fallbackdrift directive:: Specify fallback drift intervals
|
||||||
|
* generatecommandkey directive:: Generate command key automatically
|
||||||
* include directive:: Include a configuration file
|
* include directive:: Include a configuration file
|
||||||
* initstepslew directive:: Trim the system clock on boot-up.
|
* initstepslew directive:: Trim the system clock on boot-up.
|
||||||
* keyfile directive:: Specify location of file containing keys
|
* 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
|
the form
|
||||||
|
|
||||||
@example
|
@example
|
||||||
20 foobar
|
20 MD5 HEX:B028F91EA5C38D06C2E140B26C7F41EC
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
When running the chronyc program to perform run-time configuration,
|
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
|
will be used and the clock frequency will stay at the last value
|
||||||
calculated before synchronisation was lost.
|
calculated before synchronisation was lost.
|
||||||
@c }}}
|
@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
|
@c {{{ include
|
||||||
@node include directive
|
@node include directive
|
||||||
@subsection include
|
@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:}
|
optional @code{ASCII:} prefix or as a hexadecimal number with @code{HEX:}
|
||||||
prefix.
|
prefix.
|
||||||
|
|
||||||
The ID for the chronyc authentication key is specified with the
|
The ID for the chronyc authentication key is specified with the commandkey
|
||||||
commandkey command (see earlier).
|
command (see earlier). The command key can be generated automatically on
|
||||||
|
start with the @code{generatecommandkey} directive.
|
||||||
@c }}}
|
@c }}}
|
||||||
@c {{{ leapsectz
|
@c {{{ leapsectz
|
||||||
@node leapsectz directive
|
@node leapsectz directive
|
||||||
|
|
21
conf.c
21
conf.c
|
@ -73,6 +73,7 @@ static void parse_driftfile(char *);
|
||||||
static void parse_dumpdir(char *);
|
static void parse_dumpdir(char *);
|
||||||
static void parse_dumponexit(char *);
|
static void parse_dumponexit(char *);
|
||||||
static void parse_fallbackdrift(char *);
|
static void parse_fallbackdrift(char *);
|
||||||
|
static void parse_generatecommandkey(char *);
|
||||||
static void parse_include(char *);
|
static void parse_include(char *);
|
||||||
static void parse_initstepslew(char *);
|
static void parse_initstepslew(char *);
|
||||||
static void parse_keyfile(char *);
|
static void parse_keyfile(char *);
|
||||||
|
@ -111,6 +112,7 @@ static void parse_user(char *);
|
||||||
/* Configuration variables */
|
/* Configuration variables */
|
||||||
|
|
||||||
static int restarted = 0;
|
static int restarted = 0;
|
||||||
|
static int generate_command_key = 0;
|
||||||
static char *rtc_device = "/dev/rtc";
|
static char *rtc_device = "/dev/rtc";
|
||||||
static int acquisition_port = 0; /* 0 means let kernel choose port */
|
static int acquisition_port = 0; /* 0 means let kernel choose port */
|
||||||
static int ntp_port = 123;
|
static int ntp_port = 123;
|
||||||
|
@ -386,6 +388,8 @@ CNF_ReadFile(const char *filename)
|
||||||
parse_dumponexit(p);
|
parse_dumponexit(p);
|
||||||
} else if (!strcasecmp(command, "fallbackdrift")) {
|
} else if (!strcasecmp(command, "fallbackdrift")) {
|
||||||
parse_fallbackdrift(p);
|
parse_fallbackdrift(p);
|
||||||
|
} else if (!strcasecmp(command, "generatecommandkey")) {
|
||||||
|
parse_generatecommandkey(p);
|
||||||
} else if (!strcasecmp(command, "include")) {
|
} else if (!strcasecmp(command, "include")) {
|
||||||
parse_include(p);
|
parse_include(p);
|
||||||
} else if (!strcasecmp(command, "initstepslew")) {
|
} 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
|
static void
|
||||||
parse_makestep(char *line)
|
parse_makestep(char *line)
|
||||||
{
|
{
|
||||||
|
@ -1563,6 +1576,14 @@ CNF_GetCommandKey(void)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
CNF_GetGenerateCommandKey(void)
|
||||||
|
{
|
||||||
|
return generate_command_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
CNF_GetDumpOnExit(void)
|
CNF_GetDumpOnExit(void)
|
||||||
{
|
{
|
||||||
|
|
1
conf.h
1
conf.h
|
@ -56,6 +56,7 @@ extern int CNF_GetLogTempComp(void);
|
||||||
extern char *CNF_GetKeysFile(void);
|
extern char *CNF_GetKeysFile(void);
|
||||||
extern char *CNF_GetRtcFile(void);
|
extern char *CNF_GetRtcFile(void);
|
||||||
extern unsigned long CNF_GetCommandKey(void);
|
extern unsigned long CNF_GetCommandKey(void);
|
||||||
|
extern int CNF_GetGenerateCommandKey(void);
|
||||||
extern int CNF_GetDumpOnExit(void);
|
extern int CNF_GetDumpOnExit(void);
|
||||||
extern int CNF_GetManualEnabled(void);
|
extern int CNF_GetManualEnabled(void);
|
||||||
extern int CNF_GetCommandPort(void);
|
extern int CNF_GetCommandPort(void);
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -518,6 +518,7 @@ if [ $try_nss = "1" ]; then
|
||||||
HASH_OBJ="hash_nss.o"
|
HASH_OBJ="hash_nss.o"
|
||||||
HASH_COMPILE="$test_cflags"
|
HASH_COMPILE="$test_cflags"
|
||||||
HASH_LINK="$test_link"
|
HASH_LINK="$test_link"
|
||||||
|
add_def GENERATE_SHA1_KEY
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -528,6 +529,7 @@ if [ "x$HASH_LINK" = "x" ] && [ $try_tomcrypt = "1" ]; then
|
||||||
HASH_OBJ="hash_tomcrypt.o"
|
HASH_OBJ="hash_tomcrypt.o"
|
||||||
HASH_COMPILE="-I/usr/include/tomcrypt"
|
HASH_COMPILE="-I/usr/include/tomcrypt"
|
||||||
HASH_LINK="-ltomcrypt"
|
HASH_LINK="-ltomcrypt"
|
||||||
|
add_def GENERATE_SHA1_KEY
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
64
keys.c
64
keys.c
|
@ -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
|
void
|
||||||
KEY_Initialise(void)
|
KEY_Initialise(void)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +127,12 @@ KEY_Initialise(void)
|
||||||
command_key_valid = 0;
|
command_key_valid = 0;
|
||||||
cache_valid = 0;
|
cache_valid = 0;
|
||||||
KEY_Reload();
|
KEY_Reload();
|
||||||
|
|
||||||
|
if (CNF_GetGenerateCommandKey() && !KEY_KeyKnown(KEY_GetCommandKey())) {
|
||||||
|
if (generate_key(KEY_GetCommandKey()))
|
||||||
|
KEY_Reload();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
main.c
4
main.c
|
@ -88,13 +88,13 @@ MAI_CleanupAndExit(void)
|
||||||
TMC_Finalise();
|
TMC_Finalise();
|
||||||
MNL_Finalise();
|
MNL_Finalise();
|
||||||
ACQ_Finalise();
|
ACQ_Finalise();
|
||||||
KEY_Finalise();
|
|
||||||
CLG_Finalise();
|
CLG_Finalise();
|
||||||
NSR_Finalise();
|
NSR_Finalise();
|
||||||
NCR_Finalise();
|
NCR_Finalise();
|
||||||
BRD_Finalise();
|
BRD_Finalise();
|
||||||
SST_Finalise();
|
SST_Finalise();
|
||||||
REF_Finalise();
|
REF_Finalise();
|
||||||
|
KEY_Finalise();
|
||||||
RCL_Finalise();
|
RCL_Finalise();
|
||||||
SRC_Finalise();
|
SRC_Finalise();
|
||||||
RTC_Finalise();
|
RTC_Finalise();
|
||||||
|
@ -383,6 +383,7 @@ int main
|
||||||
RTC_Initialise();
|
RTC_Initialise();
|
||||||
SRC_Initialise();
|
SRC_Initialise();
|
||||||
RCL_Initialise();
|
RCL_Initialise();
|
||||||
|
KEY_Initialise();
|
||||||
|
|
||||||
/* Command-line switch must have priority */
|
/* Command-line switch must have priority */
|
||||||
if (!sched_priority) {
|
if (!sched_priority) {
|
||||||
|
@ -411,7 +412,6 @@ int main
|
||||||
NCR_Initialise();
|
NCR_Initialise();
|
||||||
NSR_Initialise();
|
NSR_Initialise();
|
||||||
CLG_Initialise();
|
CLG_Initialise();
|
||||||
KEY_Initialise();
|
|
||||||
ACQ_Initialise();
|
ACQ_Initialise();
|
||||||
MNL_Initialise();
|
MNL_Initialise();
|
||||||
TMC_Initialise();
|
TMC_Initialise();
|
||||||
|
|
Loading…
Reference in a new issue