]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: add support for MS-SNTP authentication in Samba
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 27 Jul 2016 12:09:32 +0000 (14:09 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 29 Jul 2016 08:17:33 +0000 (10:17 +0200)
Add support for authenticating MS-SNTP responses in Samba (ntp_signd).
Supported is currently only the old MS-SNTP authenticator field. It's
disabled by default. It can be enabled with the --enable-ntp-signd
configure option and the ntpsigndsocket directive, which specifies the
location of the Samba ntp_signd socket.

conf.c
conf.h
configure
doc/chrony.conf.adoc
logging.h
main.c
ntp_core.c
ntp_signd.c [new file with mode: 0644]
ntp_signd.h [new file with mode: 0644]
stubs.c
test/compilation/001-features

diff --git a/conf.c b/conf.c
index 5d31091815d5f00b0adfbb81dd686ca7872cc0df..316275b80d98e9e325542443e95645f4a67045f5 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -181,6 +181,9 @@ static IPAddr bind_cmd_address4, bind_cmd_address6;
 /* Path to the Unix domain command socket. */
 static char *bind_cmd_path;
 
+/* Path to Samba (ntp_signd) socket. */
+static char *ntp_signd_socket = NULL;
+
 /* Filename to use for storing pid of running chronyd, to prevent multiple
  * chronyds being started. */
 static char *pidfile;
@@ -361,6 +364,7 @@ CNF_Finalise(void)
   Free(leapsec_tz);
   Free(logdir);
   Free(bind_cmd_path);
+  Free(ntp_signd_socket);
   Free(pidfile);
   Free(rtc_device);
   Free(rtc_file);
@@ -506,6 +510,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
     parse_int(p, &min_sources);
   } else if (!strcasecmp(command, "noclientlog")) {
     no_client_log = parse_null(p);
+  } else if (!strcasecmp(command, "ntpsigndsocket")) {
+    parse_string(p, &ntp_signd_socket);
   } else if (!strcasecmp(command, "peer")) {
     parse_source(p, NTP_PEER, 0);
   } else if (!strcasecmp(command, "pidfile")) {
@@ -1736,6 +1742,14 @@ CNF_GetBindCommandAddress(int family, IPAddr *addr)
 
 /* ================================================== */
 
+char *
+CNF_GetNtpSigndSocket(void)
+{
+  return ntp_signd_socket;
+}
+
+/* ================================================== */
+
 char *
 CNF_GetPidFile(void)
 {
diff --git a/conf.h b/conf.h
index 7168fb3da97e1cacc8edbb2a7f0a27e4221ec715..ae5a890ac2e6b87aa9d88d4be10a21424e42d2d6 100644 (file)
--- a/conf.h
+++ b/conf.h
@@ -76,6 +76,7 @@ extern void CNF_GetBindAddress(int family, IPAddr *addr);
 extern void CNF_GetBindAcquisitionAddress(int family, IPAddr *addr);
 extern void CNF_GetBindCommandAddress(int family, IPAddr *addr);
 extern char *CNF_GetBindCommandPath(void);
+extern char *CNF_GetNtpSigndSocket(void);
 extern char *CNF_GetPidFile(void);
 extern REF_LeapMode CNF_GetLeapSecMode(void);
 extern char *CNF_GetLeapSecTimezone(void);
index cb1d139acc6177614f2fbdcaeae896da954eeccf..a14126bf5b7000a068bd24820db81146e334f871 100755 (executable)
--- a/configure
+++ b/configure
@@ -99,6 +99,7 @@ For better control, use the options below.
   --without-seccomp      Don't use seccomp even if it is available
   --disable-asyncdns     Disable asynchronous name resolving
   --disable-forcednsretry Don't retry on permanent DNS error
+  --enable-ntp-signd     Enable support for MS-SNTP authentication in Samba
   --with-ntp-era=SECONDS Specify earliest assumed NTP time in seconds
                          since 1970-01-01 [50*365 days ago]
   --with-user=USER       Specify default chronyd user [root]
@@ -213,6 +214,7 @@ try_setsched=0
 try_lockmem=0
 feat_asyncdns=1
 feat_forcednsretry=1
+feat_ntp_signd=0
 ntp_era_split=""
 default_user="root"
 default_hwclockfile=""
@@ -317,6 +319,9 @@ do
     --disable-forcednsretry)
       feat_forcednsretry=0
     ;;
+    --enable-ntp-signd)
+      feat_ntp_signd=1
+    ;;
     --with-ntp-era=* )
       ntp_era_split=`echo $option | sed -e 's/^.*=//;'`
     ;;
