]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: add support for sending KoD responses
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 7 Nov 2019 13:57:52 +0000 (14:57 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 5 Mar 2020 15:02:15 +0000 (16:02 +0100)
Enable the server to respond with a KoD when authentication fails. This
will be used by NTS to respond with a NAK when a client has expired
cookies.

ntp_auth.c
ntp_auth.h
ntp_core.c

index 9f20e843a20499382429a70eebc06bb621e5f320..0f2e0b69325ecb7e109ee924f2848b5291f9283f 100644 (file)
@@ -336,8 +336,10 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
 /* ================================================== */
 
 int
-NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info)
+NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info, uint32_t *kod)
 {
+  *kod = 0;
+
   switch (info->auth.mode) {
     case NTP_AUTH_NONE:
       break;
@@ -368,7 +370,8 @@ NAU_AdjustResponseTimestamp(NTP_Packet *request, NTP_PacketInfo *info, struct ti
 int
 NAU_GenerateResponseAuth(NTP_Packet *request, NTP_PacketInfo *request_info,
                          NTP_Packet *response, NTP_PacketInfo *response_info,
-                         NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr)
+                         NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr,
+                         uint32_t kod)
 {
   switch (request_info->auth.mode) {
     case NTP_AUTH_NONE:
index 7537238fda1e44be1683c7f70ae047cdc6541668..a0326142d383d20ed07d36ab6dbe1e5c86c894e7 100644 (file)
@@ -59,8 +59,9 @@ extern int NAU_GenerateRequestAuth(NAU_Instance instance, NTP_Packet *request,
 /* Parse a request or response to detect the authentication mode */
 extern int NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info);
 
-/* Verify that a request is authentic */
-extern int NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info);
+/* Verify that a request is authentic.  If it is not authentic and a non-zero
+   kod code is returned, a KoD response should be sent back. */
+extern int NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info, uint32_t *kod);
 
 /* Adjust a transmit timestamp for an estimated minimum time it takes to call
    NAU_GenerateResponseAuth() */
@@ -73,7 +74,8 @@ extern void NAU_AdjustResponseTimestamp(NTP_Packet *request, NTP_PacketInfo *inf
 extern int NAU_GenerateResponseAuth(NTP_Packet *request, NTP_PacketInfo *request_info,
                                     NTP_Packet *response, NTP_PacketInfo *response_info,
                                     NTP_Remote_Address *remote_addr,
-                                    NTP_Local_Address *local_addr);
+                                    NTP_Local_Address *local_addr,
+                                    uint32_t kod);
 
 /* Verify that a response is authentic */
 extern int NAU_CheckResponseAuth(NAU_Instance instance, NTP_Packet *response,
index 38917edc21455b8acfe672023768972ceaf4dfe6..7f48d9a58599ca47ae7b7a4f02db755ab5c30b6c 100644 (file)
@@ -904,6 +904,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
                 int interleaved, /* Flag enabling interleaved mode */
                 int my_poll, /* The log2 of the local poll interval */
                 int version, /* The NTP version to be set in the packet */
+                uint32_t kod, /* KoD code - 0 disabled */
                 NAU_Instance auth, /* The authentication to be used for the packet */
                 NTP_int64 *remote_ntp_rx, /* The receive timestamp from received packet */
                 NTP_int64 *remote_ntp_tx, /* The transmit timestamp from received packet */
@@ -987,6 +988,12 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
     local_receive = local_rx->ts;
   }
 
+  if (kod != 0) {
+    leap_status = LEAP_Unsynchronised;
+    our_stratum = NTP_INVALID_STRATUM;
+    our_ref_id = kod;
+  }
+
   /* Generate transmit packet */
   message.lvm = NTP_LVM(leap_status, version, my_mode);
   /* Stratum 16 and larger are invalid */
@@ -1068,7 +1075,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
         return 0;
       }
     } else {
-      if (!NAU_GenerateResponseAuth(request, request_info, &message, &info, where_to, from)) {
+      if (!NAU_GenerateResponseAuth(request, request_info, &message, &info,
+                                    where_to, from, kod)) {
         DEBUG_LOG("Could not generate response auth");
         return 0;
       }
@@ -1208,7 +1216,7 @@ transmit_timeout(void *arg)
   }
 
   /* Send the request (which may also be a response in the symmetric mode) */
-  sent = transmit_packet(inst->mode, interleaved, inst->local_poll, inst->version,
+  sent = transmit_packet(inst->mode, interleaved, inst->local_poll, inst->version, 0,
                          inst->auth,
                          initial ? NULL : &inst->remote_ntp_rx,
                          initial ? &inst->init_remote_ntp_tx : &inst->remote_ntp_tx,
@@ -2018,6 +2026,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
   NTP_int64 *local_ntp_rx, *local_ntp_tx;
   NTP_Local_Timestamp local_tx, *tx_ts;
   int log_index, interleaved, poll, version;
+  uint32_t kod;
 
   /* Ignore the packet if it wasn't received by server socket */
   if (!NIO_IsServerSocket(local_addr->sock_fd)) {
@@ -2058,6 +2067,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
       return;
   }
 
+  kod = 0;
   log_index = CLG_LogNTPAccess(&remote_addr->ip_addr, &rx_ts->ts);
 
   /* Don't reply to all requests if the rate is excessive */
@@ -2067,9 +2077,12 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
   }
 
   /* Check authentication */
-  if (!NAU_CheckRequestAuth(message, &info)) {
-    DEBUG_LOG("NTP packet discarded auth mode=%d", (int)info.auth.mode);
-    return;
+  if (!NAU_CheckRequestAuth(message, &info, &kod)) {
+    DEBUG_LOG("NTP packet failed auth mode=%d kod=%"PRIx32, (int)info.auth.mode, kod);
+
+    /* Don't respond unless a non-zero KoD was returned */
+    if (kod == 0)
+      return;
   }
 
   /* If it is an NTPv4 packet with a long MAC and no extension fields,
@@ -2090,7 +2103,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
      in the interleaved mode.  This means the third reply to a new client is
      the earliest one that can be interleaved.  We don't want to waste time
      on clients that are not using the interleaved mode. */
-  if (log_index >= 0) {
+  if (kod == 0 && log_index >= 0) {
     CLG_GetNtpTimestamps(log_index, &local_ntp_rx, &local_ntp_tx);
     interleaved = !UTI_IsZeroNtp64(local_ntp_rx) &&
                   !UTI_CompareNtp64(&message->originate_ts, local_ntp_rx) &&
@@ -2111,7 +2124,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
   poll = MAX(poll, message->poll);
 
   /* Send a reply */
-  transmit_packet(my_mode, interleaved, poll, version, NULL,
+  transmit_packet(my_mode, interleaved, poll, version, kod, NULL,
                   &message->receive_ts, &message->transmit_ts,
                   rx_ts, tx_ts, local_ntp_rx, NULL, remote_addr, local_addr,
                   message, &info);
@@ -2550,7 +2563,7 @@ broadcast_timeout(void *arg)
   UTI_ZeroNtp64(&orig_ts);
   zero_local_timestamp(&recv_ts);
 
-  transmit_packet(MODE_BROADCAST, 0, poll, NTP_VERSION, destination->auth,
+  transmit_packet(MODE_BROADCAST, 0, poll, NTP_VERSION, 0, destination->auth,
                   &orig_ts, &orig_ts, &recv_ts, NULL, NULL, NULL,
                   &destination->addr, &destination->local_addr, NULL, NULL);