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