summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/libntp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp')
-rw-r--r--contrib/ntp/libntp/Makefile.am1
-rw-r--r--contrib/ntp/libntp/Makefile.in22
-rw-r--r--contrib/ntp/libntp/a_md5encrypt.c4
-rw-r--r--contrib/ntp/libntp/authkeys.c326
-rw-r--r--contrib/ntp/libntp/authreadkeys.c103
-rw-r--r--contrib/ntp/libntp/is_ip_address.c40
-rw-r--r--contrib/ntp/libntp/ntp_intres.c48
-rw-r--r--contrib/ntp/libntp/ntp_worker.c2
-rw-r--r--contrib/ntp/libntp/recvbuff.c28
-rw-r--r--contrib/ntp/libntp/work_fork.c7
-rw-r--r--contrib/ntp/libntp/work_thread.c23
11 files changed, 332 insertions, 272 deletions
diff --git a/contrib/ntp/libntp/Makefile.am b/contrib/ntp/libntp/Makefile.am
index a3b50e1..26a4709 100644
--- a/contrib/ntp/libntp/Makefile.am
+++ b/contrib/ntp/libntp/Makefile.am
@@ -36,6 +36,7 @@ libisc_SRCS = \
$(srcdir)/../lib/isc/unix/time.c \
$(srcdir)/../lib/isc/sha1.c \
$(srcdir)/../lib/isc/sockaddr.c \
+ $(srcdir)/../lib/isc/tsmemcmp.c \
$(NULL)
if PTHREADS
diff --git a/contrib/ntp/libntp/Makefile.in b/contrib/ntp/libntp/Makefile.in
index 5cf5703..9125c19 100644
--- a/contrib/ntp/libntp/Makefile.in
+++ b/contrib/ntp/libntp/Makefile.in
@@ -182,6 +182,7 @@ am__libntp_a_SOURCES_DIST = systime.c a_md5encrypt.c adjtime.c \
$(srcdir)/../lib/isc/$(LIBISC_PTHREADS_NOTHREADS)/thread.c \
$(srcdir)/../lib/isc/unix/time.c $(srcdir)/../lib/isc/sha1.c \
$(srcdir)/../lib/isc/sockaddr.c \
+ $(srcdir)/../lib/isc/tsmemcmp.c \
$(srcdir)/../lib/isc/pthreads/mutex.c
am__objects_1 =
@PTHREADS_TRUE@am__objects_2 = mutex.$(OBJEXT)
@@ -196,7 +197,7 @@ am__objects_3 = assertions.$(OBJEXT) buffer.$(OBJEXT) \
result.$(OBJEXT) stdio.$(OBJEXT) stdtime.$(OBJEXT) \
strerror.$(OBJEXT) task.$(OBJEXT) thread.$(OBJEXT) \
time.$(OBJEXT) sha1.$(OBJEXT) sockaddr.$(OBJEXT) \
- $(am__objects_1) $(am__objects_2)
+ tsmemcmp.$(OBJEXT) $(am__objects_1) $(am__objects_2)
am__objects_4 = a_md5encrypt.$(OBJEXT) adjtime.$(OBJEXT) \
atoint.$(OBJEXT) atolfp.$(OBJEXT) atouint.$(OBJEXT) \
audio.$(OBJEXT) authkeys.$(OBJEXT) authreadkeys.$(OBJEXT) \
@@ -264,6 +265,7 @@ am__libntpsim_a_SOURCES_DIST = systime_s.c a_md5encrypt.c adjtime.c \
$(srcdir)/../lib/isc/$(LIBISC_PTHREADS_NOTHREADS)/thread.c \
$(srcdir)/../lib/isc/unix/time.c $(srcdir)/../lib/isc/sha1.c \
$(srcdir)/../lib/isc/sockaddr.c \
+ $(srcdir)/../lib/isc/tsmemcmp.c \
$(srcdir)/../lib/isc/pthreads/mutex.c
am_libntpsim_a_OBJECTS = systime_s.$(OBJEXT) $(am__objects_4)
libntpsim_a_OBJECTS = $(am_libntpsim_a_OBJECTS)
@@ -631,7 +633,8 @@ libisc_SRCS = $(srcdir)/../lib/isc/assertions.c \
$(srcdir)/../lib/isc/task.c \
$(srcdir)/../lib/isc/$(LIBISC_PTHREADS_NOTHREADS)/thread.c \
$(srcdir)/../lib/isc/unix/time.c $(srcdir)/../lib/isc/sha1.c \
- $(srcdir)/../lib/isc/sockaddr.c $(NULL) $(am__append_1)
+ $(srcdir)/../lib/isc/sockaddr.c \
+ $(srcdir)/../lib/isc/tsmemcmp.c $(NULL) $(am__append_1)
libntp_a_SRCS = \
a_md5encrypt.c \
adjtime.c \
@@ -862,6 +865,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timetoa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timevalops.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsmemcmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uglydate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vint64ops.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/work_fork.Po@am__quote@
@@ -1323,6 +1327,20 @@ sockaddr.obj: $(srcdir)/../lib/isc/sockaddr.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sockaddr.obj `if test -f '$(srcdir)/../lib/isc/sockaddr.c'; then $(CYGPATH_W) '$(srcdir)/../lib/isc/sockaddr.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../lib/isc/sockaddr.c'; fi`
+tsmemcmp.o: $(srcdir)/../lib/isc/tsmemcmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tsmemcmp.o -MD -MP -MF $(DEPDIR)/tsmemcmp.Tpo -c -o tsmemcmp.o `test -f '$(srcdir)/../lib/isc/tsmemcmp.c' || echo '$(srcdir)/'`$(srcdir)/../lib/isc/tsmemcmp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tsmemcmp.Tpo $(DEPDIR)/tsmemcmp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../lib/isc/tsmemcmp.c' object='tsmemcmp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tsmemcmp.o `test -f '$(srcdir)/../lib/isc/tsmemcmp.c' || echo '$(srcdir)/'`$(srcdir)/../lib/isc/tsmemcmp.c
+
+tsmemcmp.obj: $(srcdir)/../lib/isc/tsmemcmp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tsmemcmp.obj -MD -MP -MF $(DEPDIR)/tsmemcmp.Tpo -c -o tsmemcmp.obj `if test -f '$(srcdir)/../lib/isc/tsmemcmp.c'; then $(CYGPATH_W) '$(srcdir)/../lib/isc/tsmemcmp.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../lib/isc/tsmemcmp.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tsmemcmp.Tpo $(DEPDIR)/tsmemcmp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../lib/isc/tsmemcmp.c' object='tsmemcmp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tsmemcmp.obj `if test -f '$(srcdir)/../lib/isc/tsmemcmp.c'; then $(CYGPATH_W) '$(srcdir)/../lib/isc/tsmemcmp.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../lib/isc/tsmemcmp.c'; fi`
+
mutex.o: $(srcdir)/../lib/isc/pthreads/mutex.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mutex.o -MD -MP -MF $(DEPDIR)/mutex.Tpo -c -o mutex.o `test -f '$(srcdir)/../lib/isc/pthreads/mutex.c' || echo '$(srcdir)/'`$(srcdir)/../lib/isc/pthreads/mutex.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mutex.Tpo $(DEPDIR)/mutex.Po
diff --git a/contrib/ntp/libntp/a_md5encrypt.c b/contrib/ntp/libntp/a_md5encrypt.c
index beaf6fd..618ccd9 100644
--- a/contrib/ntp/libntp/a_md5encrypt.c
+++ b/contrib/ntp/libntp/a_md5encrypt.c
@@ -10,7 +10,7 @@
#include "ntp_stdlib.h"
#include "ntp.h"
#include "ntp_md5.h" /* provides OpenSSL digest API */
-
+#include "isc/string.h"
/*
* MD5authencrypt - generate message digest
*
@@ -92,7 +92,7 @@ MD5authdecrypt(
"MAC decrypt: MAC length error");
return (0);
}
- return !memcmp(digest, (const char *)pkt + length + 4, len);
+ return !isc_tsmemcmp(digest, (const char *)pkt + length + 4, len);
}
/*
diff --git a/contrib/ntp/libntp/authkeys.c b/contrib/ntp/libntp/authkeys.c
index 36fdd8b..51337d5 100644
--- a/contrib/ntp/libntp/authkeys.c
+++ b/contrib/ntp/libntp/authkeys.c
@@ -30,7 +30,7 @@ struct savekey {
u_long lifetime; /* remaining lifetime */
keyid_t keyid; /* key identifier */
u_short type; /* OpenSSL digest NID */
- u_short secretsize; /* secret octets */
+ size_t secretsize; /* secret octets */
u_short flags; /* KEY_ flags that wave */
};
@@ -51,12 +51,12 @@ symkey_alloc * authallocs;
#endif /* DEBUG */
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 *, KeyAccT *);
-static void freesymkey(symkey *, symkey **);
+static void auth_resize_hashtable(void);
+static void allocsymkey(keyid_t, u_short,
+ u_short, u_long, size_t, u_char *, KeyAccT *);
+static void freesymkey(symkey *);
#ifdef DEBUG
-static void free_auth_mem(void);
+static void free_auth_mem(void);
#endif
symkey key_listhead; /* list of all in-use keys */;
@@ -93,14 +93,87 @@ int authnumfreekeys;
/*
* The key cache. We cache the last key we looked at here.
+ * Note: this should hold the last *trusted* key. Also the
+ * cache is only loaded when the digest type / MAC algorithm
+ * is valid.
*/
keyid_t cache_keyid; /* key identifier */
u_char *cache_secret; /* secret */
-u_short cache_secretsize; /* secret length */
+size_t cache_secretsize; /* secret length */
int cache_type; /* OpenSSL digest NID */
u_short cache_flags; /* flags that wave */
KeyAccT *cache_keyacclist; /* key access list */
+/* --------------------------------------------------------------------
+ * manage key access lists
+ * --------------------------------------------------------------------
+ */
+/* allocate and populate new access node and pushes it on the list.
+ * Returns the new head.
+ */
+KeyAccT*
+keyacc_new_push(
+ KeyAccT * head,
+ const sockaddr_u * addr
+ )
+{
+ KeyAccT * node = emalloc(sizeof(KeyAccT));
+
+ memcpy(&node->addr, addr, sizeof(sockaddr_u));
+ node->next = head;
+ return node;
+}
+
+/* ----------------------------------------------------------------- */
+/* pop and deallocate the first node of a list of access nodes, if
+ * the list is not empty. Returns the tail of the list.
+ */
+KeyAccT*
+keyacc_pop_free(
+ KeyAccT *head
+ )
+{
+ KeyAccT * next = NULL;
+ if (head) {
+ next = head->next;
+ free(head);
+ }
+ return next;
+}
+
+/* ----------------------------------------------------------------- */
+/* deallocate the list; returns an empty list. */
+KeyAccT*
+keyacc_all_free(
+ KeyAccT * head
+ )
+{
+ while (head)
+ head = keyacc_pop_free(head);
+ return head;
+}
+
+/* ----------------------------------------------------------------- */
+/* scan a list to see if it contains a given address. Return the
+ * default result value in case of an empty list.
+ */
+int /*BOOL*/
+keyacc_contains(
+ const KeyAccT *head,
+ const sockaddr_u *addr,
+ int defv)
+{
+ if (head) {
+ do {
+ if (SOCK_EQ(&head->addr, addr))
+ return TRUE;
+ } while (NULL != (head = head->next));
+ return FALSE;
+ } else {
+ return !!defv;
+ }
+}
+
/*
* init_auth - initialize internal data
@@ -139,7 +212,7 @@ free_auth_mem(void)
symkey_alloc * next_alloc;
while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) {
- freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ freesymkey(sk);
}
free(key_hash);
key_hash = NULL;
@@ -243,6 +316,21 @@ auth_log2(size_t x)
return (u_short)r;
}
+static void
+authcache_flush_id(
+ keyid_t id
+ )
+{
+ if (cache_keyid == id) {
+ cache_keyid = 0;
+ cache_type = 0;
+ cache_flags = 0;
+ cache_secret = NULL;
+ cache_secretsize = 0;
+ cache_keyacclist = NULL;
+ }
+}
+
/*
* auth_resize_hashtable
@@ -288,17 +376,20 @@ auth_resize_hashtable(void)
*/
static void
allocsymkey(
- symkey ** bucket,
keyid_t id,
u_short flags,
u_short type,
u_long lifetime,
- u_short secretsize,
+ size_t secretsize,
u_char * secret,
KeyAccT * ka
)
{
symkey * sk;
+ symkey ** bucket;
+
+ bucket = &key_hash[KEYHASH(id)];
+
if (authnumfreekeys < 1)
auth_moremem(-1);
@@ -323,12 +414,19 @@ allocsymkey(
*/
static void
freesymkey(
- symkey * sk,
- symkey ** bucket
+ symkey * sk
)
{
+ symkey ** bucket;
symkey * unlinked;
+ if (NULL == sk)
+ return;
+
+ authcache_flush_id(sk->keyid);
+ keyacc_all_free(sk->keyacclist);
+
+ bucket = &key_hash[KEYHASH(sk->keyid)];
if (sk->secret != NULL) {
memset(sk->secret, '\0', sk->secretsize);
free(sk->secret);
@@ -354,37 +452,26 @@ auth_findkey(
{
symkey * sk;
- for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
- if (id == sk->keyid) {
+ for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink)
+ if (id == sk->keyid)
return sk;
- }
- }
-
return NULL;
}
/*
- * auth_havekey - return TRUE if the key id is zero or known
+ * auth_havekey - return TRUE if the key id is zero or known. The
+ * key needs not to be trusted.
*/
int
auth_havekey(
keyid_t id
)
{
- symkey * sk;
-
- if (0 == id || cache_keyid == id) {
- return TRUE;
- }
-
- for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
- if (id == sk->keyid) {
- return TRUE;
- }
- }
-
- return FALSE;
+ return
+ (0 == id) ||
+ (cache_keyid == id) ||
+ (NULL != auth_findkey(id));
}
@@ -400,35 +487,25 @@ authhavekey(
symkey * sk;
authkeylookups++;
- if (0 == id || cache_keyid == id) {
- return TRUE;
- }
+ if (0 == id || cache_keyid == id)
+ return !!(KEY_TRUSTED & cache_flags);
/*
- * Seach the bin for the key. If found and the key type
- * is zero, somebody marked it trusted without specifying
- * a key or key type. In this case consider the key missing.
+ * Search the bin for the key. If not found, or found but the key
+ * type is zero, somebody marked it trusted without specifying a
+ * key or key type. In this case consider the key missing.
*/
authkeyuncached++;
- for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) {
- if (id == sk->keyid) {
- if (0 == sk->type) {
- authkeynotfound++;
- return FALSE;
- }
- break;
- }
+ sk = auth_findkey(id);
+ if ((sk == NULL) || (sk->type == 0)) {
+ authkeynotfound++;
+ return FALSE;
}
/*
- * If the key is not found, or if it is found but not trusted,
- * the key is not considered found.
+ * If the key is not trusted, the key is not considered found.
*/
- if (NULL == sk) {
- authkeynotfound++;
- return FALSE;
- }
- if (!(KEY_TRUSTED & sk->flags)) {
+ if ( ! (KEY_TRUSTED & sk->flags)) {
authnokey++;
return FALSE;
}
@@ -456,7 +533,6 @@ authtrust(
u_long trust
)
{
- symkey ** bucket;
symkey * sk;
u_long lifetime;
@@ -464,12 +540,9 @@ authtrust(
* Search bin for key; if it does not exist and is untrusted,
* forget it.
*/
- bucket = &key_hash[KEYHASH(id)];
- for (sk = *bucket; sk != NULL; sk = sk->hlink) {
- if (id == sk->keyid)
- break;
- }
- if (!trust && NULL == sk)
+
+ sk = auth_findkey(id);
+ if (!trust && sk == NULL)
return;
/*
@@ -478,27 +551,22 @@ authtrust(
* not to be trusted.
*/
if (sk != NULL) {
- if (cache_keyid == id) {
- cache_flags = 0;
- cache_keyid = 0;
- cache_keyacclist = NULL;
- }
-
/*
- * Key exists. If it is to be trusted, say so and
- * update its lifetime.
+ * Key exists. If it is to be trusted, say so and update
+ * its lifetime. If no longer trusted, return it to the
+ * free list. Flush the cache first to be sure there are
+ * no discrepancies.
*/
+ authcache_flush_id(id);
if (trust > 0) {
sk->flags |= KEY_TRUSTED;
if (trust > 1)
sk->lifetime = current_time + trust;
else
sk->lifetime = 0;
- return;
+ } else {
+ freesymkey(sk);
}
-
- /* No longer trusted, return it to the free list. */
- freesymkey(sk, bucket);
return;
}
@@ -511,7 +579,7 @@ authtrust(
} else {
lifetime = 0;
}
- allocsymkey(bucket, id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
+ allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL);
}
@@ -520,22 +588,17 @@ authtrust(
*/
int
authistrusted(
- keyid_t keyno
+ keyid_t id
)
{
symkey * sk;
- symkey ** bucket;
- if (keyno == cache_keyid)
+ if (id == cache_keyid)
return !!(KEY_TRUSTED & cache_flags);
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)) {
+ sk = auth_findkey(id);
+ if (sk == NULL || !(KEY_TRUSTED & sk->flags)) {
authkeynotfound++;
return FALSE;
}
@@ -553,38 +616,23 @@ authistrusted(
)
{
symkey * sk;
- symkey ** bucket;
- KeyAccT * kal;
- KeyAccT * k;
- if (keyno == cache_keyid)
- kal = cache_keyacclist;
- else {
+ /* That specific key was already used to authenticate the
+ * packet. Therefore, the key *must* exist... There's a chance
+ * that is not trusted, though.
+ */
+ if (keyno == cache_keyid) {
+ return (KEY_TRUSTED & cache_flags) &&
+ keyacc_contains(cache_keyacclist, sau, TRUE);
+ } 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;
+ sk = auth_findkey(keyno);
+ INSIST(NULL != sk);
+ return (KEY_TRUSTED & sk->flags) &&
+ keyacc_contains(sk->keyacclist, sau, TRUE);
}
-
- 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
@@ -601,71 +649,66 @@ MD5auth_setkey(
keyid_t keyno,
int keytype,
const u_char *key,
- size_t len,
+ size_t secretsize,
KeyAccT *ka
)
{
symkey * sk;
- symkey ** bucket;
u_char * secret;
- size_t secretsize;
DEBUG_ENSURE(keytype <= USHRT_MAX);
- DEBUG_ENSURE(len < 4 * 1024);
+ DEBUG_ENSURE(secretsize < 4 * 1024);
/*
* See if we already have the key. If so just stick in the
* new value.
*/
- bucket = &key_hash[KEYHASH(keyno)];
- for (sk = *bucket; sk != NULL; sk = sk->hlink) {
- if (keyno == sk->keyid) {
+ sk = auth_findkey(keyno);
+ if (sk != NULL && keyno == sk->keyid) {
/* TALOS-CAN-0054: make sure we have a new buffer! */
- if (NULL != sk->secret) {
- memset(sk->secret, 0, sk->secretsize);
- free(sk->secret);
- }
- sk->secret = emalloc(len);
- sk->type = (u_short)keytype;
- secretsize = len;
- sk->secretsize = (u_short)secretsize;
+ if (NULL != sk->secret) {
+ memset(sk->secret, 0, sk->secretsize);
+ free(sk->secret);
+ }
+ sk->secret = emalloc(secretsize + 1);
+ sk->type = (u_short)keytype;
+ sk->secretsize = secretsize;
+ /* make sure access lists don't leak here! */
+ if (ka != sk->keyacclist) {
+ keyacc_all_free(sk->keyacclist);
sk->keyacclist = ka;
+ }
#ifndef DISABLE_BUG1243_FIX
- memcpy(sk->secret, key, secretsize);
+ memcpy(sk->secret, key, secretsize);
#else
- /* >MUST< use 'strncpy()' here! See above! */
- strncpy((char *)sk->secret, (const char *)key,
- secretsize);
+ /* >MUST< use 'strncpy()' here! See above! */
+ strncpy((char *)sk->secret, (const char *)key,
+ secretsize);
#endif
- if (cache_keyid == keyno) {
- cache_flags = 0;
- cache_keyid = 0;
- cache_keyacclist = NULL;
- }
- return;
- }
+ authcache_flush_id(keyno);
+ return;
}
/*
* Need to allocate new structure. Do it.
*/
- secretsize = len;
- secret = emalloc(secretsize);
+ secret = emalloc(secretsize + 1);
#ifndef DISABLE_BUG1243_FIX
memcpy(secret, key, secretsize);
#else
/* >MUST< use 'strncpy()' here! See above! */
strncpy((char *)secret, (const char *)key, secretsize);
#endif
- allocsymkey(bucket, keyno, 0, (u_short)keytype, 0,
- (u_short)secretsize, secret, ka);
+ allocsymkey(keyno, 0, (u_short)keytype, 0,
+ secretsize, secret, ka);
#ifdef DEBUG
if (debug >= 4) {
size_t j;
printf("auth_setkey: key %d type %d len %d ", (int)keyno,
keytype, (int)secretsize);
- for (j = 0; j < secretsize; j++)
+ for (j = 0; j < secretsize; j++) {
printf("%02x", secret[j]);
+ }
printf("\n");
}
#endif
@@ -697,10 +740,11 @@ auth_delkeys(void)
free(sk->secret);
sk->secret = NULL; /* TALOS-CAN-0054 */
}
+ sk->keyacclist = keyacc_all_free(sk->keyacclist);
sk->secretsize = 0;
sk->lifetime = 0;
} else {
- freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ freesymkey(sk);
}
ITER_DLIST_END()
}
@@ -716,7 +760,7 @@ auth_agekeys(void)
ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey)
if (sk->lifetime > 0 && current_time > sk->lifetime) {
- freesymkey(sk, &key_hash[KEYHASH(sk->keyid)]);
+ freesymkey(sk);
authkeyexpired++;
}
ITER_DLIST_END()
diff --git a/contrib/ntp/libntp/authreadkeys.c b/contrib/ntp/libntp/authreadkeys.c
index 1d4ee30..e9273ad 100644
--- a/contrib/ntp/libntp/authreadkeys.c
+++ b/contrib/ntp/libntp/authreadkeys.c
@@ -101,13 +101,33 @@ log_maybe(
...)
{
va_list ap;
- if (++(*pnerr) <= nerr_loglimit) {
+ if ((NULL == pnerr) || (++(*pnerr) <= nerr_loglimit)) {
va_start(ap, fmt);
mvsyslog(LOG_ERR, fmt, ap);
va_end(ap);
}
}
+static void
+free_keydata(
+ KeyDataT *node
+ )
+{
+ KeyAccT *kap;
+
+ if (node) {
+ while (node->keyacclist) {
+ kap = node->keyacclist;
+ node->keyacclist = kap->next;
+ free(kap);
+ }
+
+ /* purge secrets from memory before free()ing it */
+ memset(node, 0, sizeof(*node) + node->seclen);
+ free(node);
+ }
+}
+
/*
* authreadkeys - (re)read keys from a file.
*/
@@ -156,7 +176,7 @@ authreadkeys(
* First is key number. See if it is okay.
*/
keyno = atoi(token);
- if (keyno == 0) {
+ if (keyno < 1) {
log_maybe(&nerr,
"authreadkeys: cannot change key %s",
token);
@@ -180,6 +200,14 @@ authreadkeys(
keyno);
continue;
}
+
+ /* We want to silently ignore keys where we do not
+ * support the requested digest type. OTOH, we want to
+ * make sure the file is well-formed. That means we
+ * have to process the line completely and have to
+ * finally throw away the result... This is a bit more
+ * work, but it also results in better error detection.
+ */
#ifdef OPENSSL
/*
* The key type is the NID used by the message digest
@@ -189,30 +217,28 @@ authreadkeys(
*/
keytype = keytype_from_text(token, NULL);
if (keytype == 0) {
- log_maybe(&nerr,
+ log_maybe(NULL,
"authreadkeys: invalid type for key %d",
keyno);
- continue;
- }
- if (EVP_get_digestbynid(keytype) == NULL) {
- log_maybe(&nerr,
+ } else if (EVP_get_digestbynid(keytype) == NULL) {
+ log_maybe(NULL,
"authreadkeys: no algorithm for key %d",
keyno);
- continue;
+ keytype = 0;
}
#else /* !OPENSSL follows */
-
/*
* The key type is unused, but is required to be 'M' or
* 'm' for compatibility.
*/
if (!(*token == 'M' || *token == 'm')) {
- log_maybe(&nerr,
+ log_maybe(NULL,
"authreadkeys: invalid type for key %d",
keyno);
- continue;
+ keytype = 0;
+ } else {
+ keytype = KEY_TYPE_MD5;
}
- keytype = KEY_TYPE_MD5;
#endif /* !OPENSSL */
/*
@@ -269,26 +295,22 @@ authreadkeys(
}
token = nexttok(&line);
-DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL"));
+ 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;
+ sockaddr_u addr;
i = strchr(tp, (int)',');
if (i)
*i = '\0';
-DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
+ 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;
+ if (is_ip_address(tp, AF_UNSPEC, &addr)) {
+ next->keyacclist = keyacc_new_push(
+ next->keyacclist, &addr);
} else {
log_maybe(&nerr,
"authreadkeys: invalid IP address <%s> for key %d",
@@ -303,21 +325,25 @@ DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
}
}
+ /* check if this has to be weeded out... */
+ if (0 == keytype) {
+ free_keydata(next);
+ next = NULL;
+ continue;
+ }
+
INSIST(NULL != next);
next->next = list;
list = next;
}
fclose(fp);
- if (nerr > nerr_maxlimit) {
- msyslog(LOG_ERR,
- "authreadkeys: rejecting file '%s' after %u errors (emergency break)",
- file, nerr);
- goto onerror;
- }
if (nerr > 0) {
+ const char * why = "";
+ if (nerr > nerr_maxlimit)
+ why = " (emergency break)";
msyslog(LOG_ERR,
- "authreadkeys: rejecting file '%s' after %u error(s)",
- file, nerr);
+ "authreadkeys: rejecting file '%s' after %u error(s)%s",
+ file, nerr, why);
goto onerror;
}
@@ -328,9 +354,8 @@ DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
list = next->next;
MD5auth_setkey(next->keyid, next->keytype,
next->secbuf, next->seclen, next->keyacclist);
- /* purge secrets from memory before free()ing it */
- memset(next, 0, sizeof(*next) + next->seclen);
- free(next);
+ next->keyacclist = NULL; /* consumed by MD5auth_setkey */
+ free_keydata(next);
}
return (1);
@@ -338,17 +363,7 @@ DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
/* 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);
+ free_keydata(next);
}
return (0);
}
diff --git a/contrib/ntp/libntp/is_ip_address.c b/contrib/ntp/libntp/is_ip_address.c
index 1f21376..d36984c 100644
--- a/contrib/ntp/libntp/is_ip_address.c
+++ b/contrib/ntp/libntp/is_ip_address.c
@@ -7,53 +7,13 @@
# 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>
diff --git a/contrib/ntp/libntp/ntp_intres.c b/contrib/ntp/libntp/ntp_intres.c
index b0f5620..0b5bb75 100644
--- a/contrib/ntp/libntp/ntp_intres.c
+++ b/contrib/ntp/libntp/ntp_intres.c
@@ -201,8 +201,6 @@ static time_t next_res_init;
/* === forward declarations === */
static u_int reserve_dnschild_ctx(void);
static u_int get_dnschild_ctx(void);
-static void alloc_dnsworker_context(u_int);
-/* static void free_dnsworker_context(u_int); */
static dnsworker_ctx * get_worker_context(blocking_child *, u_int);
static void scheduled_sleep(time_t, time_t,
dnsworker_ctx *);
@@ -949,47 +947,41 @@ get_dnschild_ctx(void)
}
-static void
-alloc_dnsworker_context(
- u_int idx
- )
-{
- const size_t worker_context_sz = sizeof(*dnsworker_contexts[0]);
-
- REQUIRE(NULL == dnsworker_contexts[idx]);
- dnsworker_contexts[idx] = emalloc_zero(worker_context_sz);
-}
-
-
static dnsworker_ctx *
get_worker_context(
blocking_child * c,
u_int idx
)
{
- static size_t ps = sizeof(dnsworker_contexts[0]);
- u_int min_new_alloc;
- u_int new_alloc;
- size_t octets;
- size_t new_octets;
+ u_int min_new_alloc;
+ u_int new_alloc;
+ size_t octets;
+ size_t new_octets;
+ dnsworker_ctx * retv;
+ worker_global_lock(TRUE);
+
if (dnsworker_contexts_alloc <= idx) {
min_new_alloc = 1 + idx;
/* round new_alloc up to nearest multiple of 4 */
new_alloc = (min_new_alloc + 4) & ~(4 - 1);
- new_octets = new_alloc * ps;
- octets = dnsworker_contexts_alloc * ps;
+ new_octets = new_alloc * sizeof(dnsworker_ctx*);
+ octets = dnsworker_contexts_alloc * sizeof(dnsworker_ctx*);
dnsworker_contexts = erealloc_zero(dnsworker_contexts,
new_octets, octets);
dnsworker_contexts_alloc = new_alloc;
+ retv = emalloc_zero(sizeof(dnsworker_ctx));
+ dnsworker_contexts[idx] = retv;
+ } else if (NULL == (retv = dnsworker_contexts[idx])) {
+ retv = emalloc_zero(sizeof(dnsworker_ctx));
+ dnsworker_contexts[idx] = retv;
}
-
- if (NULL == dnsworker_contexts[idx])
- alloc_dnsworker_context(idx);
- ZERO(*dnsworker_contexts[idx]);
- dnsworker_contexts[idx]->c = c;
-
- return dnsworker_contexts[idx];
+
+ worker_global_lock(FALSE);
+
+ ZERO(*retv);
+ retv->c = c;
+ return retv;
}
diff --git a/contrib/ntp/libntp/ntp_worker.c b/contrib/ntp/libntp/ntp_worker.c
index 087f06c..d1d09c0 100644
--- a/contrib/ntp/libntp/ntp_worker.c
+++ b/contrib/ntp/libntp/ntp_worker.c
@@ -267,7 +267,7 @@ process_blocking_resp(
void
harvest_blocking_responses(void)
{
- int idx;
+ size_t idx;
blocking_child* cp;
u_int scseen, scdone;
diff --git a/contrib/ntp/libntp/recvbuff.c b/contrib/ntp/libntp/recvbuff.c
index 73ebe88..f888950 100644
--- a/contrib/ntp/libntp/recvbuff.c
+++ b/contrib/ntp/libntp/recvbuff.c
@@ -156,18 +156,15 @@ uninit_recvbuff(void)
void
freerecvbuf(recvbuf_t *rb)
{
- if (rb == NULL) {
- msyslog(LOG_ERR, "freerecvbuff received NULL buffer");
- return;
+ if (rb) {
+ LOCK();
+ rb->used--;
+ if (rb->used != 0)
+ msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
+ LINK_SLIST(free_recv_list, rb, link);
+ free_recvbufs++;
+ UNLOCK();
}
-
- LOCK();
- rb->used--;
- if (rb->used != 0)
- msyslog(LOG_ERR, "******** freerecvbuff non-zero usage: %d *******", rb->used);
- LINK_SLIST(free_recv_list, rb, link);
- free_recvbufs++;
- UNLOCK();
}
@@ -264,7 +261,7 @@ get_full_recv_buffer(void)
*/
void
purge_recv_buffers_for_fd(
- SOCKET fd
+ int fd
)
{
recvbuf_t *rbufp;
@@ -277,7 +274,12 @@ purge_recv_buffers_for_fd(
rbufp != NULL;
rbufp = next) {
next = rbufp->link;
- if (rbufp->fd == fd) {
+# ifdef HAVE_IO_COMPLETION_PORT
+ if (rbufp->dstadr == NULL && rbufp->fd == fd)
+# else
+ if (rbufp->fd == fd)
+# endif
+ {
UNLINK_MID_FIFO(punlinked, full_recv_fifo,
rbufp, link, recvbuf_t);
INSIST(punlinked == rbufp);
diff --git a/contrib/ntp/libntp/work_fork.c b/contrib/ntp/libntp/work_fork.c
index 96c550e..6c9545a 100644
--- a/contrib/ntp/libntp/work_fork.c
+++ b/contrib/ntp/libntp/work_fork.c
@@ -451,7 +451,7 @@ fork_blocking_child(
}
}
-#ifdef HAVE_DROPROOT
+#if defined(HAVE_DROPROOT) && !defined(NEED_EARLY_FORK)
/* defer the fork until after root is dropped */
if (droproot && !root_dropped)
return;
@@ -540,6 +540,11 @@ fork_blocking_child(
}
+void worker_global_lock(int inOrOut)
+{
+ (void)inOrOut;
+}
+
#else /* !WORK_FORK follows */
char work_fork_nonempty_compilation_unit;
#endif
diff --git a/contrib/ntp/libntp/work_thread.c b/contrib/ntp/libntp/work_thread.c
index 11e3267..82f6064 100644
--- a/contrib/ntp/libntp/work_thread.c
+++ b/contrib/ntp/libntp/work_thread.c
@@ -88,7 +88,27 @@ static int ensure_workresp_empty_slot(blocking_child *);
static int queue_req_pointer(blocking_child *, blocking_pipe_header *);
static void cleanup_after_child(blocking_child *);
+static sema_type worker_mmutex;
+static sem_ref worker_memlock;
+/* --------------------------------------------------------------------
+ * locking the global worker state table (and other global stuff)
+ */
+void
+worker_global_lock(
+ int inOrOut)
+{
+ if (worker_memlock) {
+ if (inOrOut)
+ wait_for_sem(worker_memlock, NULL);
+ else
+ tickle_sem(worker_memlock);
+ }
+}
+
+/* --------------------------------------------------------------------
+ * implementation isolation wrapper
+ */
void
exit_worker(
int exitcode
@@ -724,6 +744,9 @@ prepare_child_sems(
blocking_child *c
)
{
+ if (NULL == worker_memlock)
+ worker_memlock = create_sema(&worker_mmutex, 1, 1);
+
c->accesslock = create_sema(&c->sem_table[0], 1, 1);
c->workitems_pending = create_sema(&c->sem_table[1], 0, 0);
c->wake_scheduled_sleep = create_sema(&c->sem_table[2], 0, 1);
OpenPOWER on IntegriCloud