@@ -432,6 +437,10 @@ fi
 if [ $feat_ntp = "1" ]; then
   add_def FEAT_NTP
   EXTRA_OBJECTS="$EXTRA_OBJECTS ntp_core.o ntp_io.o ntp_sources.o"
+  if [ $feat_ntp_signd = "1" ]; then
+    add_def FEAT_SIGND
+    EXTRA_OBJECTS="$EXTRA_OBJECTS ntp_signd.o"
+  fi
 else
   feat_asyncdns=0
 fi
@@ -826,7 +835,7 @@ add_def MAIL_PROGRAM "\"$mail_program\""
 
 common_features="`get_features IPV6 DEBUG`"
 chronyc_features="`get_features READLINE`"
-chronyd_features="`get_features CMDMON NTP REFCLOCK RTC PRIVDROP SCFILTER SECHASH ASYNCDNS`"
+chronyd_features="`get_features CMDMON NTP REFCLOCK RTC PRIVDROP SCFILTER SECHASH SIGND ASYNCDNS`"
 add_def CHRONYC_FEATURES "\"$chronyc_features $common_features\""
 add_def CHRONYD_FEATURES "\"$chronyd_features $common_features\""
 echo "Features : $chronyd_features $chronyc_features $common_features"
index fcfefdb61544c5b4e16361ff84f48fce9714e73e..33fbfca85f46ad955323b006c93a8da4b2145160 100644 (file)
@@ -1760,6 +1760,20 @@ should result in lower and more consistent latency. It should not have
 significant impact on performance as *chronyd's* memory usage is modest. The
 *mlockall(2)* man page has more details.
 
+[[ntpsigndsocket]]*ntpsigndsocket* _directory_::
+This directive specifies the location of the Samba *ntp_signd* socket when it
+is running as a Domain Controller (DC). If *chronyd* is compiled with this
+feature, responses to MS-SNTP clients will be signed by the *smbd* daemon. Note
+that MS-SNTP requests are not authenticated, so any NTP client can get
+responses authenticated with passwords of users in the domain. Access to the
+server should be carefully controlled.
++
+An example of the directive is:
++
+----
+ntpsigndsocket /var/lib/samba/ntp_signd
+----
+
 [[pidfile]]*pidfile* _file_::
 *chronyd* always writes its process ID (PID) to a file, and checks this file on
 startup to see if another *chronyd* may already be running on the system. By
