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.
This commit is contained in:
Miroslav Lichvar 2016-11-29 13:26:46 +01:00
parent 1d5d768545
commit e6e9a472db
5 changed files with 34 additions and 9 deletions

View file

@ -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;

View file

@ -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 <<server,*server*>>

16
keys.c
View file

@ -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)
{

1
keys.h
View file

@ -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,

View file

@ -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,