From e6e9a472dbeefc17a595c708cbf9b2ff08bf04c0 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 29 Nov 2016 13:26:46 +0100 Subject: [PATCH] ntp: avoid truncation of NTPv4 MACs by default If the MAC in NTPv4 requests would be truncated, use version 3 by default to avoid the truncation. This is necessary for compatibility with older chronyd servers, which do not respond to messages with truncated MACs. --- cmdparse.c | 2 +- doc/chrony.conf.adoc | 10 +++++++--- keys.c | 16 ++++++++++++++++ keys.h | 1 + ntp_core.c | 14 +++++++++----- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/cmdparse.c b/cmdparse.c index d22ba21..700da32 100644 --- a/cmdparse.c +++ b/cmdparse.c @@ -54,7 +54,7 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src) src->params.iburst = 0; src->params.min_stratum = SRC_DEFAULT_MINSTRATUM; src->params.poll_target = SRC_DEFAULT_POLLTARGET; - src->params.version = NTP_VERSION; + src->params.version = 0; src->params.max_sources = SRC_DEFAULT_MAXSOURCES; src->params.min_samples = SRC_DEFAULT_MINSAMPLES; src->params.max_samples = SRC_DEFAULT_MAXSAMPLES; diff --git a/doc/chrony.conf.adoc b/doc/chrony.conf.adoc index d19e9ee..d265044 100644 --- a/doc/chrony.conf.adoc +++ b/doc/chrony.conf.adoc @@ -215,9 +215,13 @@ avoid selecting that source. This is useful with low stratum sources that are known to be unreliable or inaccurate and which should be used only when other sources are unreachable. *version* _version_::: -This option sets the NTP version number used in packets sent to the server. -This can be useful when the server runs an old NTP implementation that does not -respond to newer versions. The default version number is 4. +This option sets the NTP version of packets sent to the server. This can be +useful when the server runs an old NTP implementation that does not respond to +requests using a newer version. The default version depends on whether a key is +specified by the *key* option and which authentication hash function the key +is using. If the output size of the hash function is longer than 160 bits, the +default version is 3 for compatibility with older *chronyd* servers. Otherwise, +the default version is 4. [[pool]]*pool* _name_ [_option_]...:: The syntax of this directive is similar to that for the <> diff --git a/keys.c b/keys.c index dfe18a3..09b27bc 100644 --- a/keys.c +++ b/keys.c @@ -322,6 +322,22 @@ KEY_GetAuthDelay(uint32_t key_id) /* ================================================== */ +int +KEY_GetAuthLength(uint32_t key_id) +{ + unsigned char buf[MAX_HASH_LENGTH]; + Key *key; + + key = get_key_by_id(key_id); + + if (!key) + return 0; + + return HSH_Hash(key->hash_id, buf, 0, buf, 0, buf, sizeof (buf)); +} + +/* ================================================== */ + int KEY_CheckKeyLength(uint32_t key_id) { diff --git a/keys.h b/keys.h index 9e5d236..82f3a26 100644 --- a/keys.h +++ b/keys.h @@ -37,6 +37,7 @@ extern void KEY_Reload(void); extern int KEY_GetKey(uint32_t key_id, char **key, int *len); extern int KEY_KeyKnown(uint32_t key_id); extern int KEY_GetAuthDelay(uint32_t key_id); +extern int KEY_GetAuthLength(uint32_t key_id); extern int KEY_CheckKeyLength(uint32_t key_id); extern int KEY_GenerateAuth(uint32_t key_id, const unsigned char *data, diff --git a/ntp_core.c b/ntp_core.c index 01c103f..37512bc 100644 --- a/ntp_core.c +++ b/ntp_core.c @@ -520,11 +520,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result->auto_offline = params->auto_offline; result->poll_target = params->poll_target; - result->version = params->version; - if (result->version < NTP_MIN_COMPAT_VERSION) - result->version = NTP_MIN_COMPAT_VERSION; - else if (result->version > NTP_VERSION) - result->version = NTP_VERSION; + result->version = NTP_VERSION; if (params->authkey == INACTIVE_AUTHKEY) { result->auth_mode = AUTH_NONE; @@ -541,8 +537,16 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar result->auth_key_id, UTI_IPToString(&result->remote_addr.ip_addr), "too short"); } + + /* If the MAC in NTPv4 packets would be truncated, use version 3 by + default for compatibility with older chronyd servers */ + if (KEY_GetAuthLength(result->auth_key_id) + 4 > NTP_MAX_V4_MAC_LENGTH) + result->version = 3; } + if (params->version) + result->version = CLAMP(NTP_MIN_COMPAT_VERSION, params->version, NTP_VERSION); + /* Create a source instance for this NTP source */ result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, params->sel_options,