]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Cleanup, fix ntp_intres when requestkey type means digests
authorDave Hart <hart@ntp.org>
Thu, 12 Nov 2009 00:51:35 +0000 (00:51 +0000)
committerDave Hart <hart@ntp.org>
Thu, 12 Nov 2009 00:51:35 +0000 (00:51 +0000)
  larger than 16 octets.
Add /lib to OpenSSL library search path, OpenSolaris has it there.

bk: 4afb5c17_FCklSAA8sArpvcR3zWSIA

configure.ac
include/ntp_request.h
include/ntpd.h
libntp/authreadkeys.c
libntp/hextoint.c
libntp/ssl_init.c
ntpd/ntp_config.c
ntpd/ntp_intres.c
ntpd/ntp_request.c
ntpdc/layout.std
ntpdc/ntpdc.c

index c9eb8972af814b2b8b77bca282b219beb1f5efc1..eafde1240cb079fb2f6e2cbdc4e87746c6cf2a52 100644 (file)
@@ -3249,7 +3249,7 @@ esac])
 case "$ans" in
  no) ;;
  yes) # Look in:
-    ans="/usr/lib /usr/lib/openssl /usr/sfw/lib /usr/local/lib /usr/local/ssl/lib"
+    ans="/usr/lib /usr/lib/openssl /usr/sfw/lib /usr/local/lib /usr/local/ssl/lib /lib"
     ;;
  *) # Look where they said
     ;;
@@ -3346,7 +3346,6 @@ case "$ntp_openssl" in
     esac
     AC_SUBST(LCRYPTO, [-lcrypto])
     AC_DEFINE(OPENSSL, , [Use OpenSSL?])
-    AC_CHECK_FUNCS([EVP_md2 EVP_mdc2])
 esac
 
 #
index 1d4e90ba4dfd205938f43ffd73ff69962e8f3f4a..8b6dbf3b63b93461b7e53174cb54d065d338395e 100644 (file)
@@ -136,7 +136,7 @@ struct req_pkt {
                                        /* struct conf_peer must fit */
        l_fp tstamp;                    /* time stamp, for authentication */
        keyid_t keyid;                  /* (optional) encryption key */
-       char mac[MAX_MD5_LEN-sizeof(keyid_t)]; /* (optional) auth code */
+       char mac[MAX_MAC_LEN-sizeof(keyid_t)]; /* (optional) auth code */
 };
 
 /*
@@ -146,13 +146,16 @@ struct req_pkt {
 struct req_pkt_tail {
        l_fp tstamp;                    /* time stamp, for authentication */
        keyid_t keyid;                  /* (optional) encryption key */
-       char mac[MAX_MD5_LEN-sizeof(keyid_t)]; /* (optional) auth code */
+       char mac[MAX_MAC_LEN-sizeof(keyid_t)]; /* (optional) auth code */
 };
 
 /* MODE_PRIVATE request packet header length before optional items. */
 #define        REQ_LEN_HDR     (offsetof(struct req_pkt, data))
 /* MODE_PRIVATE request packet fixed length without MAC. */
 #define        REQ_LEN_NOMAC   (offsetof(struct req_pkt, keyid))
+/* MODE_PRIVATE req_pkt_tail minimum size (16 octet digest) */
+#define REQ_TAIL_MIN   \
+       (sizeof(struct req_pkt_tail) - (MAX_MAC_LEN - MAX_MD5_LEN))
 
 /*
  * A MODE_PRIVATE response packet.  The length here is variable, this
index 86e0d844337d5a110cfb7ec49659cfad0f49f45c..bdd574dd57373905581bb2ac82f07bb19fd06947 100644 (file)
@@ -302,6 +302,8 @@ extern u_long       numasyncmsgs;           /* number of async messages we've sent */
 
 /* ntp_intres.c */
 extern keyid_t req_keyid;              /* request keyid */
+extern int     req_keytype;            /* OpenSSL NID such as NID_md5 */
+extern size_t  req_hashlen;            /* digest size for req_keytype */
 extern char *  req_file;               /* name of the file with configuration info */
 #ifdef SYS_WINNT
 extern HANDLE ResolverEventHandle;
