(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, ¶ms);
switch (status) {
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;
} 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;
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 */
#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"
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 */
};
/* ================================================== */
instance = MallocNew(struct NAU_Instance_Record);
instance->mode = mode;
instance->key_id = INACTIVE_AUTHKEY;
+ instance->nts = NULL;
assert(sizeof (instance->key_id) == 4);
/* ================================================== */
+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);
}
NAU_PrepareRequestAuth(NAU_Instance instance)
{
switch (instance->mode) {
+ case NTP_AUTH_NTS:
+ if (!NNC_PrepareForAuth(instance->nts))
+ return 0;
+ break;
default:
break;
}
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);
}
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);
}
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;
}
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;
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;
}
case NTP_AUTH_NONE:
case NTP_AUTH_SYMMETRIC:
break;
+ case NTP_AUTH_NTS:
+ NNC_ChangeAddress(instance->nts, address);
+ break;
default:
assert(0);
}
/* 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);
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();
int filter_length;
int interleaved;
int sel_options;
+ int nts;
+ int nts_port;
uint32_t authkey;
double max_delay;
double max_delay_ratio;
#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 */