index 77d376e915a943389256ce699a5ea05f6c030a36..f3ebb476e1a50aee5f5327dab79654303c5e5b34 100644 (file)
--- a/logging.h
+++ b/logging.h
@@ -83,6 +83,7 @@ typedef enum {
   LOGF_Reference,
   LOGF_NtpIO,
   LOGF_NtpCore,
+  LOGF_NtpSignd,
   LOGF_NtpSources,
   LOGF_Scheduler,
   LOGF_SourceStats,
diff --git a/main.c b/main.c
index 214934eadee2637bbc79299f38ac651fe6351623..2ae36512429c59e637a19b9fe0c6db1c6be7dacd 100644 (file)
--- a/main.c
+++ b/main.c
@@ -35,6 +35,7 @@
 #include "local.h"
 #include "sys.h"
 #include "ntp_io.h"
+#include "ntp_signd.h"
 #include "ntp_sources.h"
 #include "ntp_core.h"
 #include "sources.h"
@@ -107,6 +108,7 @@ MAI_CleanupAndExit(void)
   TMC_Finalise();
   MNL_Finalise();
   CLG_Finalise();
+  NSD_Finalise();
   NSR_Finalise();
   SST_Finalise();
   NCR_Finalise();
@@ -523,6 +525,7 @@ int main
   REF_Initialise();
   SST_Initialise();
   NSR_Initialise();
+  NSD_Initialise();
   CLG_Initialise();
   MNL_Initialise();
   TMC_Initialise();
index 09ee03b4fffb21df90d4f984726dca9656fd0351..c325a80aebe4470f31b3b0ad542d6c073998899c 100644 (file)
@@ -32,6 +32,7 @@
 #include "array.h"
 #include "ntp_core.h"
 #include "ntp_io.h"
+#include "ntp_signd.h"
 #include "memory.h"
 #include "sched.h"
 #include "reference.h"
@@ -919,24 +920,28 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
 
   /* Authenticate the packet if needed */
 
-  if (auth_mode == AUTH_SYMMETRIC) {
+  if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) {
     /* Pre-compensate the transmit time by approx. how long it will
        take to generate the authentication data. */
-    local_transmit.tv_usec += KEY_GetAuthDelay(key_id);
+    local_transmit.tv_usec += auth_mode == AUTH_SYMMETRIC ?
+                              KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id);
     UTI_NormaliseTimeval(&local_transmit);
     UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
 
-    auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
-        offsetof(NTP_Packet, auth_keyid),
-        (unsigned char *)&message.auth_data, sizeof (message.auth_data));
-    if (auth_len > 0) {
+    if (auth_mode == AUTH_SYMMETRIC) {
+      auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
+                                  offsetof(NTP_Packet, auth_keyid),
+                                  (unsigned char *)&message.auth_data,
+                                  sizeof (message.auth_data));
+      if (!auth_len) {
+        DEBUG_LOG(LOGF_NtpCore, "Could not generate auth data with key %"PRIu32, key_id);
+        return 0;
+      }
       message.auth_keyid = htonl(key_id);
       length += sizeof (message.auth_keyid) + auth_len;
-    } else {
-      DEBUG_LOG(LOGF_NtpCore,
-                "Could not generate auth data with key %"PRIu32" to send packet",
-                key_id);
-      return 0;
+    } else if (auth_mode == AUTH_MSSNTP) {
+      /* MS-SNTP packets are signed (asynchronously) by ntp_signd */
+      return NSD_SignAndSendPacket(key_id, &message, where_to, from, length);
     }
   } else {
     if (auth_mode == AUTH_CRYPTO_NAK) {
@@ -1755,6 +1760,9 @@ NCR_ProcessUnknown
         /* Reply with crypto-NAK */
         auth_mode = AUTH_CRYPTO_NAK;
         break;
+      case AUTH_MSSNTP:
+        /* Ignore the failure (MS-SNTP servers don't check client MAC) */
+        break;
       default:
         /* Discard packets in other modes */
         DEBUG_LOG(LOGF_NtpCore, "NTP packet discarded auth_mode=%d", auth_mode);
diff --git a/ntp_signd.c b/ntp_signd.c
new file mode 100644 (file)
index 0000000..c237391
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar  2016
+ * 
+ * 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.
+ * 
+ **********************************************************************
+
+  =======================================================================
+
+  Support for MS-SNTP authentication in Samba (ntp_signd)
+  */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include "array.h"
+#include "conf.h"
+#include "logging.h"
+#include "ntp_io.h"
+#include "ntp_signd.h"
+#include "sched.h"
+#include "util.h"
+
+/* Declarations per samba/source4/librpc/idl/ntp_signd.idl */
+
+#define SIGND_VERSION 0
+
+typedef enum {
+  SIGN_TO_CLIENT = 0,
+  ASK_SERVER_TO_SIGN = 1,
+  CHECK_SERVER_SIGNATURE = 2,
+  SIGNING_SUCCESS = 3,
+  SIGNING_FAILURE = 4,
+} SigndOp;
+
+typedef struct {
+  uint32_t length;
+  uint32_t version;
+  uint32_t op;
+  uint16_t packet_id;
+  uint16_t _pad;
+  uint32_t key_id;
+  NTP_Packet packet_to_sign;
+} SigndRequest;
+
+typedef struct {
+  uint32_t length;
+  uint32_t version;
+  uint32_t op;
+  uint32_t packet_id;
+  NTP_Packet signed_packet;
+} SigndResponse;
+
+typedef struct {
+  NTP_Remote_Address remote_addr;
+  NTP_Local_Address local_addr;
+
+  int sent;
+  int received;
+  int request_length;
+  struct timeval request_tv;
+  SigndRequest request;
+  SigndResponse response;
+} SignInstance;
+
+/* As the communication with ntp_signd is asynchronous, incoming packets are
+   saved in a queue in order to avoid loss when they come in bursts */
+
+#define MAX_QUEUE_LENGTH 16U
+#define NEXT_QUEUE_INDEX(index) (((index) + 1) % MAX_QUEUE_LENGTH)
+#define IS_QUEUE_EMPTY() (queue_head == queue_tail)
+
+/* Fixed-size array of SignInstance */
+static ARR_Instance queue;
+static unsigned int queue_head;
+static unsigned int queue_tail;
+
+#define INVALID_SOCK_FD -1
+
+/* Unix domain socket connected to ntp_signd */
+static int sock_fd;
+
+#define MIN_AUTH_DELAY 1.0e-5
+#define MAX_AUTH_DELAY 1.0e-2
+
+/* Average time needed for signing one packet.  This is used to adjust the
+   transmit timestamp in NTP packets.  The timestamp won't be very accurate as
+   the delay is variable, but it should be good enough for MS-SNTP clients. */
+static double auth_delay;
+
+/* Flag indicating if the MS-SNTP authentication is enabled */
+static int enabled;
+
+/* ================================================== */
+
+static void read_write_socket(int sock_fd, int event, void *anything);
+
+/* ================================================== */
+
+static void
+close_socket(void)
+{
+  SCH_RemoveFileHandler(sock_fd);
+  close(sock_fd);
+  sock_fd = INVALID_SOCK_FD;
+
+  /* Empty the queue */
+  queue_head = queue_tail = 0;
+}
+
+/* ================================================== */
+
+static int
+open_socket(void)
+{
+  struct sockaddr_un s;
+
+  if (sock_fd >= 0)
+    return 1;
+
+  sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (sock_fd < 0) {
+    DEBUG_LOG(LOGF_NtpSignd, "Could not open signd socket : %s", strerror(errno));
+    return 0;
+  }
+
+  UTI_FdSetCloexec(sock_fd);
+  SCH_AddFileHandler(sock_fd, SCH_FILE_INPUT, read_write_socket, NULL);
+
+  s.sun_family = AF_UNIX;
+  if (snprintf(s.sun_path, sizeof (s.sun_path), "%s/socket",
+               CNF_GetNtpSigndSocket()) >= sizeof (s.sun_path)) {
+    DEBUG_LOG(LOGF_NtpSignd, "signd socket path too long");
+    close_socket();
+    return 0;
+  }
+
+  if (connect(sock_fd, (struct sockaddr *)&s, sizeof (s)) < 0) {
+    DEBUG_LOG(LOGF_NtpSignd, "Could not connect to signd : %s", strerror(errno));
+    close_socket();
+    return 0;
+  }
+
+  DEBUG_LOG(LOGF_NtpSignd, "Connected to signd");
+
+  return 1;
+}
+
+/* ================================================== */
+
+static void
+process_response(SignInstance *inst)
+{
+  struct timeval tv;
+  double delay;
+
+  if (ntohs(inst->request.packet_id) != ntohl(inst->response.packet_id)) {
+    DEBUG_LOG(LOGF_NtpSignd, "Invalid response ID");
+    return;
+  }
+
+  if (ntohl(inst->response.op) != SIGNING_SUCCESS) {
+    DEBUG_LOG(LOGF_NtpSignd, "Signing failed");
+    return;
+  }
+
+  /* Check if the file descriptor is still valid */
+  if (!NIO_IsServerSocket(inst->local_addr.sock_fd)) {
+    DEBUG_LOG(LOGF_NtpSignd, "Invalid NTP socket");
+    return;
+  }
+
+  SCH_GetLastEventTime(NULL, NULL, &tv);
+  UTI_DiffTimevalsToDouble(&delay, &tv, &inst->request_tv);
+
+  DEBUG_LOG(LOGF_NtpSignd, "Signing succeeded (delay %f)", delay);
+
+  /* Send the signed NTP packet */
+  NIO_SendPacket(&inst->response.signed_packet, &inst->remote_addr, &inst->local_addr,
+                 ntohl(inst->response.length) + sizeof (inst->response.length) -
+                 offsetof(SigndResponse, signed_packet));
+
+  /* Update exponential moving average of the authentication delay */
+  delay = CLAMP(MIN_AUTH_DELAY, delay, MAX_AUTH_DELAY);
+  auth_delay += 0.1 * (delay - auth_delay);
+}
+
+/* ================================================== */
+
+static void
+read_write_socket(int sock_fd, int event, void *anything)
+{
+  SignInstance *inst;
+  uint32_t response_length;
+  int s;
+
+  inst = ARR_GetElement(queue, queue_head);
+
+  if (event == SCH_FILE_OUTPUT) {
+    assert(!IS_QUEUE_EMPTY());
+    assert(inst->sent < inst->request_length);
+
+    if (!inst->sent)
+      SCH_GetLastEventTime(NULL, NULL, &inst->request_tv);
+
+    s = send(sock_fd, (char *)&inst->request + inst->sent,
+             inst->request_length - inst->sent, 0);
+
+    if (s < 0) {
+      DEBUG_LOG(LOGF_NtpSignd, "signd socket error: %s", strerror(errno));
+      close_socket();
+      return;
+    }
+
+    DEBUG_LOG(LOGF_NtpSignd, "Sent %d bytes to signd", s);
+    inst->sent += s;
+
+    /* Try again later if the request is not complete yet */
+    if (inst->sent < inst->request_length)
+      return;
+
+    /* Disable output and wait for a response */
+    SCH_SetFileHandlerEvents(sock_fd, SCH_FILE_INPUT);
+  }
+
+  if (event == SCH_FILE_INPUT) {
+    if (IS_QUEUE_EMPTY()) {
+        DEBUG_LOG(LOGF_NtpSignd, "Unexpected signd response");
+        close_socket();
+        return;
+    }
+
+    assert(inst->received < sizeof (inst->response));
+    s = recv(sock_fd, (char *)&inst->response + inst->received,
+             sizeof (inst->response) - inst->received, 0);
+
+    if (s <= 0) {
+      if (s < 0)
+        DEBUG_LOG(LOGF_NtpSignd, "signd socket error: %s", strerror(errno));
+      else
+        DEBUG_LOG(LOGF_NtpSignd, "signd socket closed");
+
+      close_socket();
+      return;
+    }
+
+    DEBUG_LOG(LOGF_NtpSignd, "Received %d bytes from signd", s);
+    inst->received += s;
+
+    if (inst->received < sizeof (inst->response.length))
+      return;
+
+    response_length = ntohl(inst->response.length) + sizeof (inst->response.length);
+
+    if (response_length < offsetof(SigndResponse, signed_packet) ||
+        response_length > sizeof (SigndResponse)) {
+      DEBUG_LOG(LOGF_NtpSignd, "Invalid response length");
+      close_socket();
+      return;
+    }
+
+    /* Wait for more data if not complete yet */
+    if (inst->received < response_length)
+      return;
+
+    process_response(inst);
+
+    /* Move the head and enable output for the next packet */
+    queue_head = NEXT_QUEUE_INDEX(queue_head);
+    if (!IS_QUEUE_EMPTY())
+      SCH_SetFileHandlerEvents(sock_fd, SCH_FILE_INPUT | SCH_FILE_OUTPUT);
+  }
+}
+
+/* ================================================== */
+
+void
+NSD_Initialise()
+{
+  sock_fd = INVALID_SOCK_FD;
+  auth_delay = MIN_AUTH_DELAY;
+  enabled = CNF_GetNtpSigndSocket() && CNF_GetNtpSigndSocket()[0];
+
+  if (!enabled)
+    return;
+
+  queue = ARR_CreateInstance(sizeof (SignInstance));
+  ARR_SetSize(queue, MAX_QUEUE_LENGTH);
+  queue_head = queue_tail = 0;
+
+  LOG(LOGS_INFO, LOGF_NtpSignd, "MS-SNTP authentication enabled");
+}
+
+/* ================================================== */
+
+void
+NSD_Finalise()
+{
+  if (!enabled)
+    return;
+  if (sock_fd != INVALID_SOCK_FD)
+    close_socket();
+  ARR_DestroyInstance(queue);
+}
+
+/* ================================================== */
+
+extern int NSD_GetAuthDelay(uint32_t key_id)
+{
+  return auth_delay * 1.0e6;
+}
+
+/* ================================================== */
+
+int
+NSD_SignAndSendPacket(uint32_t key_id, NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
+{
+  SignInstance *inst;
+
+  if (!enabled) {
+    DEBUG_LOG(LOGF_NtpSignd, "signd disabled");
+    return 0;
+  }
+
+  if (queue_head == NEXT_QUEUE_INDEX(queue_tail)) {
+    DEBUG_LOG(LOGF_NtpSignd, "signd queue full");
+    return 0;
+  }
+
+  if (length != NTP_NORMAL_PACKET_LENGTH) {
+    DEBUG_LOG(LOGF_NtpSignd, "Invalid packet length");
+    return 0;
+  }
+
+  if (!open_socket())
+    return 0;
+
+  inst = ARR_GetElement(queue, queue_tail);
+  inst->remote_addr = *remote_addr;
+  inst->local_addr = *local_addr;
+  inst->sent = 0;
+  inst->received = 0;
+  inst->request_length = offsetof(SigndRequest, packet_to_sign) + length;
+
+  /* The length field doesn't include itself */
+  inst->request.length = htonl(inst->request_length - sizeof (inst->request.length));
+  inst->request.version = htonl(SIGND_VERSION);
+  inst->request.op = htonl(SIGN_TO_CLIENT);
+  inst->request.packet_id = htons(queue_tail);
+  inst->request._pad = 0;
+  inst->request.key_id = htonl(key_id);
+
+  memcpy(&inst->request.packet_to_sign, packet, length);
+
+  /* Enable output if there was no pending request */
+  if (IS_QUEUE_EMPTY())
+    SCH_SetFileHandlerEvents(sock_fd, SCH_FILE_INPUT | SCH_FILE_OUTPUT);
+
+  queue_tail = NEXT_QUEUE_INDEX(queue_tail);
+
+  DEBUG_LOG(LOGF_NtpSignd, "Packet added to signd queue (%u:%u)",
+            queue_head, queue_tail);
+
+  return 1;
+}
diff --git a/ntp_signd.h b/ntp_signd.h
new file mode 100644 (file)
index 0000000..f45a5cb
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar  2016
+ * 
+ * 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 for MS-SNTP authentication via Samba (ntp_signd) */
+
+#ifndef GOT_NTP_SIGND_H
+#define GOT_NTP_SIGND_H
+
+#include "addressing.h"
+#include "ntp.h"
+
+/* Initialisation function */
+extern void NSD_Initialise(void);
+
+/* Finalisation function */
+extern void NSD_Finalise(void);
+
+/* Function to get an estimate of delay due to signing */
+extern int NSD_GetAuthDelay(uint32_t key_id);
+
+/* Function to sign an NTP packet and send it */
+extern int NSD_SignAndSendPacket(uint32_t key_id, NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
+
+#endif
diff --git a/stubs.c b/stubs.c
index a5e50b65807d7173c859e578406755a3a27431c3..648bb796c893031357c2c0237401319027e25ae5 100644 (file)
--- a/stubs.c
+++ b/stubs.c
@@ -38,6 +38,7 @@
 #include "ntp_core.h"
 #include "ntp_io.h"
 #include "ntp_sources.h"
+#include "ntp_signd.h"
 #include "privops.h"
 #include "refclock.h"
 #include "sched.h"
@@ -367,3 +368,29 @@ RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
 }
 
 #endif /* !FEAT_REFCLOCK */
+
+#ifndef FEAT_SIGND
+
+void
+NSD_Initialise(void)
+{
+}
+
+void
+NSD_Finalise(void)
+{
+}
+
+int
+NSD_GetAuthDelay(uint32_t key_id)
+{
+  return 0;
+}
+
+int
+NSD_SignAndSendPacket(uint32_t key_id, NTP_Packet *packet, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
+{
+  return 0;
+}
+
+#endif /* !FEAT_SIGND */
index 9da21d23079b157beb80fd773c75dd04fb87138d..783e6018f7f2017a681f6ea367816f380400df6a 100755 (executable)
@@ -6,6 +6,7 @@ cd ../..
 
 for opts in \
        "--enable-debug" \
+       "--enable-ntp-signd" \
        "--enable-scfilter" \
        "--disable-asyncdns" \
        "--disable-ipv6" \