]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Sec 2936] Skeleton Key: Any trusted key system can serve time. HStenn.
authorHarlan Stenn <stenn@ntp.org>
Mon, 18 Jan 2016 11:55:56 +0000 (11:55 +0000)
committerHarlan Stenn <stenn@ntp.org>
Mon, 18 Jan 2016 11:55:56 +0000 (11:55 +0000)
bk: 569cd2ccRluJHjvqRvxDmstIPiBftA

23 files changed:
ChangeLog
NEWS
include/Makefile.am
include/ntp_io.h
include/ntp_keyacc.h [new file with mode: 0644]
include/ntp_stdlib.h
include/ntp_types.h
libntp/Makefile.am
libntp/authkeys.c
libntp/authreadkeys.c
libntp/authusekey.c
libntp/is_ip_address.c [new file with mode: 0644]
ntpd/invoke-ntp.keys.texi
ntpd/ntp.keys.5man
ntpd/ntp.keys.5mdoc
ntpd/ntp.keys.def
ntpd/ntp.keys.html
ntpd/ntp.keys.man.in
ntpd/ntp.keys.mdoc.in
ntpd/ntp_crypto.c
ntpd/ntp_io.c
ntpd/ntp_proto.c
tests/libntp/authkeys.c

index 7f336f64dcc0841e0da3a0f581217cabdab0da93..d71ee357202b020113d6d456c3dc7160f46b9a97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 ---
 
 * [Sec 2935] Deja Vu: Replay attack on authenticated broadcast mode. HStenn.
+* [Sec 2936] Skeleton Key: Any trusted key system can serve time. HStenn.
 * [Sec 2937] ntpq: nextvar() missing length check. perlinger@ntp.org
 * [Sec 2938] ntpq saveconfig command allows dangerous characters
   in filenames. perlinger@ntp.org
diff --git a/NEWS b/NEWS
index e90024109b7208f8359d5bcac28bcfe46629f42e..c759e898c43a078784ea30e001ca278ad5439d26 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -171,6 +171,46 @@ following X low- and Y medium-severity vulnerabilities:
            This is potentially more dangerous if ntpq is run as root. 
     Credit: This weakness was discovered by Jonathan Gardner at Cisco ASIG.
 
+* Skeleton Key: Any trusted key system can serve time
+   Date Resolved: Stable (4.2.8p6) 19 Jan 2016
+   References: Sec 2936 / CVE-2015-7974
+   Affects: All ntp-4 releases up to, but not including 4.2.8p6, and
+       4.3.0 up to, but not including 4.3.XX
+   CVSS: (AV:N/AC:H/Au:S/C:N/I:C/A:N) Base Score: 4.9
+   Summary: Symmetric key encryption uses a shared trusted key. The
+       reported title for this issue was "Missing key check allows
+       impersonation between authenticated peers" and the report claimed
+       "A key specified only for one server should only work to
+       authenticate that server, other trusted keys should be refused."
+       Except there has never been any correlation between this trusted
+       key and server v. clients machines and there has never been any
+       way to specify a key only for one server. We have treated this as
+       an enhancement request, and ntp-4.2.8p6 includes other checks and
+       tests to strengthen clients against attacks coming from broadcast
+       servers.
+   Mitigation:
+       Implement BCP-38.
+       If this scenario represents a real or a potential issue for you,
+           upgrade to 4.2.8p6, or later, from the NTP Project Download
+           Page or the NTP Public Services Project Download Page, and
+           use the new field in the ntp.keys file that specifies the list
+           of IPs that are allowed to serve time. Note that this alone
+           will not protect against time packets with forged source IP
+           addresses, however other changes in ntp-4.2.8p6 provide
+           significant mitigation against broadcast attacks. MITM attacks
+           are a different story.
+       If you are unable to upgrade:
+           Don't use broadcast mode if you cannot monitor your client
+               servers.
+           If you choose to use symmetric keys to authenticate time
+               packets in a hostile environment where ephemeral time
+               servers can be created, or if it is expected that malicious
+               time servers will participate in an NTP broadcast domain,
+               limit the number of participating systems that participate
+               in the shared-key group. 
+       Monitor your ntpd instances. 
+   Credit: This weakness was discovered by Matt Street of Cisco ASIG. 
+
 * Deja Vu: Replay attack on authenticated broadcast mode
    Date Resolved: Stable (4.2.8p6) 19 Jan 2016
    References: Sec 2935 / CVE-2015-7973
index d8b4dd2b54cf5dc8993a021e4ee426b7cc810e58..521ac146c7772e2d6343d8bd1e59d4806bae9cd2 100644 (file)
@@ -36,6 +36,7 @@ noinst_HEADERS =      \
        ntp_if.h        \
        ntp_intres.h    \
        ntp_io.h        \
+       ntp_keyacc.h    \
        ntp_libopts.h   \
        ntp_lineedit.h  \
        ntp_lists.h     \
index 5950f0035d6bd6650eecbc97bd5bd1bb5c548d07..d34d60a80b985ef24688b64876c0fd6418a148ac 100644 (file)
@@ -40,6 +40,8 @@
 
 #include "libntp.h"    /* This needs Something above for GETDTABLESIZE */
 
