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 In the file @file{/etc/ppp/ip-up} we add the command sequence
@example @example
/usr/local/bin/chronyc <<EOF /usr/local/bin/chronyc -a online
password xyzzy
online
EOF
@end example @end example
and in the file @file{/etc/ppp/ip-down} we add the sequence and in the file @file{/etc/ppp/ip-down} we add the sequence
@example @example
/usr/local/bin/chronyc <<EOF /usr/local/bin/chronyc -a offline
password xyzzy
offline
EOF
@end example @end example
@code{chronyd's} polling of the servers will now only occur whilst the @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 @file{/etc/ppp/ip-up} and @file{/etc/ppp/ip-down} when the link goes
online and offline respectively. online and offline respectively.
The relevant part of the @file{/etc/ppp/ip-up} file is (with a dummy The relevant part of the @file{/etc/ppp/ip-up} file is
password)
@example @example
/usr/local/bin/chronyc <<EOF /usr/local/bin/chronyc -a online
password xxxxxxxx
online
EOF
@end example @end example
and the relevant part of the @file{/etc/ppp/ip-down} script is and the relevant part of the @file{/etc/ppp/ip-down} script is
@example @example
/usr/local/bin/chronyc <<EOF /usr/local/bin/chronyc -a <<EOF
password xxxxxxxx
offline offline
dump dump
writertc writertc
@ -1484,7 +1473,8 @@ password foobar
@end example @end example
must be entered before any commands affecting the operation of the 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 }}}
@c {{{ cmdport @c {{{ cmdport
@node cmdport directive @node cmdport directive
@ -2957,6 +2947,14 @@ With this option hostnames will be resolved only to IPv6 addresses.
@item -m @item -m
With this option multiple commands can be specified on the command line. With this option multiple commands can be specified on the command line.
Each argument will be interpreted as a whole command. 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 @end table
@c }}} @c }}}
@c {{{ SS:Security with chronyc @c {{{ SS:Security with chronyc
@ -3188,6 +3186,9 @@ An example is
@example @example
authhash SHA1 authhash SHA1
@end example @end example
The authhash command is run automatically on start if @code{chronyc} was
started with the `-a' option.
@c }}} @c }}}
@c {{{ burst @c {{{ burst
@node burst command @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:} 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 prefix. It has to match @code{chronyd's} currently defined command key
(@pxref{commandkey directive}). (@pxref{commandkey directive}).
The password command is run automatically on start if @code{chronyc} was
started with the `-a' option.
@c }}} @c }}}
@c {{{ polltarget @c {{{ polltarget
@node polltarget command @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 allow multiple commands to be specified on the command line. Each argument
will be interpreted as a whole command. will be interpreted as a whole command.
.TP .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 \fIcommand\fR
specify command. If no command is given, chronyc will read commands specify command. If no command is given, chronyc will read commands
interactively. interactively.

View file

@ -2512,9 +2512,9 @@ process_cmd_dns(const char *line)
/* ================================================== */ /* ================================================== */
static int static int
process_cmd_authhash(char *line) process_cmd_authhash(const char *line)
{ {
char *hash_name; const char *hash_name;
int new_hash_id; int new_hash_id;
assert(auth_hash_id >= 0); 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 static int
process_args(int argc, char **argv, int multi) process_args(int argc, char **argv, int multi)
{ {
@ -2804,7 +2875,8 @@ main(int argc, char **argv)
char *line; char *line;
const char *progname = argv[0]; const char *progname = argv[0];
const char *hostname = "localhost"; 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; int port = DEFAULT_CANDM_PORT;
/* Parse command line options */ /* Parse command line options */
@ -2819,6 +2891,13 @@ main(int argc, char **argv)
if (*argv) { if (*argv) {
port = atoi(*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")) { } else if (!strcmp(*argv, "-m")) {
multi = 1; multi = 1;
} else if (!strcmp(*argv, "-n")) { } else if (!strcmp(*argv, "-n")) {
@ -2833,7 +2912,7 @@ main(int argc, char **argv)
printf("chronyc (chrony) version %s\n", CHRONY_VERSION); printf("chronyc (chrony) version %s\n", CHRONY_VERSION);
exit(0); exit(0);
} else if (!strncmp(*argv, "-", 1)) { } 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); exit(1);
} else { } else {
break; /* And process remainder of line as a command */ break; /* And process remainder of line as a command */
@ -2857,7 +2936,13 @@ main(int argc, char **argv)
open_io(hostname, port); 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); ret = process_args(argc, argv, multi);
} else { } else {
do { do {