]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: enable NTS support
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 4 Feb 2020 14:27:24 +0000 (15:27 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 5 Mar 2020 15:02:15 +0000 (16:02 +0100)
Add an option to enable NTS for an NTP source. Check for NTS-specific
extension fields and pass the packets to the NTS-NTP code in order to
enable the NTS client and server.

cmdmon.c
cmdparse.c
ntp.h
ntp_auth.c
ntp_auth.h
ntp_core.c
srcparams.h

index ba6e9857ce6d625f20401b23e2f3fc76e3a26fc4..5e3fc5562044142cf1c3be141ccd77a1529f599e 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -743,6 +743,8 @@ handle_add_source(CMD_Request *rx_message, CMD_Reply *tx_message)
     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0) |
     (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_REQUIRE ? SRC_SELECT_REQUIRE : 0);
+  params.nts = 0;
+  params.nts_port = 0;
 
   status = NSR_AddSourceByName(name, port, pool, type, &params);
   switch (status) {
index 37037d120e13e82859da9687219512ba530a4d39..0124586ea9ca11b922ff07112d1848c4b7bb488c 100644 (file)
@@ -62,6 +62,8 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
   src->params.filter_length = 0;
   src->params.interleaved = 0;
   src->params.sel_options = 0;
+  src->params.nts = 0;
+  src->params.nts_port = SRC_DEFAULT_NTSPORT;
   src->params.authkey = INACTIVE_AUTHKEY;
   src->params.max_delay = SRC_DEFAULT_MAXDELAY;
   src->params.max_delay_ratio = SRC_DEFAULT_MAXDELAYRATIO;
@@ -140,6 +142,11 @@ CPS_ParseNTPSourceAdd(char *line, CPS_NTP_Source *src)
     } else if (!strcasecmp(cmd, "minstratum")) {
       if (sscanf(line, "%d%n", &src->params.min_stratum, &n) != 1)
         return 0;
+    } else if (!strcasecmp(cmd, "nts")) {
+      src->params.nts = 1;
+    } else if (!strcasecmp(cmd, "ntsport")) {
+      if (sscanf(line, "%d%n", &src->params.nts_port, &n) != 1)
+        return 0;
     } else if (!strcasecmp(cmd, "offset")) {
       if (sscanf(line, "%lf%n", &src->params.offset, &n) != 1)
         return 0;
diff --git a/ntp.h b/ntp.h
index 3edc18d7fe148db16df0ecc4d0991bfb557164b1..90f24c29ed4b967d790e23fb6fedb7b189d3b8d0 100644 (file)
--- a/ntp.h
+++ b/ntp.h
@@ -119,6 +119,7 @@ typedef enum {
   NTP_AUTH_SYMMETRIC,           /* MAC using symmetric key (RFC 1305, RFC 5905) */
   NTP_AUTH_MSSNTP,              /* MS-SNTP authenticator field */
   NTP_AUTH_MSSNTP_EXT,          /* MS-SNTP extended authenticator field */
+  NTP_AUTH_NTS,                 /* Network Time Security (RFC ????) */
 } NTP_AuthMode;
 
 /* Structure describing an NTP packet */
index 4f9915440b0ca261044c6e4e721497f32579355a..9c1056d1704f710d59e18bea4b35a48fbb817fbd 100644 (file)
@@ -34,6 +34,9 @@
 #include "ntp_auth.h"
 #include "ntp_ext.h"
 #include "ntp_signd.h"
+#include "nts_ntp.h"
+#include "nts_ntp_client.h"
+#include "nts_ntp_server.h"
 #include "srcparams.h"
 #include "util.h"
 
@@ -42,6 +45,7 @@
 struct NAU_Instance_Record {
   NTP_AuthMode mode;            /* Authentication mode of NTP packets */
   uint32_t key_id;              /* Identifier of a symmetric key */
+  NNC_Instance nts;             /* Client NTS state */
 };
 
 /* ================================================== */
@@ -131,6 +135,7 @@ create_instance(NTP_AuthMode mode)
   instance = MallocNew(struct NAU_Instance_Record);
   instance->mode = mode;
   instance->key_id = INACTIVE_AUTHKEY;
+  instance->nts = NULL;
 
   assert(sizeof (instance->key_id) == 4);
 
@@ -164,9 +169,23 @@ NAU_CreateSymmetricInstance(uint32_t key_id)
 
 /* ================================================== */
 
+NAU_Instance
+NAU_CreateNtsInstance(IPSockAddr *nts_address, const char *name, const IPSockAddr *ntp_address)
+{
+  NAU_Instance instance = create_instance(NTP_AUTH_NTS);
+
+  instance->nts = NNC_CreateInstance(nts_address, name, ntp_address);
+
+  return instance;
+}
+
+/* ================================================== */
+
 void
 NAU_DestroyInstance(NAU_Instance instance)
 {
+  if (instance->nts)
+    NNC_DestroyInstance(instance->nts);
   Free(instance);
 }
 
@@ -198,6 +217,10 @@ int
 NAU_PrepareRequestAuth(NAU_Instance instance)
 {
   switch (instance->mode) {
+    case NTP_AUTH_NTS:
+      if (!NNC_PrepareForAuth(instance->nts))
+        return 0;
+      break;
     default:
       break;
   }
@@ -225,6 +248,10 @@ NAU_GenerateRequestAuth(NAU_Instance instance, NTP_Packet *request, NTP_PacketIn
       if (!generate_symmetric_auth(instance->key_id, request, info))
         return 0;
       break;
+    case NTP_AUTH_NTS:
+      if (!NNC_GenerateRequestAuth(instance->nts, request, info))
+        return 0;
+      break;
     default:
       assert(0);
   }
@@ -307,6 +334,12 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
     assert(ef_length > 0);
 
     switch (ef_type) {
+      case NTP_EF_NTS_UNIQUE_IDENTIFIER:
+      case NTP_EF_NTS_COOKIE:
+      case NTP_EF_NTS_COOKIE_PLACEHOLDER:
+      case NTP_EF_NTS_AUTH_AND_EEF:
+        info->auth.mode = NTP_AUTH_NTS;
+        break;
       default:
         DEBUG_LOG("Unknown extension field type=%x", (unsigned int)ef_type);
     }
@@ -351,6 +384,10 @@ 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_NTS:
+      if (!NNS_CheckRequestAuth(request, info, kod))
+        return 0;
+      break;
     default:
       return 0;
   }
@@ -388,6 +425,10 @@ NAU_GenerateResponseAuth(NTP_Packet *request, NTP_PacketInfo *request_info,
         return 0;
       /* Don't send the original packet */
       return 0;
+    case NTP_AUTH_NTS:
+      if (!NNS_GenerateResponseAuth(request, request_info, response, response_info, kod))
+        return 0;
+      break;
     default:
       DEBUG_LOG("Could not authenticate response auth_mode=%d", (int)request_info->auth.mode);
       return 0;
@@ -416,6 +457,10 @@ NAU_CheckResponseAuth(NAU_Instance instance, NTP_Packet *response, NTP_PacketInf
       if (!check_symmetric_auth(response, info))
         return 0;
       break;
+    case NTP_AUTH_NTS:
+      if (!NNC_CheckResponseAuth(instance->nts, response, info))
+        return 0;
+      break;
     default:
       return 0;
   }
@@ -432,6 +477,9 @@ NAU_ChangeAddress(NAU_Instance instance, IPAddr *address)
     case NTP_AUTH_NONE:
     case NTP_AUTH_SYMMETRIC:
       break;
+    case NTP_AUTH_NTS:
+      NNC_ChangeAddress(instance->nts, address);
+      break;
     default:
       assert(0);
   }
index 8211c631bf8d5c0fcb7e0964a5b4cd5d33e25d28..b1f06eb84df3b89d193a8d93c67c1a30a5dd1fef 100644 (file)
@@ -35,6 +35,8 @@ typedef struct NAU_Instance_Record *NAU_Instance;
 /* Create an authenticator instance in a specific mode */
 extern NAU_Instance NAU_CreateNoneInstance(void);
 extern NAU_Instance NAU_CreateSymmetricInstance(uint32_t key_id);
+extern NAU_Instance NAU_CreateNtsInstance(IPSockAddr *nts_address, const char *name,
+                                          const IPSockAddr *ntp_address);
 
 /* Destroy an instance */
 extern void NAU_DestroyInstance(NAU_Instance instance);
index 0c6349ff8138b2a1036dc18d29989cbb4360ccd7..68b86e18d0cc7764ec0d81ecc5f56dade05d0926 100644 (file)
@@ -559,7 +559,17 @@ NCR_CreateInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type,
   result->auto_offline = params->auto_offline;
   result->poll_target = params->poll_target;
 
-  if (params->authkey != INACTIVE_AUTHKEY) {
+  if (params->nts) {
+    IPSockAddr nts_address;
+
+    if (result->mode == MODE_ACTIVE)
+      LOG(LOGS_WARN, "NTS not supported with peers");
+
+    nts_address.ip_addr = remote_addr->ip_addr;
+    nts_address.port = params->nts_port;
+
+    result->auth = NAU_CreateNtsInstance(&nts_address, name, &result->remote_addr);
+  } else if (params->authkey != INACTIVE_AUTHKEY) {
     result->auth = NAU_CreateSymmetricInstance(params->authkey);
   } else {
     result->auth = NAU_CreateNoneInstance();
index deabd23c5e4e14730533c7ff1fecbd72ba1d3dc5..59d8a2348d81f441c0d5084a79d4394866543c23 100644 (file)
@@ -52,6 +52,8 @@ typedef struct {
   int filter_length;
   int interleaved;
   int sel_options;
+  int nts;
+  int nts_port;
   uint32_t authkey;
   double max_delay;
   double max_delay_ratio;
@@ -74,6 +76,7 @@ typedef struct {
 #define SRC_DEFAULT_MINSAMPLES (-1)
 #define SRC_DEFAULT_MAXSAMPLES (-1)
 #define SRC_DEFAULT_ASYMMETRY 1.0
+#define SRC_DEFAULT_NTSPORT 11443
 #define INACTIVE_AUTHKEY 0
 
 /* Flags for source selection */