--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ NTP authentication
+ */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include "keys.h"
+#include "logging.h"
+#include "memory.h"
+#include "ntp_auth.h"
+#include "ntp_signd.h"
+#include "srcparams.h"
+#include "util.h"
+
+/* Structure to hold authentication configuration and state */
+
+struct NAU_Instance_Record {
+ NTP_AuthMode mode; /* Authentication mode of NTP packets */
+ uint32_t key_id; /* Identifier of a symmetric key */
+};
+
+/* ================================================== */
+
+static int
+generate_symmetric_auth(uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *info)
+{
+ int auth_len, max_auth_len;
+
+ /* 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);
+
+ auth_len = KEY_GenerateAuth(key_id, (unsigned char *)packet, info->length,
+ (unsigned char *)packet + info->length + 4, max_auth_len);
+ if (!auth_len) {
+ 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;
+
+ return 1;
+}
+
+/* ================================================== */
+
+static int
+check_symmetric_auth(NTP_Packet *packet, NTP_PacketInfo *info)
+{
+ int trunc_len;
+
+ if (info->auth.mac.length < NTP_MIN_MAC_LENGTH)
+ return 0;
+
+ trunc_len = info->version == 4 && info->auth.mac.length <= NTP_MAX_V4_MAC_LENGTH ?
+ NTP_MAX_V4_MAC_LENGTH : NTP_MAX_MAC_LENGTH;
+
+ if (!KEY_CheckAuth(info->auth.mac.key_id, (void *)packet, info->auth.mac.start,
+ (unsigned char *)packet + info->auth.mac.start + 4,
+ info->auth.mac.length - 4, trunc_len - 4))
+ return 0;
+
+ return 1;
+}
+
+/* ================================================== */
+
+static void
+adjust_timestamp(NTP_AuthMode mode, uint32_t key_id, struct timespec *ts)
+{
+ switch (mode) {
+ case AUTH_SYMMETRIC:
+ ts->tv_nsec += KEY_GetAuthDelay(key_id);
+ UTI_NormaliseTimespec(ts);
+ break;
+ case AUTH_MSSNTP:
+ ts->tv_nsec += NSD_GetAuthDelay(key_id);
+ UTI_NormaliseTimespec(ts);
+ default:
+ break;
+ }
+}
+
+/* ================================================== */
+
+static NAU_Instance
+create_instance(NTP_AuthMode mode)
+{
+ NAU_Instance instance;
+
+ instance = MallocNew(struct NAU_Instance_Record);
+ instance->mode = mode;
+ instance->key_id = INACTIVE_AUTHKEY;
+
+ assert(sizeof (instance->key_id) == 4);
+
+ return instance;
+}
+
+/* ================================================== */
+
+NAU_Instance
+NAU_CreateNoneInstance(void)
+{
+ return create_instance(AUTH_NONE);
+}
+
+/* ================================================== */
+
+NAU_Instance
+NAU_CreateSymmetricInstance(uint32_t key_id)
+{
+ NAU_Instance instance = create_instance(AUTH_SYMMETRIC);
+
+ instance->key_id = key_id;
+
+ if (!KEY_KeyKnown(key_id))
+ LOG(LOGS_WARN, "Key %"PRIu32" is %s", key_id, "missing");
+ else if (!KEY_CheckKeyLength(key_id))
+ LOG(LOGS_WARN, "Key %"PRIu32" is %s", key_id, "too short");
+
+ return instance;
+}
+
+/* ================================================== */
+
+void
+NAU_DestroyInstance(NAU_Instance instance)
+{
+ Free(instance);
+}
+
+/* ================================================== */
+
+int
+NAU_IsAuthEnabled(NAU_Instance instance)
+{
+ return instance->mode != AUTH_NONE;
+}
+
+/* ================================================== */
+
+int
+NAU_GetSuggestedNtpVersion(NAU_Instance instance)
+{
+ /* If the MAC in NTPv4 packets would be truncated, prefer NTPv3 for
+ compatibility with older chronyd servers */
+ if (instance->mode == AUTH_SYMMETRIC &&
+ KEY_GetAuthLength(instance->key_id) + sizeof (instance->key_id) > NTP_MAX_V4_MAC_LENGTH)
+ return 3;
+
+ return NTP_VERSION;
+}
+
+/* ================================================== */
+
+int
+NAU_PrepareRequestAuth(NAU_Instance instance)
+{
+ switch (instance->mode) {
+ default:
+ break;
+ }
+
+ return 1;
+}
+
+/* ================================================== */
+
+void
+NAU_AdjustRequestTimestamp(NAU_Instance instance, struct timespec *ts)
+{
+ adjust_timestamp(instance->mode, instance->key_id, ts);
+}
+
+/* ================================================== */
+
+int
+NAU_GenerateRequestAuth(NAU_Instance instance, NTP_Packet *request, NTP_PacketInfo *info)
+{
+ switch (instance->mode) {
+ case AUTH_NONE:
+ break;
+ case AUTH_SYMMETRIC:
+ if (!generate_symmetric_auth(instance->key_id, request, info))
+ return 0;
+ break;
+ default:
+ assert(0);
+ }
+
+ return 1;
+}
+
+/* ================================================== */
+
+int
+NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info)
+{
+ switch (info->auth.mode) {
+ case AUTH_NONE:
+ break;
+ case AUTH_SYMMETRIC:
+ if (!check_symmetric_auth(request, info))
+ return 0;
+ break;
+ case AUTH_MSSNTP:
+ /* MS-SNTP requests are not authenticated */
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ================================================== */
+
+void
+NAU_AdjustResponseTimestamp(NTP_Packet *request, NTP_PacketInfo *info, struct timespec *ts)
+{
+ adjust_timestamp(info->auth.mode, info->auth.mac.key_id, ts);
+}
+
+/* ================================================== */
+
+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)
+{
+ switch (request_info->auth.mode) {
+ case AUTH_NONE:
+ break;
+ case AUTH_SYMMETRIC:
+ if (!generate_symmetric_auth(request_info->auth.mac.key_id, response, response_info))
+ return 0;
+ break;
+ case AUTH_MSSNTP:
+ /* Sign the packet asynchronously by ntp_signd */
+ if (!NSD_SignAndSendPacket(request_info->auth.mac.key_id, response, response_info,
+ remote_addr, local_addr))
+ return 0;
+ /* Don't send the original packet */
+ return 0;
+ default:
+ DEBUG_LOG("Could not authenticate response auth_mode=%d", (int)request_info->auth.mode);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ================================================== */
+
+int
+NAU_CheckResponseAuth(NAU_Instance instance, NTP_Packet *response, NTP_PacketInfo *info)
+{
+ /* If we don't expect the packet to be authenticated, ignore any
+ authentication data in the packet */
+ if (instance->mode == AUTH_NONE)
+ return 1;
+
+ /* The authentication must match the expected mode */
+ if (info->auth.mode != instance->mode)
+ return 0;
+
+ switch (info->auth.mode) {
+ case AUTH_NONE:
+ break;
+ case AUTH_SYMMETRIC:
+ /* Check if it is authenticated with the specified key */
+ if (info->auth.mac.key_id != instance->key_id)
+ return 0;
+ /* and that the MAC is valid */
+ if (!check_symmetric_auth(response, info))
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ Header file for NTP authentication
+ */
+
+#ifndef GOT_NTP_AUTH_H
+#define GOT_NTP_AUTH_H
+
+#include "addressing.h"
+#include "ntp.h"
+
+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);
+
+/* Destroy an instance */
+extern void NAU_DestroyInstance(NAU_Instance instance);
+
+/* Check if an instance is not in the None mode */
+extern int NAU_IsAuthEnabled(NAU_Instance instance);
+
+/* Get NTP version recommended for better compatibility */
+extern int NAU_GetSuggestedNtpVersion(NAU_Instance instance);
+
+/* Perform operations necessary for NAU_GenerateRequestAuth() */
+extern int NAU_PrepareRequestAuth(NAU_Instance instance);
+
+/* Adjust a transmit timestamp for an estimated minimum time it takes to call
+ NAU_GenerateRequestAuth() */
+extern void NAU_AdjustRequestTimestamp(NAU_Instance instance, struct timespec *ts);
+
+/* Extend a request with data required by the authentication mode */
+extern int NAU_GenerateRequestAuth(NAU_Instance instance, NTP_Packet *request,
+ NTP_PacketInfo *info);
+
+/* Verify that a request is authentic */
+extern int NAU_CheckRequestAuth(NTP_Packet *request, NTP_PacketInfo *info);
+
+/* Adjust a transmit timestamp for an estimated minimum time it takes to call
+ NAU_GenerateResponseAuth() */
+extern void NAU_AdjustResponseTimestamp(NTP_Packet *request, NTP_PacketInfo *info,
+ struct timespec *ts);
+
+/* Extend a response with data required by the authentication mode. This
+ function can be called only if the previous call of NAU_CheckRequestAuth()
+ was on the same request. */
+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);
+
+/* Verify that a response is authentic */
+extern int NAU_CheckResponseAuth(NAU_Instance instance, NTP_Packet *response,
+ NTP_PacketInfo *info);
+
+#endif
#include "sysincl.h"
#include "array.h"
+#include "ntp_auth.h"
#include "ntp_core.h"
#include "ntp_ext.h"
#include "ntp_io.h"
-#include "ntp_signd.h"
#include "memory.h"
#include "sched.h"
#include "reference.h"
double offset_correction; /* Correction applied to measured offset
(e.g. for asymmetry in network delay) */
- NTP_AuthMode auth_mode; /* Authentication mode of our requests */
- uint32_t auth_key_id; /* The ID of the authentication key to
- use. */
+ NAU_Instance auth; /* Authentication */
/* Count of transmitted packets since last valid response */
unsigned int tx_count;
typedef struct {
NTP_Remote_Address addr;
NTP_Local_Address local_addr;
+ NAU_Instance auth;
int interval;
} BroadcastDestination;
if (server_sock_fd6 != INVALID_SOCK_FD)
NIO_CloseServerSocket(server_sock_fd6);
- for (i = 0; i < ARR_GetSize(broadcasts); i++)
+ for (i = 0; i < ARR_GetSize(broadcasts); i++) {
NIO_CloseServerSocket(((BroadcastDestination *)ARR_GetElement(broadcasts, i))->local_addr.sock_fd);
+ NAU_DestroyInstance(((BroadcastDestination *)ARR_GetElement(broadcasts, i))->auth);
+ }
ARR_DestroyInstance(broadcasts);
ADF_DestroyTable(access_auth_table);
result->auto_offline = params->auto_offline;
result->poll_target = params->poll_target;
- result->version = NTP_VERSION;
-
- if (params->authkey == INACTIVE_AUTHKEY) {
- result->auth_mode = AUTH_NONE;
- result->auth_key_id = 0;
+ if (params->authkey != INACTIVE_AUTHKEY) {
+ result->auth = NAU_CreateSymmetricInstance(params->authkey);
} else {
- result->auth_mode = AUTH_SYMMETRIC;
- result->auth_key_id = params->authkey;
- if (!KEY_KeyKnown(result->auth_key_id)) {
- LOG(LOGS_WARN, "Key %"PRIu32" used by source %s is %s",
- result->auth_key_id, UTI_IPToString(&result->remote_addr.ip_addr),
- "missing");
- } else if (!KEY_CheckKeyLength(result->auth_key_id)) {
- LOG(LOGS_WARN, "Key %"PRIu32" used by source %s is %s",
- result->auth_key_id, UTI_IPToString(&result->remote_addr.ip_addr),
- "too short");
- }
-
- /* If the MAC in NTPv4 packets would be truncated, use version 3 by
- default for compatibility with older chronyd servers */
- if (KEY_GetAuthLength(result->auth_key_id) + 4 > NTP_MAX_V4_MAC_LENGTH)
- result->version = 3;
+ result->auth = NAU_CreateNoneInstance();
}
+ result->version = NAU_GetSuggestedNtpVersion(result->auth);
+
if (params->version)
result->version = CLAMP(NTP_MIN_COMPAT_VERSION, params->version, NTP_VERSION);
if (instance->filter)
SPF_DestroyInstance(instance->filter);
+ NAU_DestroyInstance(instance->auth);
+
/* This will destroy the source instance inside the
structure, which will cause reselection if this was the
synchronising source etc. */
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 */
- int auth_mode, /* The authentication mode */
- uint32_t key_id, /* The authentication key ID */
+ 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 */
NTP_Local_Timestamp *local_rx, /* The RX time of the received packet */
{
NTP_PacketInfo info;
NTP_Packet message;
- int auth_len, max_auth_len, ret, precision;
struct timespec local_receive, local_transmit;
double smooth_offset, local_transmit_err;
+ int ret, precision;
NTP_int64 ts_fuzz;
/* Parameters read from reference module */
struct timespec our_ref_time;
double our_root_delay, our_root_dispersion;
+ assert(auth || (request && request_info));
+
/* Don't reply with version higher than ours */
if (version > NTP_VERSION) {
version = NTP_VERSION;
if (smooth_time)
UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
- /* Authenticate the packet */
-
- if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) {
- /* Pre-compensate the transmit time by approximately how long it will
- take to generate the authentication data */
- local_transmit.tv_nsec += auth_mode == AUTH_SYMMETRIC ?
- KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id);
- UTI_NormaliseTimespec(&local_transmit);
- UTI_TimespecToNtp64(interleaved ? &local_tx->ts : &local_transmit,
- &message.transmit_ts, &ts_fuzz);
-
- if (auth_mode == AUTH_SYMMETRIC) {
- /* Truncate long MACs in NTPv4 packets to allow deterministic parsing
- of extension fields (RFC 7822) */
- max_auth_len = (version == 4 ?
- NTP_MAX_V4_MAC_LENGTH : (sizeof (message) - info.length)) - 4;
-
- auth_len = KEY_GenerateAuth(key_id, (unsigned char *)&message, info.length,
- (unsigned char *)&message + info.length + 4, max_auth_len);
- if (!auth_len) {
- DEBUG_LOG("Could not generate auth data with key %"PRIu32, key_id);
- return 0;
- }
+ /* Pre-compensate the transmit time by approximately how long it will take
+ to generate the authentication data */
+ if (auth)
+ NAU_AdjustRequestTimestamp(auth, &local_transmit);
+ else
+ NAU_AdjustResponseTimestamp(request, request_info, &local_transmit);
- *(uint32_t *)((unsigned char *)&message + info.length) = htonl(key_id);
- info.length += 4 + auth_len;
- } else if (auth_mode == AUTH_MSSNTP) {
- /* MS-SNTP packets are signed (asynchronously) by ntp_signd */
- return NSD_SignAndSendPacket(key_id, &message, &info, where_to, from);
+ UTI_TimespecToNtp64(interleaved ? &local_tx->ts : &local_transmit,
+ &message.transmit_ts, &ts_fuzz);
+
+ /* Generate the authentication data */
+ if (auth) {
+ if (!NAU_GenerateRequestAuth(auth, &message, &info)) {
+ DEBUG_LOG("Could not generate request auth");
+ return 0;
}
} else {
- UTI_TimespecToNtp64(interleaved ? &local_tx->ts : &local_transmit,
- &message.transmit_ts, &ts_fuzz);
+ if (!NAU_GenerateResponseAuth(request, request_info, &message, &info, where_to, from)) {
+ DEBUG_LOG("Could not generate response auth");
+ return 0;
+ }
}
/* Do not send a packet with a non-zero transmit timestamp which is
DEBUG_LOG("Transmit timeout for %s", UTI_IPSockAddrToString(&inst->remote_addr));
+ /* Prepare authentication */
+ if (!NAU_PrepareRequestAuth(inst->auth)) {
+ if (inst->burst_total_samples_to_go > 0)
+ inst->burst_total_samples_to_go--;
+ adjust_poll(inst, 0.25);
+ SRC_UpdateReachability(inst->source, 0);
+ restart_timeout(inst, get_transmit_delay(inst, 1, 0.0));
+ return;
+ }
+
/* Open new client socket */
if (inst->mode == MODE_CLIENT) {
close_client_socket(inst);
/* Send the request (which may also be a response in the symmetric mode) */
sent = transmit_packet(inst->mode, interleaved, inst->local_poll, inst->version,
- inst->auth_mode, inst->auth_key_id,
+ inst->auth,
initial ? NULL : &inst->remote_ntp_rx,
initial ? &inst->init_remote_ntp_tx : &inst->remote_ntp_tx,
initial ? &inst->init_local_rx : &inst->local_rx,
/* ================================================== */
-static int
-check_symmetric_auth(NTP_Packet *packet, NTP_PacketInfo *info)
-{
- int trunc_len;
-
- if (info->auth.mac.length < NTP_MIN_MAC_LENGTH)
- return 0;
-
- trunc_len = info->version == 4 && info->auth.mac.length <= NTP_MAX_V4_MAC_LENGTH ?
- NTP_MAX_V4_MAC_LENGTH : NTP_MAX_MAC_LENGTH;
-
- if (!KEY_CheckAuth(info->auth.mac.key_id, (void *)packet, info->auth.mac.start,
- (unsigned char *)packet + info->auth.mac.start + 4,
- info->auth.mac.length - 4, trunc_len - 4))
- return 0;
-
- return 1;
-}
-
-/* ================================================== */
-
-static int
-check_packet_auth(NTP_Packet *packet, NTP_PacketInfo *info,
- NTP_AuthMode *auth_mode, uint32_t *key_id)
-{
- *auth_mode = info->auth.mode;
-
- if (info->auth.mode != AUTH_SYMMETRIC)
- return 0;
-
- if (!check_symmetric_auth(packet, info))
- return 0;
-
- *key_id = info->auth.mac.key_id;
- return 1;
-}
-
-/* ================================================== */
-
static int
check_delay_ratio(NCR_Instance inst, SST_Stats stats,
struct timespec *sample_time, double delay)
SST_Stats stats;
int pkt_leap, pkt_version;
- uint32_t pkt_refid, pkt_key_id;
+ uint32_t pkt_refid;
double pkt_root_delay;
double pkt_root_dispersion;
- NTP_AuthMode pkt_auth_mode;
/* The skew and estimated frequency offset relative to the remote source */
double skew, source_freq_lo, source_freq_hi;
/* Test 4 would check for denied access. It would always pass as this
function is called only for known sources. */
- /* Test 5 checks for authentication failure. If we expect authenticated info
- from this peer/server and the packet doesn't have it, the authentication
- is bad, or it's authenticated with a different key than expected, it's got
- to fail. If we don't expect the packet to be authenticated, just ignore
- the test. */
- test5 = inst->auth_mode == AUTH_NONE ||
- (check_packet_auth(message, info, &pkt_auth_mode, &pkt_key_id) &&
- pkt_auth_mode == inst->auth_mode && pkt_key_id == inst->auth_key_id);
+ /* Test 5 checks for authentication failure */
+ test5 = NAU_CheckResponseAuth(inst->auth, message, info);
/* Test 6 checks for unsynchronised server */
test6 = pkt_leap != LEAP_Unsynchronised &&
test5) << 1 | test6) << 1 | test7) << 1 |
testA) << 1 | testB) << 1 | testC) << 1 | testD;
inst->report.interleaved = interleaved_packet;
- inst->report.authenticated = inst->auth_mode != AUTH_NONE;
+ inst->report.authenticated = NAU_IsAuthEnabled(inst->auth);
inst->report.tx_tss_char = tss_chars[local_transmit.source];
inst->report.rx_tss_char = tss_chars[local_receive.source];
NTP_Mode my_mode;
NTP_int64 *local_ntp_rx, *local_ntp_tx;
NTP_Local_Timestamp local_tx, *tx_ts;
- int valid_auth, log_index, interleaved, poll, version;
- NTP_AuthMode auth_mode;
- uint32_t key_id;
+ int log_index, interleaved, poll, version;
/* Ignore the packet if it wasn't received by server socket */
if (!NIO_IsServerSocket(local_addr->sock_fd)) {
return;
}
- /* Check if the packet includes MAC that authenticates properly */
- valid_auth = check_packet_auth(message, &info, &auth_mode, &key_id);
-
- /* If authentication failed, select whether and how we should respond */
- if (!valid_auth) {
- switch (auth_mode) {
- case AUTH_NONE:
- /* Reply with no MAC */
- break;
- case AUTH_MSSNTP:
- /* Ignore the failure (MS-SNTP servers don't check client MAC) */
- break;
- default:
- /* Discard packets in other modes */
- DEBUG_LOG("NTP packet discarded auth_mode=%u", auth_mode);
- return;
- }
+ /* Check authentication */
+ if (!NAU_CheckRequestAuth(message, &info)) {
+ DEBUG_LOG("NTP packet discarded auth mode=%d", (int)info.auth.mode);
+ return;
}
/* If it is an NTPv4 packet with a long MAC and no extension fields,
poll = MAX(poll, message->poll);
/* Send a reply */
- transmit_packet(my_mode, interleaved, poll, version,
- auth_mode, key_id, &message->receive_ts, &message->transmit_ts,
+ transmit_packet(my_mode, interleaved, poll, version, NULL,
+ &message->receive_ts, &message->transmit_ts,
rx_ts, tx_ts, local_ntp_rx, NULL, remote_addr, local_addr,
message, &info);
UTI_ZeroNtp64(&orig_ts);
zero_local_timestamp(&recv_ts);
- transmit_packet(MODE_BROADCAST, 0, poll, NTP_VERSION, 0, 0, &orig_ts, &orig_ts, &recv_ts,
- NULL, NULL, NULL, &destination->addr, &destination->local_addr, NULL, NULL);
+ transmit_packet(MODE_BROADCAST, 0, poll, NTP_VERSION, destination->auth,
+ &orig_ts, &orig_ts, &recv_ts, NULL, NULL, NULL,
+ &destination->addr, &destination->local_addr, NULL, NULL);
/* Requeue timeout. We don't care if interval drifts gradually. */
SCH_AddTimeoutInClass(destination->interval, get_separation(poll), SAMPLING_RANDOMNESS,
destination->local_addr.ip_addr.family = IPADDR_UNSPEC;
destination->local_addr.if_index = INVALID_IF_INDEX;
destination->local_addr.sock_fd = NIO_OpenServerSocket(&destination->addr);
+ destination->auth = NAU_CreateNoneInstance();
destination->interval = CLAMP(1, interval, 1 << MAX_POLL);
SCH_AddTimeoutInClass(destination->interval, MAX_SAMPLING_SEPARATION, SAMPLING_RANDOMNESS,