index a64d4ef7ebb9855969b582d880b6075489c90e87..91383d715b67e1f10da92a96fd38b17d68ca89da 100644 (file)
@@ -178,23 +178,25 @@ authreadkeys(
                        MD5auth_setkey(keyno, keytype, (u_char *)token, len);
                } else {
                        char    hex[] = "0123456789abcdef";
-                       int     temp;
+                       u_char  temp;
                        char    *ptr;
+                       int     jlim;
 
-                       for (j = 0; j < len; j++) {
+                       jlim = min(len, 2 * sizeof(keystr));
+                       for (j = 0; j < jlim; j++) {
                                ptr = strchr(hex, tolower(token[j]));
                                if (ptr == NULL) {
                                        msyslog(LOG_ERR,
                                            "authreadkeys: invalid hex digit for key %d", keyno);
                                        continue;
                                }
-                               temp = ptr - hex;
+                               temp = (u_char)(ptr - hex);
                                if (j & 1)
                                        keystr[j / 2] |= temp;
                                else
                                        keystr[j / 2] = temp << 4;
                        }
-                       MD5auth_setkey(keyno, keytype, keystr, len / 2);
+                       MD5auth_setkey(keyno, keytype, keystr, jlim / 2);
                }
        }
        fclose(fp);
index 0d774eb4ee3f56d24c601d7140257f7dd233e0c0..a2e8c043fb35027b4d75505863ee883d53638b76 100644 (file)
@@ -9,7 +9,7 @@
 int
 hextoint(
        const char *str,
-       u_long *ival
+       u_long *pu
        )
 {
        register u_long u;
@@ -18,22 +18,24 @@ hextoint(
        cp = str;
 
        if (*cp == '\0')
-           return 0;
+               return 0;
 
        u = 0;
        while (*cp != '\0') {
-               if (!isxdigit((int)*cp))
-                   return 0;
-               if (u >= 0x10000000)
-                   return 0;   /* overflow */
+               if (!isxdigit(*cp))
+                       return 0;
+               if (u & 0xF0000000)
+                       return 0;       /* overflow */
                u <<= 4;
-               if (*cp <= '9')         /* very ascii dependent */
-                   u += *cp++ - '0';
-               else if (*cp >= 'a')
-                   u += *cp++ - 'a' + 10;
+               if ('0' <= *cp && *cp <= '9')
+                       u += *cp++ - '0';
+               else if ('a' <= *cp && *cp <= 'f')
+                       u += *cp++ - 'a' + 10;
+               else if ('A' <= *cp && *cp <= 'F')
+                       u += *cp++ - 'A' + 10;
                else
-                   u += *cp++ - 'A' + 10;
+                       return 0;
        }
-       *ival = u;
+       *pu = u;
        return 1;
 }
index 59ef8ff1a9d965a9338478ea1731e84136159e3f..c7bf7e63f8b8b0c282a4aa675304fcc819ae63aa 100644 (file)
@@ -7,6 +7,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <ctype.h>
 #include <ntp.h>
 #include <ntp_debug.h>
 #include <lib_strbuf.h>
@@ -56,14 +57,14 @@ ssl_check_version(void)
  */
 int
 keytype_from_text(
-       const char *keytype_name,
+       const char *text,
        size_t *pdigest_len
        )
 {
        int             key_type;
        u_int           digest_len;
 #ifdef OPENSSL
-       char            digest[EVP_MAX_MD_SIZE];
+       u_char          digest[EVP_MAX_MD_SIZE];
        char *          upcased;
        char *          pch;
        EVP_MD_CTX      ctx;
@@ -76,7 +77,7 @@ keytype_from_text(
         */
        INIT_SSL();
        LIB_GETBUF(upcased);
-       strncpy(upcased, keytype_name, LIB_BUFLENGTH);
+       strncpy(upcased, text, LIB_BUFLENGTH);
        for (pch = upcased; '\0' != *pch; pch++)
                *pch = (char)toupper(*pch);
        key_type = OBJ_sn2nid(upcased);
@@ -84,7 +85,7 @@ keytype_from_text(
        key_type = 0;
 #endif
 
-       if (!key_type && 'm' == tolower(keytype_name[0]))
+       if (!key_type && 'm' == tolower(text[0]))
                key_type = NID_md5;
 
        if (!key_type)
@@ -94,6 +95,17 @@ keytype_from_text(
 #ifdef OPENSSL
                EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
                EVP_DigestFinal(&ctx, digest, &digest_len);
+               if (digest_len + sizeof(keyid_t) > MAX_MAC_LEN) {
+                       fprintf(stderr,
+                               "key type %s %u octet digests are too big, max %u\n",
+                               keytype_name(key_type), digest_len,
+                               MAX_MAC_LEN - sizeof(keyid_t));
+                       msyslog(LOG_ERR,
+                               "key type %s %u octet digests are too big, max %u",
+                               keytype_name(key_type), digest_len,
+                               MAX_MAC_LEN - sizeof(keyid_t));
+                       return 0;
+               }
 #else
                digest_len = 16;
 #endif
@@ -123,7 +135,7 @@ keytype_name(
        if (NULL == name)
                name = unknown_type;
 #else  /* !OPENSSL follows */
-       if (nid_MD5 == nid)
+       if (NID_md5 == nid)
                name = "MD5";
        else
                name = unknown_type;
index 88655b799dd99dd1f202a69cb96692749e0c25f5..bcbf6c500302360315ed4ba10b56213f41454415 100644 (file)
@@ -1707,11 +1707,15 @@ config_auth(
        struct config_tree *ptree
        )
 {
+       extern int      cache_type;     /* authkeys.c */
 #ifdef OPENSSL
+       u_char          digest[EVP_MAX_MD_SIZE];
+       u_int           digest_len;
+       EVP_MD_CTX      ctx;
        struct attr_val *my_val;
-       int item;
+       int             item;
 #endif
-       int *key_val;
+       int *           key_val;
 
        /* Crypto Command */
 #ifdef OPENSSL
@@ -1811,12 +1815,23 @@ config_auth(
                req_keyid = info_auth_keyid;
 
        /* if doesn't exist, make up one at random */
-       if (!authhavekey(req_keyid)) {
+       if (authhavekey(req_keyid)) {
+               req_keytype = cache_type;
+#ifndef OPENSSL
+               req_hashlen = 16;
+#else  /* OPENSSL follows */
+               EVP_DigestInit(&ctx, EVP_get_digestbynid(req_keytype));
+               EVP_DigestFinal(&ctx, digest, &digest_len);
+               req_hashlen = digest_len;
+#endif
+       } else {
                int     rankey;
 
                rankey = ntp_random();
-               MD5auth_setkey(req_keyid, NID_md5, (u_char *)&rankey,
-                   sizeof(rankey));
+               req_keytype = NID_md5;
+               req_hashlen = 16;
+               MD5auth_setkey(req_keyid, req_keytype,
+                   (u_char *)&rankey, sizeof(rankey));
                authtrust(req_keyid, 1);
        }
 
@@ -3362,7 +3377,7 @@ config_peers(
                status = get_multiple_netnums(curr_peer->addr->address,
                    &peeraddr, &res, 0, t_UNK);
 
-#if 0 /* Hack for debugging Deferred DNS */
+#ifdef FORCE_DEFER_DNS /* Hack for debugging Deferred DNS */
                if (status == 1) {
                        /* Deferring everything breaks refclocks. */
                        memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
index 44659a616b7ce7f5e9a44ff37055778923e050b2..85f93e3c76168acb272aa91d8d91890720ec9c31 100644 (file)
@@ -137,6 +137,8 @@ static      SOCKET sockfd = INVALID_SOCKET; /* NT uses SOCKET */
 /* stuff to be filled in by caller */
 
 keyid_t req_keyid;     /* request keyid */
+int    req_keytype;    /* OpenSSL NID such as NID_md5 */
+size_t req_hashlen;    /* digest size for req_keytype */
 char *req_file;                /* name of the file with configuration info */
 
 /* end stuff to be filled in */
@@ -496,7 +498,6 @@ findhostaddr(
        }
 
        if (entry->ce_name) {
-               if (0) msyslog(LOG_INFO, "findhostaddr: Trying %s", entry->ce_name);
                DPRINTF(2, ("findhostaddr: Resolving <%s>\n",
                        entry->ce_name));
 
@@ -696,15 +697,21 @@ request(
        struct conf_peer *conf
        )
 {
-       fd_set fdset;
        struct sock_timeval tvout;
        struct req_pkt reqpkt;
-       l_fp ts;
+       size_t  req_len;
+       size_t  total_len;      /* req_len plus keyid & digest */
+       fd_set  fdset;
+       l_fp    ts;
+       char *  pch;
+       char *  pchEnd;
+       l_fp *  pts;
+       keyid_t *pkeyid;
        int n;
 #ifdef SYS_WINNT
-       HANDLE hReadWriteEvent = NULL;
-       BOOL ret;
-       DWORD NumberOfBytesWritten, NumberOfBytesRead, dwWait;
+       HANDLE  hReadWriteEvent = NULL;
+       BOOL    ret;
+       DWORD   NumberOfBytesWritten, NumberOfBytesRead, dwWait;
        OVERLAPPED overlap;
 #endif /* SYS_WINNT */
 
@@ -735,34 +742,66 @@ request(
        /*
         * Make up a request packet with the configuration info
         */
-       memset((char *)&reqpkt, 0, sizeof(reqpkt));
+       memset(&reqpkt, 0, sizeof(reqpkt));
 
        reqpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
        reqpkt.auth_seq = AUTH_SEQ(1, 0);       /* authenticated, no seq */
        reqpkt.implementation = IMPL_XNTPD;     /* local implementation */
        reqpkt.request = REQ_CONFIG;            /* configure a new peer */
        reqpkt.err_nitems = ERR_NITEMS(0, 1);   /* one item */
-       reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct conf_peer));
+       reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(*conf));
        /* Make sure mbz_itemsize <= sizeof reqpkt.data */
-       if (sizeof(struct conf_peer) > sizeof (reqpkt.data)) {
-               msyslog(LOG_ERR, "Bletch: conf_peer is too big for reqpkt.data!");
+       if (sizeof(*conf) > sizeof(reqpkt.data)) {
+               msyslog(LOG_ERR,
+                       "Bletch: conf_peer is too big for reqpkt.data!");
                resolver_exit(1);
        }
-       memmove(reqpkt.data, (char *)conf, sizeof(struct conf_peer));
-       reqpkt.keyid = htonl(req_keyid);
+       memcpy(reqpkt.data, conf, sizeof(*conf));
+
+       if (sys_authenticate && req_hashlen > 16) {
+               pch = reqpkt.data; 
+               /* 32-bit alignment */
+               pch += (sizeof(*conf) + 3) & ~3;
+               pts = (void *)pch;
+               pkeyid = (void *)(pts + 1);
+               pchEnd = (void *)pkeyid;
+               req_len = pchEnd - (char *)&reqpkt;
+               pchEnd = (void *)(pkeyid + 1);
+               pchEnd += req_hashlen;
+               total_len = pchEnd - (char *)&reqpkt;
+               if (total_len > sizeof(reqpkt)) {
+                       msyslog(LOG_ERR,
+                               "intres total_len %u limit is %u (%u octet digest)\n",
+                               total_len, sizeof(reqpkt),
+                               req_hashlen);
+                       resolver_exit(1);
+               }
+       } else {
+               pts = &reqpkt.tstamp;
+               pkeyid = &reqpkt.keyid;
+               req_len = REQ_LEN_NOMAC;
+       }
 
+       *pkeyid = htonl(req_keyid);
        get_systime(&ts);
        L_ADDUF(&ts, SKEWTIME);
-       HTONL_FP(&ts, &reqpkt.tstamp);
-       n = 0;
-       if (sys_authenticate)
-               n = authencrypt(req_keyid, (u_int32 *)&reqpkt, REQ_LEN_NOMAC);
+       HTONL_FP(&ts, pts);
+       if (sys_authenticate) {
+               n = authencrypt(req_keyid, (void *)&reqpkt, req_len);
+               if ((size_t)n != req_hashlen + sizeof(reqpkt.keyid)) {
+                       msyslog(LOG_ERR,
+                               "intres maclen %d expected %u\n",
+                               n, req_hashlen + sizeof(reqpkt.keyid));
+                       resolver_exit(1);
+               }
+               req_len += n;
+       }
 
        /*
         * Done.  Send it.
         */
 #ifndef SYS_WINNT
-       n = send(sockfd, (char *)&reqpkt, (unsigned)(REQ_LEN_NOMAC + n), 0);
+       n = send(sockfd, (char *)&reqpkt, req_len, 0);
        if (n < 0) {
                msyslog(LOG_ERR, "send to NTP server failed: %m");
                return 0;       /* maybe should exit */
@@ -780,7 +819,7 @@ request(
         */
        overlap.Offset = overlap.OffsetHigh = (DWORD)0;
        overlap.hEvent = hReadWriteEvent;
-       ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, REQ_LEN_NOMAC + n,
+       ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, req_len,
                        NULL, (LPOVERLAPPED)&overlap);
        if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) {
                msyslog(LOG_ERR, "send to NTP server failed: %m");
@@ -818,17 +857,14 @@ request(
                n = select(sockfd + 1, &fdset, (fd_set *)0,
                           (fd_set *)0, &tvout);
 
-               if (n < 0)
-               {
+               if (n < 0) {
                        if (errno != EINTR)
-                           msyslog(LOG_ERR, "select() fails: %m");
+                               msyslog(LOG_ERR, "select() fails: %m");
                        return 0;
-               }
-               else if (n == 0)
-               {
+               } else if (n == 0) {
 #ifdef DEBUG
                        if (debug)
-                           msyslog(LOG_INFO, "select() returned 0.");
+                               msyslog(LOG_INFO, "ntp_intres select() returned 0.");
 #endif
                        return 0;
                }
@@ -1151,7 +1187,8 @@ doconfigure(
 #endif
 
 #if defined(HAVE_RES_INIT) || defined(HAVE___RES_INIT)
-       if (dores) res_init();  /* Reload /etc/resolv.conf - bug 1226 */
+       if (dores)         /* Reload /etc/resolv.conf - bug 1226 */
+               res_init();
 #endif
        ce = confentries;
        while (ce != NULL) {
@@ -1182,7 +1219,10 @@ doconfigure(
                                removeentry(ceremove);
                                continue;
                        }
-                       // Failed case.  Should bump counter and give up.
+                       /* 
+                        * Failed case.  Should bump counter and give 
+                        * up.
+                        */
 #ifdef DEBUG
                        if (debug > 1) {
                                msyslog(LOG_INFO,
index 0fe81c3d5c4043c44f112c96c81ec754a94c6678..454e3bfe6a3743a3226268f4c326ec53f2d43ac1 100644 (file)
@@ -538,7 +538,7 @@ process_private(
                if (recv_len < (REQ_LEN_HDR +
                    (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
                    INFO_NITEMS(inpkt->err_nitems)) +
-                   sizeof(*tailinpkt))) {
+                   REQ_TAIL_MIN)) {
                        req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
                        return;
                }
@@ -575,13 +575,13 @@ process_private(
                 */
                if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid
                    || ntohl(tailinpkt->keyid) != info_auth_keyid) {
-                       DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %lu maclen %u\n",
+                       DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %u\n",
                                    INFO_IS_AUTH(inpkt->auth_seq),
                                    info_auth_keyid,
                                    ntohl(tailinpkt->keyid), mac_len));
 #ifdef DEBUG
                        msyslog(LOG_DEBUG,
-                               "process_private: failed auth %d info_auth_keyid %u pkt keyid %lu maclen %u\n",
+                               "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %u\n",
                                INFO_IS_AUTH(inpkt->auth_seq),
                                info_auth_keyid,
                                ntohl(tailinpkt->keyid), mac_len);
index ad5ed3f51920ac4603aa6e1290666863b92f27ea..8d538d15f4514b2380b918c86e95f788a89805f3 100644 (file)
@@ -1,4 +1,4 @@
-sizeof(struct req_pkt) = 212
+sizeof(struct req_pkt) = 216
 offsetof(rm_vn_mode) = 0
 offsetof(auth_seq) = 1
 offsetof(implementation) = 2
@@ -10,7 +10,7 @@ offsetof(tstamp) = 184
 offsetof(keyid) = 192
 offsetof(mac) = 196
 
-sizeof(struct req_pkt_tail) = 28
+sizeof(struct req_pkt_tail) = 32
 offsetof(tstamp) = 0
 offsetof(keyid) = 8
 offsetof(mac) = 12
index b84579d464fe6c8ad3cb6f023b7650c33afc0b4e..1c722d1860a4e932c0ace38fed917b801df04aee 100644 (file)
@@ -1807,7 +1807,7 @@ keytype(
 {
        const char *    digest_name;
        size_t          digest_len;
-       int             keytype;
+       int             key_type;
 
        if (!pcmd->nargs) {
                fprintf(fp, "keytype is %s with %u octet digests\n",
@@ -1818,9 +1818,9 @@ keytype(
 
        digest_name = pcmd->argval[0].string;
        digest_len = 0;
-       keytype = keytype_from_text(digest_name, &digest_len);
+       key_type = keytype_from_text(digest_name, &digest_len);
 
-       if (!keytype) {
+       if (!key_type) {
                fprintf(fp, "keytype must be 'md5'%s\n",
 #ifdef OPENSSL
                        " or a digest type provided by OpenSSL");
@@ -1830,7 +1830,7 @@ keytype(
                return;
        }
 
-       info_auth_keytype = keytype;
+       info_auth_keytype = key_type;
        info_auth_hashlen = digest_len;
 }