nts: update client state earlier

Generate a new uniq ID on each client poll to invalidate responses to
the previous request, even if a new request cannot be generated (e.g.
due to missing cookies). Reset the NAK indicator earlier in the request
sequence. Also, drop the cookie even if it's not included in the request
to prevent the client from getting stuck with a cookie that has an
invalid length. Rely on the exponentially increasing interval to avoid
frequent NTS-KE sessions due to a client bug.
This commit is contained in:
Miroslav Lichvar 2020-09-29 14:49:27 +02:00
parent a97830d9d6
commit f41d370e6a

View file

@ -273,8 +273,6 @@ get_cookies(NNC_Instance inst)
inst->last_nke_success = now; inst->last_nke_success = now;
inst->cookie_index = 0; inst->cookie_index = 0;
inst->nak_response = 0;
return 1; return 1;
} }
@ -285,6 +283,11 @@ NNC_PrepareForAuth(NNC_Instance inst)
{ {
inst->auth_ready = 0; inst->auth_ready = 0;
/* Prepare data for the next request and invalidate any responses to the
previous request */
UTI_GetRandomBytes(inst->uniq_id, sizeof (inst->uniq_id));
UTI_GetRandomBytes(inst->nonce, sizeof (inst->nonce));
/* Try to reload saved keys and cookies (once for the NTS-KE address) */ /* Try to reload saved keys and cookies (once for the NTS-KE address) */
if (!inst->load_attempt) { if (!inst->load_attempt) {
load_cookies(inst); load_cookies(inst);
@ -297,6 +300,8 @@ NNC_PrepareForAuth(NNC_Instance inst)
return 0; return 0;
} }
inst->nak_response = 0;
if (!inst->siv) if (!inst->siv)
inst->siv = SIV_CreateInstance(inst->context.algorithm); inst->siv = SIV_CreateInstance(inst->context.algorithm);
@ -306,10 +311,6 @@ NNC_PrepareForAuth(NNC_Instance inst)
return 0; return 0;
} }
/* Prepare data for NNC_GenerateRequestAuth() */
UTI_GetRandomBytes(inst->uniq_id, sizeof (inst->uniq_id));
UTI_GetRandomBytes(inst->nonce, sizeof (inst->nonce));
inst->auth_ready = 1; inst->auth_ready = 1;
return 1; return 1;
@ -325,14 +326,22 @@ NNC_GenerateRequestAuth(NNC_Instance inst, NTP_Packet *packet,
int i, req_cookies; int i, req_cookies;
void *ef_body; void *ef_body;
if (!inst->auth_ready || inst->num_cookies == 0 || !inst->siv) if (!inst->auth_ready)
return 0;
inst->auth_ready = 0;
if (inst->num_cookies <= 0 || !inst->siv)
return 0; return 0;
if (info->mode != MODE_CLIENT) if (info->mode != MODE_CLIENT)
return 0; return 0;
cookie = &inst->cookies[inst->cookie_index]; cookie = &inst->cookies[inst->cookie_index];
req_cookies = MIN(NTS_MAX_COOKIES - inst->num_cookies + 1, inst->num_cookies--;
inst->cookie_index = (inst->cookie_index + 1) % NTS_MAX_COOKIES;
req_cookies = MIN(NTS_MAX_COOKIES - inst->num_cookies,
MAX_TOTAL_COOKIE_LENGTH / (cookie->length + 4)); MAX_TOTAL_COOKIE_LENGTH / (cookie->length + 4));
if (!NEF_AddField(packet, info, NTP_EF_NTS_UNIQUE_IDENTIFIER, if (!NEF_AddField(packet, info, NTP_EF_NTS_UNIQUE_IDENTIFIER,
@ -354,10 +363,6 @@ NNC_GenerateRequestAuth(NNC_Instance inst, NTP_Packet *packet,
(const unsigned char *)"", 0, NTP_MAX_V4_MAC_LENGTH + 4)) (const unsigned char *)"", 0, NTP_MAX_V4_MAC_LENGTH + 4))
return 0; return 0;
inst->num_cookies--;
inst->cookie_index = (inst->cookie_index + 1) % NTS_MAX_COOKIES;
inst->auth_ready = 0;
inst->nak_response = 0;
inst->ok_response = 0; inst->ok_response = 0;
return 1; return 1;