larger than 16 octets.
Add /lib to OpenSSL library search path, OpenSolaris has it there.
bk: 4afb5c17_FCklSAA8sArpvcR3zWSIA
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
;;
esac
AC_SUBST(LCRYPTO, [-lcrypto])
AC_DEFINE(OPENSSL, , [Use OpenSSL?])
- AC_CHECK_FUNCS([EVP_md2 EVP_mdc2])
esac
#
/* 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 */
};
/*
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
/* 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;
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);
int
hextoint(
const char *str,
- u_long *ival
+ u_long *pu
)
{
register u_long u;
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;
}
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <ctype.h>
#include <ntp.h>
#include <ntp_debug.h>
#include <lib_strbuf.h>
*/
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;
*/
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);
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)
#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
if (NULL == name)
name = unknown_type;
#else /* !OPENSSL follows */
- if (nid_MD5 == nid)
+ if (NID_md5 == nid)
name = "MD5";
else
name = unknown_type;
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
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);
}
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);
/* 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 */
}
if (entry->ce_name) {
- if (0) msyslog(LOG_INFO, "findhostaddr: Trying %s", entry->ce_name);
DPRINTF(2, ("findhostaddr: Resolving <%s>\n",
entry->ce_name));
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 */
/*
* 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 */
*/
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");
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;
}
#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) {
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,
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;
}
*/
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);
-sizeof(struct req_pkt) = 212
+sizeof(struct req_pkt) = 216
offsetof(rm_vn_mode) = 0
offsetof(auth_seq) = 1
offsetof(implementation) = 2
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
{
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",
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");
return;
}
- info_auth_keytype = keytype;
+ info_auth_keytype = key_type;
info_auth_hashlen = digest_len;
}