+#include "ntp_keyacc.h"
+
 /*
  * Define FNDELAY and FASYNC using O_NONBLOCK and O_ASYNC if we need
  * to (and can).  This is here initially for QNX, but may help for
@@ -83,7 +85,6 @@ typedef enum {
 extern int     qos;
 SOCKET         move_fd(SOCKET fd);
 isc_boolean_t  get_broadcastclient_flag(void);
-extern int     is_ip_address(const char *, u_short, sockaddr_u *);
 extern void    sau_from_netaddr(sockaddr_u *, const isc_netaddr_t *);
 extern void    add_nic_rule(nic_rule_match match_type,
                             const char *if_name, int prefixlen,
diff --git a/include/ntp_keyacc.h b/include/ntp_keyacc.h
new file mode 100644 (file)
index 0000000..730c310
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ *  ntp_keyacc.h - key access stuff
+ */
+#ifndef NTP_KEYACC_H
+#define NTP_KEYACC_H
+
+typedef struct keyaccess KeyAccT;
+struct keyaccess {
+       KeyAccT *       next;
+       sockaddr_u      addr;
+};
+
+#endif /* NTP_KEYACC_H */
index d735b41f4ba7e511ca673de60a5d2dd2151c1fe3..98ac69eb4697da37c1a6ecd93f1c5288a6209713 100644 (file)
@@ -16,6 +16,7 @@
 #include "ntp_malloc.h"
 #include "ntp_string.h"
 #include "ntp_syslog.h"
+#include "ntp_keyacc.h"
 
 #ifdef __GNUC__
 #define NTP_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))
@@ -69,6 +70,7 @@ extern        int     authdecrypt     (keyid_t, u_int32 *, size_t, size_t);
 extern size_t  authencrypt     (keyid_t, u_int32 *, size_t);
 extern int     authhavekey     (keyid_t);
 extern int     authistrusted   (keyid_t);
+extern int     authistrustedip (keyid_t, sockaddr_u *);
 extern int     authreadkeys    (const char *);
 extern void    authtrust       (keyid_t, u_long);
 extern int     authusekey      (keyid_t, int, const u_char *);
@@ -97,7 +99,7 @@ extern        int     ymd2yd          (int, int, int);
 /* a_md5encrypt.c */
 extern int     MD5authdecrypt  (int, const u_char *, u_int32 *, size_t, size_t);
 extern size_t  MD5authencrypt  (int, const u_char *, u_int32 *, size_t);
-extern void    MD5auth_setkey  (keyid_t, int, const u_char *, size_t);
+extern void    MD5auth_setkey  (keyid_t, int, const u_char *, size_t, KeyAccT *c);
 extern u_int32 addr2refid      (sockaddr_u *);
 
 /* emalloc.c */
@@ -141,6 +143,7 @@ extern      int     atouint         (const char *, u_long *);
 extern int     hextoint        (const char *, u_long *);
 extern const char *    humanlogtime    (void);
 extern const char *    humantime       (time_t);
+extern int     is_ip_address   (const char *, u_short, sockaddr_u *);
 extern char *  mfptoa          (u_int32, u_int32, short);
 extern char *  mfptoms         (u_int32, u_int32, short);
 extern const char * modetoa    (size_t);
index a947f30575e555580ac9e12c194ad32816383871..7ff31254720d376948a0bf6337a4d9ecc5e740db 100644 (file)
@@ -218,6 +218,7 @@ typedef uint16_t    associd_t; /* association ID */
 #define ASSOCID_MAX    USHRT_MAX
 typedef u_int32 keyid_t;       /* cryptographic key ID */
 #define KEYID_T_MAX    (0xffffffff)
+
 typedef u_int32 tstamp_t;      /* NTP seconds timestamp */
 
 /*
index 914badb5f64b8b35fefe1f76edf5e04088502ac2..a3b50e1298ba513b19d63bc34cda10a44e3170f9 100644 (file)
@@ -70,6 +70,7 @@ libntp_a_SRCS =                                               \
        humandate.c                                     \
        icom.c                                          \
        iosignal.c                                      \
+       is_ip_address.c                                 \
        lib_strbuf.c                                    \
        machines.c                                      \
        mktime.c                                        \
index 02725fb1ba533fc107c3f822af8e4c6f933e5b04..36fdd8b7c118ba2bdb63ec3f5b1c73dc8ad585ca 100644 (file)
@@ -15,6 +15,7 @@
 #include "ntp_string.h"
 #include "ntp_malloc.h"
 #include "ntp_stdlib.h"
+#include "ntp_keyacc.h"
 
 /*
  * Structure to store keys in in the hash table.
@@ -25,6 +26,7 @@ struct savekey {
        symkey *        hlink;          /* next in hash bucket */
        DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */
        u_char *        secret;         /* shared secret */
+       KeyAccT *       keyacclist;     /* Private key access list */
        u_long          lifetime;       /* remaining lifetime */
        keyid_t         keyid;          /* key identifier */
        u_short         type;           /* OpenSSL digest NID */
@@ -50,8 +52,8 @@ symkey_alloc *        authallocs;
 
 static u_short auth_log2(size_t);
 static void    auth_resize_hashtable(void);
-static void    allocsymkey(symkey **, keyid_t, u_short,
-                           u_short, u_long, u_short, u_char *);
+static void    allocsymkey(symkey **, keyid_t, u_short, u_short,
+                           u_long, u_short, u_char *, KeyAccT *);
 static void    freesymkey(symkey *, symkey **);
 #ifdef DEBUG
 static void    free_auth_mem(void);
@@ -97,6 +99,7 @@ u_char *cache_secret;         /* secret */
 u_short        cache_secretsize;       /* secret length */
 int    cache_type;             /* OpenSSL digest NID */
 u_short cache_flags;           /* flags that wave */
