mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 12:15:07 -05:00
ntp: improve auth code
Before generating a MAC, make sure there is enough space in the packet. This is always true with the current code, but it may change when a non-NTS extension field is supported. Update the packet auth info after generating a MAC in case it's needed before the transmission. Add more assertions and make other changes for better readability.
This commit is contained in:
32
ntp_auth.c
32
ntp_auth.c
@@ -55,20 +55,29 @@ generate_symmetric_auth(uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *inf
|
||||
{
|
||||
int auth_len, max_auth_len;
|
||||
|
||||
if (info->length + NTP_MIN_MAC_LENGTH > sizeof (*packet)) {
|
||||
DEBUG_LOG("Packet too long");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Truncate long MACs in NTPv4 packets to allow deterministic parsing
|
||||
of extension fields (RFC 7822) */
|
||||
max_auth_len = (info->version == 4 ? NTP_MAX_V4_MAC_LENGTH : NTP_MAX_MAC_LENGTH) - 4;
|
||||
max_auth_len = MIN(max_auth_len, sizeof (NTP_Packet) - info->length - 4);
|
||||
max_auth_len = MIN(max_auth_len, sizeof (*packet) - info->length - 4);
|
||||
|
||||
auth_len = KEY_GenerateAuth(key_id, packet, info->length,
|
||||
(unsigned char *)packet + info->length + 4, max_auth_len);
|
||||
if (!auth_len) {
|
||||
if (auth_len < NTP_MIN_MAC_LENGTH - 4) {
|
||||
DEBUG_LOG("Could not generate auth data with key %"PRIu32, key_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*(uint32_t *)((unsigned char *)packet + info->length) = htonl(key_id);
|
||||
info->length += 4 + auth_len;
|
||||
|
||||
info->auth.mac.start = info->length;
|
||||
info->auth.mac.length = 4 + auth_len;
|
||||
info->auth.mac.key_id = key_id;
|
||||
info->length += info->auth.mac.length;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -102,7 +111,7 @@ is_zero_data(unsigned char *data, int length)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
if (data[i])
|
||||
if (data[i] != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -230,6 +239,8 @@ NAU_GenerateRequestAuth(NAU_Instance instance, NTP_Packet *request, NTP_PacketIn
|
||||
assert(0);
|
||||
}
|
||||
|
||||
info->auth.mode = instance->mode;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -251,6 +262,8 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
if (remainder <= 0)
|
||||
return 1;
|
||||
|
||||
assert(remainder % 4 == 0);
|
||||
|
||||
/* In NTPv3 and older packets don't have extension fields. Anything after
|
||||
the header is assumed to be a MAC. */
|
||||
if (info->version <= 3) {
|
||||
@@ -261,7 +274,7 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
|
||||
/* Check if it is an MS-SNTP authenticator field or extended authenticator
|
||||
field with zeroes as digest */
|
||||
if (info->version == 3 && info->auth.mac.key_id) {
|
||||
if (info->version == 3 && info->auth.mac.key_id != 0) {
|
||||
if (remainder == 20 && is_zero_data(data + parsed + 4, remainder - 4))
|
||||
info->auth.mode = NTP_AUTH_MSSNTP;
|
||||
else if (remainder == 72 && is_zero_data(data + parsed + 8, remainder - 8))
|
||||
@@ -295,7 +308,7 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
if (parsed == NTP_HEADER_LENGTH &&
|
||||
remainder > NTP_MAX_V4_MAC_LENGTH && remainder <= NTP_MAX_MAC_LENGTH &&
|
||||
KEY_CheckAuth(ntohl(*(uint32_t *)(data + parsed)), data, parsed,
|
||||
(void *)(data + parsed + 4), remainder - 4, NTP_MAX_MAC_LENGTH - 4))
|
||||
data + parsed + 4, remainder - 4, NTP_MAX_MAC_LENGTH - 4))
|
||||
break;
|
||||
|
||||
/* Check if this is a valid NTPv4 extension field and skip it */
|
||||
@@ -305,7 +318,7 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(ef_length > 0);
|
||||
assert(ef_length > 0 && ef_length % 4 == 0);
|
||||
|
||||
switch (ef_type) {
|
||||
case NTP_EF_NTS_UNIQUE_IDENTIFIER:
|
||||
@@ -358,6 +371,9 @@ NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info, uint32_t *kod)
|
||||
case NTP_AUTH_MSSNTP:
|
||||
/* MS-SNTP requests are not authenticated */
|
||||
break;
|
||||
case NTP_AUTH_MSSNTP_EXT:
|
||||
/* Not supported yet */
|
||||
return 0;
|
||||
case NTP_AUTH_NTS:
|
||||
if (!NNS_CheckRequestAuth(request, info, kod))
|
||||
return 0;
|
||||
@@ -400,6 +416,8 @@ NAU_GenerateResponseAuth(NTP_Packet *request, NTP_PacketInfo *request_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
response_info->auth.mode = request_info->auth.mode;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user