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
@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
@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
@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
@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
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
/* ================================================== */
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);
/* ================================================== */
+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)
{
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 */
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")) {
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 */
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 {