+KeyAccT *cache_keyacclist;     /* key access list */
 
 
 /*
@@ -142,6 +145,7 @@ free_auth_mem(void)
        key_hash = NULL;
        cache_keyid = 0;
        cache_flags = 0;
+       cache_keyacclist = NULL;
        for (alloc = authallocs; alloc != NULL; alloc = next_alloc) {
                next_alloc = alloc->link;
                free(alloc->mem);       
@@ -290,7 +294,8 @@ allocsymkey(
        u_short         type,
        u_long          lifetime,
        u_short         secretsize,
-       u_char *        secret
+       u_char *        secret,
+       KeyAccT *       ka
        )
 {
        symkey *        sk;
@@ -304,6 +309,7 @@ allocsymkey(
        sk->type = type;
        sk->secretsize = secretsize;
        sk->secret = secret;
+       sk->keyacclist = ka;
        sk->lifetime = lifetime;
        LINK_SLIST(*bucket, sk, hlink);
        LINK_TAIL_DLIST(key_listhead, sk, llink);
@@ -435,6 +441,7 @@ authhavekey(
        cache_flags = sk->flags;
        cache_secret = sk->secret;
        cache_secretsize = sk->secretsize;
+       cache_keyacclist = sk->keyacclist;
 
        return TRUE;
 }
@@ -474,6 +481,7 @@ authtrust(
                if (cache_keyid == id) {
                        cache_flags = 0;
                        cache_keyid = 0;
+                       cache_keyacclist = NULL;
                }
 
                /*
@@ -503,7 +511,7 @@ authtrust(
        } else {
                lifetime = 0;
        }
-       allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL);
+       allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
 }
 
 
@@ -534,6 +542,49 @@ authistrusted(
        return TRUE;
 }
 
+
+/*
+ * authistrustedip - determine if the IP is OK for the keyid
+ */
+ int
+ authistrustedip(
+       keyid_t         keyno,
+       sockaddr_u *    sau
+       )
+{
+       symkey *        sk;
+       symkey **       bucket;
+       KeyAccT *       kal;
+       KeyAccT *       k;
+
+       if (keyno == cache_keyid)
+               kal = cache_keyacclist;
+       else {
+               authkeyuncached++;
+               bucket = &key_hash[KEYHASH(keyno)];
+               for (sk = *bucket; sk != NULL; sk = sk->hlink) {
+                       if (keyno == sk->keyid)
+                               break;
+               }
+               if (NULL == sk || !(KEY_TRUSTED & sk->flags)) {
+                       INSIST(!"authistrustedip: keyid not found/trusted!");
+                       return FALSE;
+               }
+               kal = sk->keyacclist;
+       }
+
+       if (NULL == kal)
+               return TRUE;
+
+       for (k = kal; k; k = k->next) {
+               if (SOCK_EQ(&k->addr, sau))
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
+
 /* Note: There are two locations below where 'strncpy()' is used. While
  * this function is a hazard by itself, it's essential that it is used
  * here. Bug 1243 involved that the secret was filled with NUL bytes
@@ -550,7 +601,8 @@ MD5auth_setkey(
        keyid_t keyno,
        int     keytype,
        const u_char *key,
-       size_t len
+       size_t  len,
+       KeyAccT *ka
        )
 {
        symkey *        sk;
@@ -576,6 +628,7 @@ MD5auth_setkey(
                        sk->type = (u_short)keytype;
                        secretsize = len;
                        sk->secretsize = (u_short)secretsize;
+                       sk->keyacclist = ka;
 #ifndef DISABLE_BUG1243_FIX
                        memcpy(sk->secret, key, secretsize);
 #else
@@ -586,6 +639,7 @@ MD5auth_setkey(
                        if (cache_keyid == keyno) {
                                cache_flags = 0;
                                cache_keyid = 0;
+                               cache_keyacclist = NULL;
                        }
                        return;
                }
@@ -603,7 +657,7 @@ MD5auth_setkey(
        strncpy((char *)secret, (const char *)key, secretsize);
 #endif
        allocsymkey(bucket, keyno, 0, (u_short)keytype, 0,
-                   (u_short)secretsize, secret);
+                   (u_short)secretsize, secret, ka);
 #ifdef DEBUG
        if (debug >= 4) {
                size_t  j;
index 95a357a8c6651adcfa4b1f75e398f4a3d5a6cd17..1d4ee3059345f429decaa010532a71e008c77554 100644 (file)
@@ -5,10 +5,12 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include "ntpd.h"      /* Only for DPRINTF */
 #include "ntp_fp.h"
 #include "ntp.h"
 #include "ntp_syslog.h"
 #include "ntp_stdlib.h"
+#include "ntp_keyacc.h"
 
 #ifdef OPENSSL
 #include "openssl/objects.h"
@@ -85,6 +87,7 @@ static void log_maybe(u_int*, const char*, ...) NTP_PRINTF(2, 3);
 typedef struct keydata KeyDataT;
 struct keydata {
        KeyDataT *next;         /* queue/stack link             */
+       KeyAccT  *keyacclist;   /* key access list              */
        keyid_t   keyid;        /* stored key ID                */
        u_short   keytype;      /* stored key type              */
        u_short   seclen;       /* length of secret             */
@@ -228,6 +231,7 @@ authreadkeys(
                len = strlen(token);
                if (len <= 20) {        /* Bug 2537 */
                        next = emalloc(sizeof(KeyDataT) + len);
+                       next->keyacclist = NULL;
                        next->keyid   = keyno;
                        next->keytype = keytype;
                        next->seclen  = len;
@@ -257,11 +261,48 @@ authreadkeys(
                        }
                        len = jlim/2; /* hmmmm.... what about odd length?!? */
                        next = emalloc(sizeof(KeyDataT) + len);
+                       next->keyacclist = NULL;
                        next->keyid   = keyno;
                        next->keytype = keytype;
                        next->seclen  = len;
                        memcpy(next->secbuf, keystr, len);
                }
+
+               token = nexttok(&line);
+DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL"));
+               if (token != NULL) {    /* A comma-separated IP access list */
+                       char *tp = token;
+
+                       while (tp) {
+                               char *i;
+                               KeyAccT ka;
+
+                               i = strchr(tp, (int)',');
+                               if (i)
+                                       *i = '\0';
+DPRINTF(0, ("authreadkeys: access list:  <%s>\n", tp));
+
+                               if (is_ip_address(tp, AF_UNSPEC, &ka.addr)) {
+                                       KeyAccT *kap;
+
+                                       kap = emalloc(sizeof(KeyAccT));
+                                       memcpy(kap, &ka, sizeof ka);
+                                       kap->next = next->keyacclist;
+                                       next->keyacclist = kap;
+                               } else {
+                                       log_maybe(&nerr,
+                                                 "authreadkeys: invalid IP address <%s> for key %d",
+                                                 tp, keyno);
+                               }
+
+                               if (i) {
+                                       tp = i + 1;
+                               } else {
+                                       tp = 0;
+                               }
+                       }
+               }
+
                INSIST(NULL != next);
                next->next = list;
                list = next;
@@ -286,7 +327,7 @@ authreadkeys(
        while (NULL != (next = list)) {
                list = next->next;
                MD5auth_setkey(next->keyid, next->keytype,
-                              next->secbuf, next->seclen);
+                              next->secbuf, next->seclen, next->keyacclist);
                /* purge secrets from memory before free()ing it */
                memset(next, 0, sizeof(*next) + next->seclen);
                free(next);
@@ -297,6 +338,14 @@ authreadkeys(
        /* Mop up temporary storage before bailing out. */
        while (NULL != (next = list)) {
                list = next->next;
+
+               while (next->keyacclist) {
+                       KeyAccT *kap = next->keyacclist;
+
+                       next->keyacclist = kap->next;
+                       free(kap);
+               }
+
                /* purge secrets from memory before free()ing it */
                memset(next, 0, sizeof(*next) + next->seclen);
                free(next);
index 0ccf522b238ac4e4f4fdecab86539a48be8a5a0b..ff449d3df6fc9a0f504ed38839b390b7e143a5bd 100644 (file)
@@ -29,6 +29,6 @@ authusekey(
        if (0 == len)
                return 0;
 
-       MD5auth_setkey(keyno, keytype, str, len);
+       MD5auth_setkey(keyno, keytype, str, len, NULL);
        return 1;
 }
diff --git a/libntp/is_ip_address.c b/libntp/is_ip_address.c
new file mode 100644 (file)
index 0000000..1f21376
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * is_ip_address
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if 0
+#include <stdio.h>
+#include <signal.h>
+#ifdef HAVE_FNMATCH_H
+# include <fnmatch.h>
+# if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE)
+#  define FNM_CASEFOLD FNM_IGNORECASE
+# endif
+#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H       /* UXPV: SIOC* #defines (Frank Vance <fvance@waii.com>) */
+# include <sys/sockio.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+#endif
+
+#include "ntp_assert.h"
+#include "ntp_stdlib.h"
+#include "safecast.h"
+
+#if 0
+#include "ntp_machine.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "iosignal.h"
+#include "ntp_lists.h"
+#include "ntp_refclock.h"
+#include "ntp_worker.h"
+#include "ntp_request.h"
+#include "timevalops.h"
+#include "timespecops.h"
+#include "ntpd-opts.h"
+#endif
+
+/* Don't include ISC's version of IPv6 variables and structures */
+#define ISC_IPV6_H 1
+#include <isc/mem.h>
+#include <isc/interfaceiter.h>
+#include <isc/netaddr.h>
+#include <isc/result.h>
+#include <isc/sockaddr.h>
+
+
+/*
+ * Code to tell if we have an IP address
+ * If we have then return the sockaddr structure
+ * and set the return value
+ * see the bind9/getaddresses.c for details
+ */
+int
+is_ip_address(
+       const char *    host,
+       u_short         af,
+       sockaddr_u *    addr
+       )
+{
+       struct in_addr in4;
+       struct addrinfo hints;
+       struct addrinfo *result;
+       struct sockaddr_in6 *resaddr6;
+       char tmpbuf[128];
+       char *pch;
+
+       REQUIRE(host != NULL);
+       REQUIRE(addr != NULL);
+
+       ZERO_SOCK(addr);
+
+       /*
+        * Try IPv4, then IPv6.  In order to handle the extended format
+        * for IPv6 scoped addresses (address%scope_ID), we'll use a local
+        * working buffer of 128 bytes.  The length is an ad-hoc value, but
+        * should be enough for this purpose; the buffer can contain a string
+        * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
+        * addresses (up to 46 bytes), the delimiter character and the
+        * terminating NULL character.
+        */
+       if (AF_UNSPEC == af || AF_INET == af)
+               if (inet_pton(AF_INET, host, &in4) == 1) {
+                       AF(addr) = AF_INET;
+                       SET_ADDR4N(addr, in4.s_addr);
+
+                       return TRUE;
+               }
+
+       if (AF_UNSPEC == af || AF_INET6 == af)
+               if (sizeof(tmpbuf) > strlen(host)) {
+                       if ('[' == host[0]) {
+                               strlcpy(tmpbuf, &host[1], sizeof(tmpbuf));
+                               pch = strchr(tmpbuf, ']');
+                               if (pch != NULL)
+                                       *pch = '\0';
+                       } else {
+                               strlcpy(tmpbuf, host, sizeof(tmpbuf));
+                       }
+                       ZERO(hints);
+                       hints.ai_family = AF_INET6;
+                       hints.ai_flags |= AI_NUMERICHOST;
+                       if (getaddrinfo(tmpbuf, NULL, &hints, &result) == 0) {
+                               AF(addr) = AF_INET6;
+                               resaddr6 = UA_PTR(struct sockaddr_in6, result->ai_addr);
+                               SET_ADDR6N(addr, resaddr6->sin6_addr);
+                               SET_SCOPE(addr, resaddr6->sin6_scope_id);
+
+                               freeaddrinfo(result);
+                               return TRUE;
+                       }
+               }
+       /*
+        * If we got here it was not an IP address
+        */
+       return FALSE;
+}
index b755d97a47fefb481d613149fe8fdc68c5489cf9..406188969fcdcccc690eea36271eefb47f9946f3 100644 (file)
@@ -6,7 +6,7 @@
 #
 # EDIT THIS FILE WITH CAUTION  (invoke-ntp.keys.texi)
 #
-# It has been AutoGen-ed  January  7, 2016 at 11:30:52 PM by AutoGen 5.18.5
+# It has been AutoGen-ed  January 18, 2016 at 10:46:58 AM by AutoGen 5.18.5
 # From the definitions    ntp.keys.def
 # and the template file   agtexi-file.tpl
 @end ignore
@@ -37,7 +37,7 @@ as the configuration file.
 Key entries use a fixed format of the form
 
 @example
-@kbd{keyno} @kbd{type} @kbd{key}
+@kbd{keyno} @kbd{type} @kbd{key} @kbd{opt_IP_list}
 @end example
 
 where
@@ -47,7 +47,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 @kbd{key}
-is the key itself.
+is the key itself, and
+@kbd{opt_IP_list}
+is an optional comma-separated list of IPs
+that are allowed to serve time.
+If
+@kbd{opt_IP_list}
+is empty,
+any properly-authenticated server message will be
+accepted.
 
 The
 @kbd{key}
index bb0028bd15bc27912ab319ce30f437a94b677f79..58161b6b6cd062850b9a2f0fbf6126ad48e55139 100644 (file)
@@ -1,8 +1,8 @@
-.TH ntp.keys 5man "07 Jan 2016" "4.2.8p5" "File Formats"
+.TH ntp.keys 5man "18 Jan 2016" "4.2.8p5" "File Formats"
 .\"
 .\"  EDIT THIS FILE WITH CAUTION  (ntp.man)
 .\"
-.\"  It has been AutoGen-ed  January  7, 2016 at 11:30:41 PM by AutoGen 5.18.5
+.\"  It has been AutoGen-ed  January 18, 2016 at 10:47:00 AM by AutoGen 5.18.5
 .\"  From the definitions    ntp.keys.def
 .\"  and the template file   agman-file.tpl
 .Sh NAME
@@ -66,7 +66,7 @@ Key entries use a fixed format of the form
 .ne 2
 
 .in +4
-\f\*[I-Font]keyno\f[] \f\*[I-Font]type\f[] \f\*[I-Font]key\f[]
+\f\*[I-Font]keyno\f[] \f\*[I-Font]type\f[] \f\*[I-Font]key\f[] \f\*[I-Font]opt_IP_list\f[]
 .in -4
 .sp \n(Ppu
 .ne 2
@@ -78,7 +78,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 \f\*[I-Font]key\f[]
-is the key itself.
+is the key itself, and
+\f\*[I-Font]opt_IP_list\f[]
+is an optional comma-separated list of IPs
+that are allowed to serve time.
+If
+\f\*[I-Font]opt_IP_list\f[]
+is empty,
+any properly-authenticated server message will be
+accepted.
 .sp \n(Ppu
 .ne 2
 
@@ -160,7 +168,7 @@ the default name of the configuration file
 .SH "AUTHORS"
 The University of Delaware and Network Time Foundation
 .SH "COPYRIGHT"
-Copyright (C) 1992-2015 The University of Delaware and Network Time Foundation all rights reserved.
+Copyright (C) 1992-2016 The University of Delaware and Network Time Foundation all rights reserved.
 This program is released under the terms of the NTP license, <http://ntp.org/license>.
 .SH "BUGS"
 Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org
index 9524989cb1ad7f4a5c8b14380f2b3347916f141e..11e2fce920529470ad905e7b40557c005f9a9f23 100644 (file)
@@ -1,9 +1,9 @@
-.Dd January 7 2016
+.Dd January 18 2016
 .Dt NTP_KEYS 5mdoc File Formats
-.Os SunOS 5.10
+.Os Linux 3.2.0-4-686-pae
 .\"  EDIT THIS FILE WITH CAUTION  (ntp.mdoc)
 .\"
-.\"  It has been AutoGen-ed  January  7, 2016 at 11:31:00 PM by AutoGen 5.18.5
+.\"  It has been AutoGen-ed  January 18, 2016 at 10:46:56 AM by AutoGen 5.18.5
 .\"  From the definitions    ntp.keys.def
 .\"  and the template file   agmdoc-file.tpl
 .Sh NAME
@@ -44,7 +44,7 @@ The key file uses the same comment conventions
 as the configuration file.
 Key entries use a fixed format of the form
 .Pp
-.D1 Ar keyno type key
+.D1 Ar keyno type key opt_IP_list
 .Pp
 where
 .Ar keyno
@@ -53,7 +53,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 .Ar key
-is the key itself.
+is the key itself, and
+.Ar opt_IP_list
+is an optional comma\-separated list of IPs
+that are allowed to serve time.
+If
+.Ar opt_IP_list
+is empty,
+any properly\-authenticated server message will be
+accepted.
 .Pp
 The
 .Ar key
@@ -147,7 +155,7 @@ it to autogen\-users@lists.sourceforge.net.  Thank you.
 .Sh "AUTHORS"
 The University of Delaware and Network Time Foundation
 .Sh "COPYRIGHT"
-Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved.
+Copyright (C) 1992\-2016 The University of Delaware and Network Time Foundation all rights reserved.
 This program is released under the terms of the NTP license, <http://ntp.org/license>.
 .Sh "BUGS"
 Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org
index dcb3d55ead9acf9622c93b4772a1e44743f30e8e..efe774c2e541ae84bdeb957b8abaf7ef35f8e0f5 100644 (file)
@@ -43,7 +43,7 @@ The key file uses the same comment conventions
 as the configuration file.
 Key entries use a fixed format of the form
 .Pp
-.D1 Ar keyno type key
+.D1 Ar keyno type key opt_IP_list
 .Pp
 where
 .Ar keyno
@@ -52,7 +52,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 .Ar key
-is the key itself.
+is the key itself, and
+.Ar opt_IP_list
+is an optional comma-separated list of IPs
+that are allowed to serve time.
+If
+.Ar opt_IP_list
+is empty,
+any properly-authenticated server message will be
+accepted.
 .Pp
 The
 .Ar key
index 738f9e03e73f44389cf4ddc8efe7e39f6a38be12..3ecd36712e5863a0377064b9e53bed3387c5d6c4 100644 (file)
@@ -3,7 +3,7 @@
 <title>NTP Symmetric Key</title>
 <meta http-equiv="Content-Type" content="text/html">
 <meta name="description" content="NTP Symmetric Key">
-<meta name="generator" content="makeinfo 4.7">
+<meta name="generator" content="makeinfo 4.13">
 <link title="Top" rel="top" href="#Top">
 <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
 <meta http-equiv="Content-Style-Type" content="text/css">
   pre.smallformat  { font-family:inherit; font-size:smaller }
   pre.smallexample { font-size:smaller }
   pre.smalllisp    { font-size:smaller }
-  span.sc { font-variant:small-caps }
-  span.roman { font-family: serif; font-weight: normal; } 
+  span.sc    { font-variant:small-caps }
+  span.roman { font-family:serif; font-weight:normal; } 
+  span.sansserif { font-family:sans-serif; font-weight:normal; } 
 --></style>
 </head>
 <body>
 <h1 class="settitle">NTP Symmetric Key</h1>
 <div class="node">
+<a name="Top"></a>
 <p><hr>
-<a name="Top"></a>Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-Description">ntp.keys Description</a>,
+Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-Description">ntp.keys Description</a>,
 Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
 Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
-<br>
+
 </div>
 
 <h2 class="unnumbered">NTP's Symmetric Key File User Manual</h2>
@@ -48,10 +50,12 @@ Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
 </ul>
 
 <div class="node">
+<a name="ntp.keys-Description"></a>
+<a name="ntp_002ekeys-Description"></a>
 <p><hr>
-<a name="ntp_002ekeys-Description"></a>Previous:&nbsp;<a rel="previous" accesskey="p" href="#Top">Top</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#Top">Top</a>,
 Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
-<br>
+
 </div>
 
 <!-- node-name,  next,  previous,  up -->
@@ -61,9 +65,11 @@ Up:&nbsp;<a rel="up" accesskey="u" href="#Top">Top</a>
 be specified in a configuration file, by default <code>/etc/ntp.keys</code>.
 
 <div class="node">
-<p><hr>
+<a name="ntp.keys-Notes"></a>
 <a name="ntp_002ekeys-Notes"></a>
-<br>
+<p><hr>
+
+
 </div>
 
 <h3 class="section">Notes about ntp.keys</h3>
@@ -93,7 +99,7 @@ may be arbitrarily set in the keys file.
 as the configuration file. 
 Key entries use a fixed format of the form
 
-<pre class="example">     <kbd>keyno</kbd> <kbd>type</kbd> <kbd>key</kbd>
+<pre class="example">     <kbd>keyno</kbd> <kbd>type</kbd> <kbd>key</kbd> <kbd>opt_IP_list</kbd>
 </pre>
   <p>where
 <kbd>keyno</kbd>
@@ -102,7 +108,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 <kbd>key</kbd>
-is the key itself.
+is the key itself, and
+<kbd>opt_IP_list</kbd>
+is an optional comma-separated list of IPs
+that are allowed to serve time. 
+If
+<kbd>opt_IP_list</kbd>
+is empty,
+any properly-authenticated server message will be
+accepted.
 
   <p>The
 <kbd>key</kbd>
@@ -159,23 +173,27 @@ This software is released under the NTP license, &lt;http://ntp.org/license&gt;.
 </ul>
 
 <div class="node">
+<a name="ntp.keys-Files"></a>
+<a name="ntp_002ekeys-Files"></a>
 <p><hr>
-<a name="ntp_002ekeys-Files"></a>Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-See-Also">ntp.keys See Also</a>,
+Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-See-Also">ntp.keys See Also</a>,
 Up:&nbsp;<a rel="up" accesskey="u" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>
-<br>
+
 </div>
 
 <h4 class="subsection">ntp.keys Files</h4>
 
      <dl>
-<dt><span class="file">/etc/ntp.keys</span><dd>the default name of the configuration file
+<dt><samp><span class="file">/etc/ntp.keys</span></samp><dd>the default name of the configuration file
 </dl>
 <div class="node">
+<a name="ntp.keys-See-Also"></a>
+<a name="ntp_002ekeys-See-Also"></a>
 <p><hr>
-<a name="ntp_002ekeys-See-Also"></a>Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>,
+Next:&nbsp;<a rel="next" accesskey="n" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>,
 Previous:&nbsp;<a rel="previous" accesskey="p" href="#ntp_002ekeys-Files">ntp.keys Files</a>,
 Up:&nbsp;<a rel="up" accesskey="u" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>
-<br>
+
 </div>
 
 <h4 class="subsection">ntp.keys See Also</h4>
@@ -186,10 +204,12 @@ Up:&nbsp;<a rel="up" accesskey="u" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>
 <code>ntpdc(1ntpdcmdoc)</code>,
 <code>sntp(1sntpmdoc)</code>
 <div class="node">
+<a name="ntp.keys-Notes"></a>
+<a name="ntp_002ekeys-Notes"></a>
 <p><hr>
-<a name="ntp_002ekeys-Notes"></a>Previous:&nbsp;<a rel="previous" accesskey="p" href="#ntp_002ekeys-See-Also">ntp.keys See Also</a>,
+Previous:&nbsp;<a rel="previous" accesskey="p" href="#ntp_002ekeys-See-Also">ntp.keys See Also</a>,
 Up:&nbsp;<a rel="up" accesskey="u" href="#ntp_002ekeys-Notes">ntp.keys Notes</a>
-<br>
+
 </div>
 
 <h4 class="subsection">ntp.keys Notes</h4>
index 78d5f091d32566d4a51971f0cf12e86ddb0bde78..95d29068870482fe8c9724fba8d602125156717e 100644 (file)
@@ -1,8 +1,8 @@
-.TH ntp.keys 5 "07 Jan 2016" "4.2.8p5" "File Formats"
+.TH ntp.keys 5 "18 Jan 2016" "4.2.8p5" "File Formats"
 .\"
 .\"  EDIT THIS FILE WITH CAUTION  (ntp.man)
 .\"
-.\"  It has been AutoGen-ed  January  7, 2016 at 11:30:41 PM by AutoGen 5.18.5
+.\"  It has been AutoGen-ed  January 18, 2016 at 10:47:00 AM by AutoGen 5.18.5
 .\"  From the definitions    ntp.keys.def
 .\"  and the template file   agman-file.tpl
 .Sh NAME
@@ -66,7 +66,7 @@ Key entries use a fixed format of the form
 .ne 2
 
 .in +4
-\f\*[I-Font]keyno\f[] \f\*[I-Font]type\f[] \f\*[I-Font]key\f[]
+\f\*[I-Font]keyno\f[] \f\*[I-Font]type\f[] \f\*[I-Font]key\f[] \f\*[I-Font]opt_IP_list\f[]
 .in -4
 .sp \n(Ppu
 .ne 2
@@ -78,7 +78,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 \f\*[I-Font]key\f[]
-is the key itself.
+is the key itself, and
+\f\*[I-Font]opt_IP_list\f[]
+is an optional comma-separated list of IPs
+that are allowed to serve time.
+If
+\f\*[I-Font]opt_IP_list\f[]
+is empty,
+any properly-authenticated server message will be
+accepted.
 .sp \n(Ppu
 .ne 2
 
@@ -160,7 +168,7 @@ the default name of the configuration file
 .SH "AUTHORS"
 The University of Delaware and Network Time Foundation
 .SH "COPYRIGHT"
-Copyright (C) 1992-2015 The University of Delaware and Network Time Foundation all rights reserved.
+Copyright (C) 1992-2016 The University of Delaware and Network Time Foundation all rights reserved.
 This program is released under the terms of the NTP license, <http://ntp.org/license>.
 .SH "BUGS"
 Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org
index 40c821e517d7353cce2597a663804386d6eb44da..7a89ee435f45573c87a188ad2389d0c71ae62ae7 100644 (file)
@@ -1,9 +1,9 @@
-.Dd January 7 2016
+.Dd January 18 2016
 .Dt NTP_KEYS 5 File Formats
-.Os SunOS 5.10
+.Os Linux 3.2.0-4-686-pae
 .\"  EDIT THIS FILE WITH CAUTION  (ntp.mdoc)
 .\"
-.\"  It has been AutoGen-ed  January  7, 2016 at 11:31:00 PM by AutoGen 5.18.5
+.\"  It has been AutoGen-ed  January 18, 2016 at 10:46:56 AM by AutoGen 5.18.5
 .\"  From the definitions    ntp.keys.def
 .\"  and the template file   agmdoc-file.tpl
 .Sh NAME
@@ -44,7 +44,7 @@ The key file uses the same comment conventions
 as the configuration file.
 Key entries use a fixed format of the form
 .Pp
-.D1 Ar keyno type key
+.D1 Ar keyno type key opt_IP_list
 .Pp
 where
 .Ar keyno
@@ -53,7 +53,15 @@ is a positive integer (between 1 and 65534),
 is the message digest algorithm,
 and
 .Ar key
-is the key itself.
+is the key itself, and
+.Ar opt_IP_list
+is an optional comma\-separated list of IPs
+that are allowed to serve time.
+If
+.Ar opt_IP_list
+is empty,
+any properly\-authenticated server message will be
+accepted.
 .Pp
 The
 .Ar key
@@ -147,7 +155,7 @@ it to autogen\-users@lists.sourceforge.net.  Thank you.
 .Sh "AUTHORS"
 The University of Delaware and Network Time Foundation
 .Sh "COPYRIGHT"
-Copyright (C) 1992\-2015 The University of Delaware and Network Time Foundation all rights reserved.
+Copyright (C) 1992\-2016 The University of Delaware and Network Time Foundation all rights reserved.
 This program is released under the terms of the NTP license, <http://ntp.org/license>.
 .Sh "BUGS"
 Please send bug reports to: http://bugs.ntp.org, bugs@ntp.org
index 7dd39a7c93a81a355f8e8275e0de06dd4590fed6..86541bdc16c4abc42e73fff8e460b7762f37819c 100644 (file)
@@ -269,7 +269,7 @@ session_key(
        memcpy(&keyid, dgst, 4);
        keyid = ntohl(keyid);
        if (lifetime != 0) {
-               MD5auth_setkey(keyno, crypto_nid, dgst, len);
+               MD5auth_setkey(keyno, crypto_nid, dgst, len, NULL);
                authtrust(keyno, lifetime);
        }
        DPRINTF(2, ("session_key: %s > %s %08x %08x hash %08x life %lu\n",
index 4b6f4f85be1678e07160a2e460c009af93ad05aa..ee52b1a5c38979b27eccd48c19b90ac6f224bbfb 100644 (file)
@@ -724,78 +724,6 @@ addr_samesubnet(
 }
 
 
-/*
- * Code to tell if we have an IP address
- * If we have then return the sockaddr structure
- * and set the return value
- * see the bind9/getaddresses.c for details
- */
-int
-is_ip_address(
-       const char *    host,
-       u_short         af,
-       sockaddr_u *    addr
-       )
-{
-       struct in_addr in4;
-       struct addrinfo hints;
-       struct addrinfo *result;
-       struct sockaddr_in6 *resaddr6;
-       char tmpbuf[128];
-       char *pch;
-
-       REQUIRE(host != NULL);
-       REQUIRE(addr != NULL);
-
-       ZERO_SOCK(addr);
-
-       /*
-        * Try IPv4, then IPv6.  In order to handle the extended format
-        * for IPv6 scoped addresses (address%scope_ID), we'll use a local
-        * working buffer of 128 bytes.  The length is an ad-hoc value, but
-        * should be enough for this purpose; the buffer can contain a string
-        * of at least 80 bytes for scope_ID in addition to any IPv6 numeric
-        * addresses (up to 46 bytes), the delimiter character and the
-        * terminating NULL character.
-        */
-       if (AF_UNSPEC == af || AF_INET == af)
-               if (inet_pton(AF_INET, host, &in4) == 1) {
-                       AF(addr) = AF_INET;
-                       SET_ADDR4N(addr, in4.s_addr);
-
-                       return TRUE;
-               }
-
-       if (AF_UNSPEC == af || AF_INET6 == af)
-               if (sizeof(tmpbuf) > strlen(host)) {
-                       if ('[' == host[0]) {
-                               strlcpy(tmpbuf, &host[1], sizeof(tmpbuf));
-                               pch = strchr(tmpbuf, ']');
-                               if (pch != NULL)
-                                       *pch = '\0';
-                       } else {
-                               strlcpy(tmpbuf, host, sizeof(tmpbuf));
-                       }
-                       ZERO(hints);
-                       hints.ai_family = AF_INET6;
-                       hints.ai_flags |= AI_NUMERICHOST;
-                       if (getaddrinfo(tmpbuf, NULL, &hints, &result) == 0) {
-                               AF(addr) = AF_INET6;
-                               resaddr6 = UA_PTR(struct sockaddr_in6, result->ai_addr);
-                               SET_ADDR6N(addr, resaddr6->sin6_addr);
-                               SET_SCOPE(addr, resaddr6->sin6_scope_id);
-
-                               freeaddrinfo(result);
-                               return TRUE;
-                       }
-               }
-       /*
-        * If we got here it was not an IP address
-        */
-       return FALSE;
-}
-
-
 /*
  * interface list enumerator - visitor pattern
  */
index 03c19144d987f6b2a1db6c2fcc5b7a873a928f2a..ad454099f8b924a16ca84cf3fd162a1d8ab58e61 100644 (file)
@@ -1597,6 +1597,40 @@ receive(
                return;         /* Drop any other kiss code packets */
        }
 
+       /*
+        * If:
+        *      - this is a *cast (uni-, broad-, or m-) server packet
+        *      - and it's authenticated
+        * then see if the sender's IP is trusted for this keyid.
+        * If it is, great - nothing special to do here.
+        * Otherwise, we should report and bail.
+        */
+
+       switch (hismode) {
+           case MODE_SERVER:           /* server mode */
+           case MODE_BROADCAST:        /* broadcast mode */
+           case MODE_ACTIVE:           /* symmetric active mode */
+               if (   is_authentic == AUTH_OK
+                   && !authistrustedip(skeyid, &peer->srcadr)) {
+                       report_event(PEVNT_AUTH, peer, "authIP");
+                       peer->badauth++;
+                       return;
+               }
+               break;
+
+           case MODE_UNSPEC:           /* unspecified (old version) */
+           case MODE_PASSIVE:          /* symmetric passive mode */
+           case MODE_CLIENT:           /* client mode */
+#if 0          /* At this point, MODE_CONTROL is overloaded by MODE_BCLIENT */
+           case MODE_CONTROL:          /* control mode */
+#endif
+           case MODE_PRIVATE:          /* private mode */
+           case MODE_BCLIENT:          /* broadcast client mode */
+               break;
+           default:
+               break;
+       }
+
 
        /*
         * That was hard and I am sweaty, but the packet is squeaky
index bea3fe539a316a5cdeea989767e0e699073b189a..fd11ef623de2182ac7cc70548d8e830605148a46 100644 (file)
@@ -72,7 +72,7 @@ AddTrustedKey(keyid_t keyno)
         * We need to add a MD5-key in addition to setting the
         * trust, because authhavekey() requires type != 0.
         */
-       MD5auth_setkey(keyno, KEYTYPE, NULL, 0);
+       MD5auth_setkey(keyno, KEYTYPE, NULL, 0, NULL);
 
        authtrust(keyno, TRUE);