client: remove authentication support
Follow the removal of the server authentication support and remove also the client support. The -a and -f options are now silently ignored to not break scripts. The authhash and password commands print a warning, but they don't return an error.
This commit is contained in:
parent
49846b3e68
commit
b11ca92ca6
1 changed files with 19 additions and 276 deletions
293
client.c
293
client.c
|
@ -35,7 +35,6 @@
|
|||
#include "logging.h"
|
||||
#include "memory.h"
|
||||
#include "nameserv.h"
|
||||
#include "hash.h"
|
||||
#include "getdate.h"
|
||||
#include "cmdparse.h"
|
||||
#include "pktlength.h"
|
||||
|
@ -1179,97 +1178,6 @@ process_cmd_delete(CMD_Request *msg, char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static char *password = NULL;
|
||||
static int password_length;
|
||||
static int auth_hash_id;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_password(CMD_Request *msg, char *line)
|
||||
{
|
||||
char *p;
|
||||
struct timeval now;
|
||||
int i, len;
|
||||
|
||||
/* Blank and free the old password */
|
||||
if (password) {
|
||||
for (i = 0; i < password_length; i++)
|
||||
password[i] = 0;
|
||||
Free(password);
|
||||
password = NULL;
|
||||
}
|
||||
|
||||
p = line;
|
||||
|
||||
if (!*p) {
|
||||
/* blank line, prompt for password */
|
||||
p = getpass("Password: ");
|
||||
}
|
||||
|
||||
if (!*p)
|
||||
return 0;
|
||||
|
||||
len = strlen(p);
|
||||
password_length = UTI_DecodePasswordFromText(p);
|
||||
|
||||
if (password_length > 0) {
|
||||
password = Malloc(password_length);
|
||||
memcpy(password, p, password_length);
|
||||
}
|
||||
|
||||
/* Erase the password from the input or getpass buffer */
|
||||
for (i = 0; i < len; i++)
|
||||
p[i] = 0;
|
||||
|
||||
if (password_length <= 0) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not decode password");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
printf("500 - Could not read time of day\n");
|
||||
return 0;
|
||||
} else {
|
||||
msg->command = htons(REQ_LOGON); /* Just force a round trip so that we get tokens etc */
|
||||
UTI_TimevalHostToNetwork(&now, &msg->data.logon.ts);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
generate_auth(CMD_Request *msg)
|
||||
{
|
||||
int data_len;
|
||||
|
||||
data_len = PKL_CommandLength(msg);
|
||||
|
||||
assert(auth_hash_id >= 0);
|
||||
|
||||
return UTI_GenerateNTPAuth(auth_hash_id, (unsigned char *)password, password_length,
|
||||
(unsigned char *)msg, data_len, ((unsigned char *)msg) + data_len, sizeof (msg->auth));
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
check_reply_auth(CMD_Reply *msg, int len)
|
||||
{
|
||||
int data_len;
|
||||
|
||||
data_len = PKL_ReplyLength(msg);
|
||||
|
||||
assert(auth_hash_id >= 0);
|
||||
|
||||
return UTI_CheckNTPAuth(auth_hash_id, (unsigned char *)password, password_length,
|
||||
(unsigned char *)msg, data_len,
|
||||
((unsigned char *)msg) + data_len, len - data_len);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
give_help(void)
|
||||
{
|
||||
|
@ -1306,7 +1214,6 @@ give_help(void)
|
|||
printf("minstratum <address> <new-min-stratum> : Modify minimum stratum of source\n");
|
||||
printf("offline [<mask>/<masked-address>] : Set sources in subnet to offline status\n");
|
||||
printf("online [<mask>/<masked-address>] : Set sources in subnet to online status\n");
|
||||
printf("password [<new-password>] : Set command authentication password\n");
|
||||
printf("polltarget <address> <new-poll-target> : Modify poll target of source\n");
|
||||
printf("reselect : Reselect synchronisation source\n");
|
||||
printf("rtcdata : Print current RTC performance parameters\n");
|
||||
|
@ -1320,7 +1227,6 @@ give_help(void)
|
|||
printf("waitsync [max-tries [max-correction [max-skew]]] : Wait until synchronised\n");
|
||||
printf("writertc : Save RTC parameters to file\n");
|
||||
printf("\n");
|
||||
printf("authhash <name>: Set command authentication hash function\n");
|
||||
printf("dns -n|+n : Disable/enable resolving IP addresses to hostnames\n");
|
||||
printf("dns -4|-6|-46 : Resolve hostnames only to IPv4/IPv6/both addresses\n");
|
||||
printf("timeout <milliseconds> : Set initial response timeout\n");
|
||||
|
@ -1333,9 +1239,6 @@ give_help(void)
|
|||
/* ================================================== */
|
||||
|
||||
static unsigned long sequence = 0;
|
||||
static unsigned long utoken = 0;
|
||||
static unsigned long token = 0;
|
||||
|
||||
static int max_retries = 2;
|
||||
static int initial_timeout = 1000;
|
||||
static int proto_version = PROTO_VERSION_NUMBER;
|
||||
|
@ -1346,7 +1249,7 @@ static int proto_version = PROTO_VERSION_NUMBER;
|
|||
successful or not.*/
|
||||
|
||||
static int
|
||||
submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
||||
submit_request(CMD_Request *request, CMD_Reply *reply)
|
||||
{
|
||||
unsigned long tx_sequence;
|
||||
int bad_length, bad_sequence, bad_header;
|
||||
|
@ -1356,7 +1259,6 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
int expected_length;
|
||||
int command_length;
|
||||
int padding_length;
|
||||
int auth_length;
|
||||
struct timeval tv;
|
||||
int timeout;
|
||||
int n_attempts;
|
||||
|
@ -1368,8 +1270,8 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
tx_sequence = sequence++;
|
||||
request->sequence = htonl(tx_sequence);
|
||||
request->attempt = 0;
|
||||
request->utoken = htonl(utoken);
|
||||
request->token = htonl(token);
|
||||
request->utoken = 0;
|
||||
request->token = 0;
|
||||
|
||||
timeout = initial_timeout;
|
||||
|
||||
|
@ -1381,35 +1283,15 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
padding_length = PKL_CommandPaddingLength(request);
|
||||
assert(command_length > 0 && command_length > padding_length);
|
||||
|
||||
/* Zero the padding to avoid sending uninitialized data. This needs to be
|
||||
done before generating auth data as it includes the padding. */
|
||||
/* Zero the padding to avoid sending uninitialized data */
|
||||
memset(((char *)request) + command_length - padding_length, 0, padding_length);
|
||||
|
||||
/* Decide whether to authenticate */
|
||||
if (password) {
|
||||
if (!utoken || (request->command == htons(REQ_LOGON))) {
|
||||
/* Otherwise, the daemon won't bother authenticating our
|
||||
packet and we won't get a token back */
|
||||
request->utoken = htonl(SPECIAL_UTOKEN);
|
||||
}
|
||||
auth_length = generate_auth(request);
|
||||
} else {
|
||||
auth_length = 0;
|
||||
}
|
||||
|
||||
/* add empty MD5 auth so older servers will not drop the request
|
||||
due to bad length */
|
||||
if (!auth_length) {
|
||||
memset(((char *)request) + command_length, 0, 16);
|
||||
auth_length = 16;
|
||||
}
|
||||
|
||||
if (send(sock_fd, (void *)request, command_length + auth_length, 0) < 0) {
|
||||
if (send(sock_fd, (void *)request, command_length, 0) < 0) {
|
||||
DEBUG_LOG(LOGF_Client, "Could not send %d bytes : %s",
|
||||
command_length + auth_length, strerror(errno));
|
||||
command_length, strerror(errno));
|
||||
return 0;
|
||||
} else {
|
||||
DEBUG_LOG(LOGF_Client, "Sent %d bytes", command_length + auth_length);
|
||||
DEBUG_LOG(LOGF_Client, "Sent %d bytes", command_length);
|
||||
}
|
||||
|
||||
/* Increment this for next time */
|
||||
|
@ -1513,30 +1395,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
DEBUG_LOG(LOGF_Client, "Reply cmd=%d reply=%d stat=%d seq=%d utok=%08x tok=%d",
|
||||
ntohs(reply->command), ntohs(reply->reply), ntohs(reply->status),
|
||||
ntohl(reply->sequence), ntohl(reply->utoken), ntohl(reply->token));
|
||||
|
||||
if (password) {
|
||||
*reply_auth_ok = check_reply_auth(reply, read_length);
|
||||
} else {
|
||||
/* Assume in this case that the reply is always considered
|
||||
to be authentic */
|
||||
*reply_auth_ok = 1;
|
||||
}
|
||||
|
||||
utoken = ntohl(reply->utoken);
|
||||
|
||||
if (*reply_auth_ok) {
|
||||
/* If we're in authenticated mode, only acquire the utoken
|
||||
and new token values if the reply authenticated properly.
|
||||
This protects against forged packets with bogus tokens
|
||||
in. We won't accept a repeat of an old message with a
|
||||
stale token in it, due to bad_sequence processing
|
||||
earlier. */
|
||||
utoken = ntohl(reply->utoken);
|
||||
token = ntohl(reply->token);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
|
@ -1549,10 +1408,9 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
|||
static int
|
||||
request_reply(CMD_Request *request, CMD_Reply *reply, int requested_reply, int verbose)
|
||||
{
|
||||
int reply_auth_ok;
|
||||
int status;
|
||||
|
||||
while (!submit_request(request, reply, &reply_auth_ok)) {
|
||||
while (!submit_request(request, reply)) {
|
||||
/* Try connecting to other addresses before giving up */
|
||||
if (open_io())
|
||||
continue;
|
||||
|
@ -1627,11 +1485,7 @@ request_reply(CMD_Request *request, CMD_Reply *reply, int requested_reply, int v
|
|||
default:
|
||||
printf("520 Got unexpected error from daemon");
|
||||
}
|
||||
if (reply_auth_ok) {
|
||||
printf("\n");
|
||||
} else {
|
||||
printf(" --- Reply not authenticated\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (status != STT_SUCCESS &&
|
||||
|
@ -2481,33 +2335,6 @@ process_cmd_dns(const char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_authhash(const char *line)
|
||||
{
|
||||
const char *hash_name;
|
||||
int new_hash_id;
|
||||
|
||||
assert(auth_hash_id >= 0);
|
||||
hash_name = line;
|
||||
|
||||
if (!*hash_name) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not parse hash name");
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_hash_id = HSH_GetHashId(hash_name);
|
||||
if (new_hash_id < 0) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Unknown hash name: %s", hash_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auth_hash_id = new_hash_id;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_cmd_timeout(const char *line)
|
||||
{
|
||||
|
@ -2579,9 +2406,6 @@ process_line(char *line)
|
|||
} else {
|
||||
do_normal_submit = process_cmd_allow(&tx_message, line);
|
||||
}
|
||||
} else if (!strcmp(command, "authhash")) {
|
||||
ret = process_cmd_authhash(line);
|
||||
do_normal_submit = 0;
|
||||
} else if (!strcmp(command, "burst")) {
|
||||
do_normal_submit = process_cmd_burst(&tx_message, line);
|
||||
} else if (!strcmp(command, "clients")) {
|
||||
|
@ -2660,8 +2484,6 @@ process_line(char *line)
|
|||
do_normal_submit = process_cmd_offline(&tx_message, line);
|
||||
} else if (!strcmp(command, "online")) {
|
||||
do_normal_submit = process_cmd_online(&tx_message, line);
|
||||
} else if (!strcmp(command, "password")) {
|
||||
do_normal_submit = process_cmd_password(&tx_message, line);
|
||||
} else if (!strcmp(command, "polltarget")) {
|
||||
do_normal_submit = process_cmd_polltarget(&tx_message, line);
|
||||
} else if (!strcmp(command, "quit")) {
|
||||
|
@ -2707,6 +2529,12 @@ process_line(char *line)
|
|||
do_normal_submit = 0;
|
||||
} else if (!strcmp(command, "writertc")) {
|
||||
process_cmd_writertc(&tx_message, line);
|
||||
} else if (!strcmp(command, "authhash") ||
|
||||
!strcmp(command, "password")) {
|
||||
/* Warn, but don't return error to not break scripts */
|
||||
LOG(LOGS_WARN, LOGF_Client, "Authentication is no longer supported");
|
||||
do_normal_submit = 0;
|
||||
ret = 1;
|
||||
} else {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Unrecognized command");
|
||||
do_normal_submit = 0;
|
||||
|
@ -2722,77 +2550,6 @@ process_line(char *line)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
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;
|
||||
uint32_t key_id = 0, key_id2;
|
||||
int key_id_valid = 1, ret;
|
||||
FILE *in;
|
||||
|
||||
in = fopen(filename, "r");
|
||||
if (!in) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not open file %s : %s", filename, strerror(errno));
|
||||
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")) {
|
||||
key_id_valid = sscanf(arg, "%"SCNu32, &key_id) == 1;
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if (!*keyfile || !key_id_valid) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not read keyfile or commandkey in file %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
in = fopen(keyfile, "r");
|
||||
if (!in) {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not open keyfile %s : %s", keyfile, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
key_id2 = key_id + 1;
|
||||
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 {
|
||||
LOG(LOGS_ERR, LOGF_Client, "Could not find key %"PRIu32" in keyfile %s", key_id, keyfile);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* Erase password from stack */
|
||||
memset(line, 0, sizeof (line));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static int
|
||||
process_args(int argc, char **argv, int multi)
|
||||
{
|
||||
|
@ -2857,8 +2614,7 @@ main(int argc, char **argv)
|
|||
char *line;
|
||||
const char *progname = argv[0];
|
||||
const char *hostnames = NULL;
|
||||
const char *conf_file = DEFAULT_CONF_FILE;
|
||||
int ret = 1, multi = 0, auto_auth = 0, family = IPADDR_UNSPEC;
|
||||
int ret = 1, multi = 0, family = IPADDR_UNSPEC;
|
||||
int port = DEFAULT_CANDM_PORT;
|
||||
|
||||
/* Parse command line options */
|
||||
|
@ -2875,11 +2631,9 @@ main(int argc, char **argv)
|
|||
}
|
||||
} else if (!strcmp(*argv, "-f")) {
|
||||
++argv, --argc;
|
||||
if (*argv) {
|
||||
conf_file = *argv;
|
||||
}
|
||||
/* For compatibility */
|
||||
} else if (!strcmp(*argv, "-a")) {
|
||||
auto_auth = 1;
|
||||
/* For compatibility */
|
||||
} else if (!strcmp(*argv, "-d")) {
|
||||
log_debug_enabled = 1;
|
||||
} else if (!strcmp(*argv, "-m")) {
|
||||
|
@ -2895,7 +2649,7 @@ main(int argc, char **argv)
|
|||
return 0;
|
||||
} else if (!strncmp(*argv, "-", 1)) {
|
||||
LOG(LOGS_ERR, LOGF_Client,
|
||||
"Usage: %s [-h HOST] [-p PORT] [-n] [-d] [-4|-6] [-a] [-f FILE] [-m] [COMMAND]",
|
||||
"Usage: %s [-h HOST] [-p PORT] [-n] [-d] [-4|-6] [-m] [COMMAND]",
|
||||
progname);
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -2911,12 +2665,6 @@ main(int argc, char **argv)
|
|||
display_gpl();
|
||||
}
|
||||
|
||||
/* MD5 is the default authentication hash */
|
||||
auth_hash_id = HSH_GetHashId("MD5");
|
||||
if (auth_hash_id < 0) {
|
||||
LOG_FATAL(LOGF_Client, "Could not initialize MD5");
|
||||
}
|
||||
|
||||
DNS_SetAddressFamily(family);
|
||||
|
||||
if (!hostnames) {
|
||||
|
@ -2933,10 +2681,6 @@ main(int argc, char **argv)
|
|||
if (!open_io())
|
||||
LOG_FATAL(LOGF_Client, "Could not open connection to daemon");
|
||||
|
||||
if (auto_auth) {
|
||||
ret = authenticate_from_config(conf_file);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
;
|
||||
} else if (argc > 0) {
|
||||
|
@ -2955,7 +2699,6 @@ main(int argc, char **argv)
|
|||
|
||||
close_io();
|
||||
|
||||
Free(password);
|
||||
ARR_DestroyInstance(sockaddrs);
|
||||
|
||||
return !ret;
|
||||
|
|
Loading…
Reference in a new issue