Add option to authenticate automatically on chronyc start

This commit is contained in:
Miroslav Lichvar 2013-05-15 19:25:15 +02:00
parent 9673a2726c
commit ae1e3bf73c
3 changed files with 121 additions and 22 deletions

View file

@ -699,19 +699,13 @@ previous section.
In the file @file{/etc/ppp/ip-up} we add the command sequence
@example
/usr/local/bin/chronyc <<EOF
password xyzzy
online
EOF
/usr/local/bin/chronyc -a online
@end example
and in the file @file{/etc/ppp/ip-down} we add the sequence
@example
/usr/local/bin/chronyc <<EOF
password xyzzy
offline
EOF
/usr/local/bin/chronyc -a offline
@end example
@code{chronyd's} polling of the servers will now only occur whilst the
@ -927,21 +921,16 @@ I use @code{pppd} for connecting to my ISP. This runs two scripts
@file{/etc/ppp/ip-up} and @file{/etc/ppp/ip-down} when the link goes
online and offline respectively.
The relevant part of the @file{/etc/ppp/ip-up} file is (with a dummy
password)
The relevant part of the @file{/etc/ppp/ip-up} file is
@example
/usr/local/bin/chronyc <<EOF
password xxxxxxxx
online
EOF
/usr/local/bin/chronyc -a online
@end example
and the relevant part of the @file{/etc/ppp/ip-down} script is
@example
/usr/local/bin/chronyc <<EOF
password xxxxxxxx
/usr/local/bin/chronyc -a <<EOF
offline
dump
writertc
@ -1484,7 +1473,8 @@ password foobar
@end example
must be entered before any commands affecting the operation of the
daemon can be entered.
daemon can be entered, or chronyc must be started with the `-a' option to run
the password command automatically.
@c }}}
@c {{{ cmdport
@node cmdport directive
@ -2957,6 +2947,14 @@ With this option hostnames will be resolved only to IPv6 addresses.
@item -m
With this option multiple commands can be specified on the command line.
Each argument will be interpreted as a whole command.
@item -f <conf-file>
This option can be used to specify an alternate location of the @code{chronyd}
configuration file (default @file{/etc/chrony.conf}). The configuration file is
needed for the `-a' option.
@item -a
With this option @code{chronyc} will try to authenticate automatically on
start. It will read the configuration file, read the command key from the
keyfile and run the authhash and password commands.
@end table
@c }}}
@c {{{ SS:Security with chronyc
@ -3188,6 +3186,9 @@ An example is
@example
authhash SHA1
@end example
The authhash command is run automatically on start if @code{chronyc} was
started with the `-a' option.
@c }}}
@c {{{ burst
@node burst command
@ -3858,6 +3859,9 @@ The 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. It has to match @code{chronyd's} currently defined command key
(@pxref{commandkey directive}).
The password command is run automatically on start if @code{chronyc} was
started with the `-a' option.
@c }}}
@c {{{ polltarget
@node polltarget command

View file

@ -42,6 +42,16 @@ resolve hostnames only to IPv6 addresses
allow multiple commands to be specified on the command line. Each argument
will be interpreted as a whole command.
.TP
\fB\-f\fR \fIconf-file\fR
This option can be used to specify an alternate location for the
configuration file (default \fI/etc/chrony.conf\fR). The configuration file is
needed for the \fB-a\fR option.
.TP
\fB\-a\fR
With this option chronyc will try to authenticate automatically on
start. It will read the configuration file, read the command key from the
keyfile and run the authhash and password commands.
.TP
\fIcommand\fR
specify command. If no command is given, chronyc will read commands
interactively.

View file

@ -2512,9 +2512,9 @@ process_cmd_dns(const char *line)
/* ================================================== */
static int
process_cmd_authhash(char *line)
process_cmd_authhash(const char *line)
{
char *hash_name;
const char *hash_name;
int new_hash_id;
assert(auth_hash_id >= 0);
@ -2748,6 +2748,77 @@ process_line(char *line, int *quit)
/* ================================================== */
static int
authenticate_from_config(const char *filename)
{
CMD_Request tx_message;
CMD_Reply rx_message;
char line[2048], keyfile[2048], *command, *arg, *password;
const char *hashname;
unsigned long key_id = 0, key_id2 = -1;
int ret;
FILE *in;
in = fopen(filename, "r");
if (!in) {
fprintf(stderr, "Could not open file %s\n", filename);
return 0;
}
*keyfile = '\0';
while (fgets(line, sizeof (line), in)) {
CPS_NormalizeLine(line);
command = line;
arg = CPS_SplitWord(line);
if (!strcasecmp(command, "keyfile")) {
snprintf(keyfile, sizeof (keyfile), "%s", arg);
} else if (!strcasecmp(command, "commandkey")) {
if (sscanf(arg, "%lu", &key_id) != 1)
key_id = -1;
}
}
fclose(in);
if (!*keyfile || key_id == -1) {
fprintf(stderr, "Could not read keyfile or commandkey in file %s\n", filename);
return 0;
}
in = fopen(keyfile, "r");
if (!in) {
fprintf(stderr, "Could not open keyfile %s\n", filename);
return 0;
}
while (fgets(line, sizeof (line), in)) {
CPS_NormalizeLine(line);
if (!*line || !CPS_ParseKey(line, &key_id2, &hashname, &password))
continue;
if (key_id == key_id2)
break;
}
fclose(in);
if (key_id == key_id2) {
if (process_cmd_authhash(hashname) &&
process_cmd_password(&tx_message, password)) {
ret = request_reply(&tx_message, &rx_message, RPY_NULL, 1);
} else {
ret = 0;
}
} else {
fprintf(stderr, "Could not find key %lu in keyfile %s\n", key_id, keyfile);
ret = 0;
}
/* Erase password from stack */
memset(line, sizeof (line), 0);
return ret;
}
/* ================================================== */
static int
process_args(int argc, char **argv, int multi)
{
@ -2804,7 +2875,8 @@ main(int argc, char **argv)
char *line;
const char *progname = argv[0];
const char *hostname = "localhost";
int quit = 0, ret = 1, multi = 0;
const char *conf_file = DEFAULT_CONF_FILE;
int quit = 0, ret = 1, multi = 0, auto_auth = 0;
int port = DEFAULT_CANDM_PORT;
/* Parse command line options */
@ -2819,6 +2891,13 @@ main(int argc, char **argv)
if (*argv) {
port = atoi(*argv);
}
} else if (!strcmp(*argv, "-f")) {
++argv, --argc;
if (*argv) {
conf_file = *argv;
}
} else if (!strcmp(*argv, "-a")) {
auto_auth = 1;
} else if (!strcmp(*argv, "-m")) {
multi = 1;
} else if (!strcmp(*argv, "-n")) {
@ -2833,7 +2912,7 @@ main(int argc, char **argv)
printf("chronyc (chrony) version %s\n", CHRONY_VERSION);
exit(0);
} else if (!strncmp(*argv, "-", 1)) {
fprintf(stderr, "Usage : %s [-h <hostname>] [-p <port-number>] [-n] [-4|-6] [-m] [command]\n", progname);
fprintf(stderr, "Usage : %s [-h <hostname>] [-p <port-number>] [-n] [-4|-6] [-m] [-a] [-f <file>]] [command]\n", progname);
exit(1);
} else {
break; /* And process remainder of line as a command */
@ -2857,7 +2936,13 @@ main(int argc, char **argv)
open_io(hostname, port);
if (argc > 0) {
if (auto_auth) {
ret = authenticate_from_config(conf_file);
}
if (!ret) {
;
} else if (argc > 0) {
ret = process_args(argc, argv, multi);
} else {
do {