]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: don't allow long MACs in NTPv4 packets with extension fields
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 3 Feb 2020 13:03:57 +0000 (14:03 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 5 Mar 2020 15:02:15 +0000 (16:02 +0100)
MAC longer than 24 octets in NTPv4 packet is supported only for
compatibility with some pre-RFC7822 chrony versions. They didn't use
any extension fields.

ntp_auth.c

index 0f2e0b69325ecb7e109ee924f2848b5291f9283f..56f05fc23e08942bb8ab2f6951c393e115af594d 100644 (file)
@@ -282,19 +282,20 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
   /* Parse the rest of the NTPv4 packet */
 
   while (remainder > 0) {
-    /* Check if the remaining data is a valid MAC.  There is a limit on MAC
-       length in NTPv4 packets to allow deterministic parsing of extension
-       fields (RFC 7822), but we need to support longer MACs to not break
-       compatibility with older chrony clients.  This needs to be done before
-       trying to parse the data as an extension field. */
+    /* Check if the remaining data is a MAC */
+    if (remainder >= NTP_MIN_MAC_LENGTH && remainder <= NTP_MAX_V4_MAC_LENGTH)
+      break;
 
-    if (remainder >= NTP_MIN_MAC_LENGTH && remainder <= NTP_MAX_MAC_LENGTH) {
-      info->auth.mac.key_id = ntohl(*(uint32_t *)(data + parsed));
-      if (remainder <= NTP_MAX_V4_MAC_LENGTH ||
-          KEY_CheckAuth(info->auth.mac.key_id, data, parsed, (void *)(data + parsed + 4),
-                        remainder - 4, NTP_MAX_MAC_LENGTH - 4))
-        break;
-    }
+    /* The NTPv4-specific limit for MAC length enables deterministic parsing of
+       packets with extension fields (RFC 7822), but we support longer MACs in
+       packets with no extension fields for compatibility with older chrony
+       clients.  Check if the longer MAC would authenticate the packet before
+       trying to parse the data as an extension field. */
+    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))
+      break;
 
     /* Check if this is a valid NTPv4 extension field and skip it */
     if (!NEF_ParseField(packet, info->length, parsed, &ef_length, &ef_type, NULL, NULL)) {