summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/nameser
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/lib/nameser')
-rw-r--r--contrib/bind/lib/nameser/Makefile33
-rw-r--r--contrib/bind/lib/nameser/ns_date.c128
-rw-r--r--contrib/bind/lib/nameser/ns_name.c65
-rw-r--r--contrib/bind/lib/nameser/ns_netint.c10
-rw-r--r--contrib/bind/lib/nameser/ns_parse.c122
-rw-r--r--contrib/bind/lib/nameser/ns_print.c93
-rw-r--r--contrib/bind/lib/nameser/ns_samedomain.c206
-rw-r--r--contrib/bind/lib/nameser/ns_sign.c348
-rw-r--r--contrib/bind/lib/nameser/ns_ttl.c6
-rw-r--r--contrib/bind/lib/nameser/ns_verify.c471
10 files changed, 1382 insertions, 100 deletions
diff --git a/contrib/bind/lib/nameser/Makefile b/contrib/bind/lib/nameser/Makefile
index d86dc74..52a102f 100644
--- a/contrib/bind/lib/nameser/Makefile
+++ b/contrib/bind/lib/nameser/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1996 by Internet Software Consortium
+# Copyright (c) 1996,1999 by Internet Software Consortium
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
# SOFTWARE.
#
-# $Id: Makefile,v 8.7 1997/05/21 19:32:08 halley Exp $
+# $Id: Makefile,v 8.16 1999/09/07 08:47:28 vixie Exp $
# these are only appropriate for BSD 4.4 or derivatives, and are used in
# development. normal builds will be done in the top level directory and
@@ -33,31 +33,48 @@ TOP= ../..
INCL = ${TOP}/include
PORTINCL = ${TOP}/port/${SYSTYPE}/include
LIBBIND = ${TOP}/lib/libbind.${A}
+LIBBINDR = ../${TOP}/lib/libbind_r.${A}
CFLAGS= ${CDEBUG} -I${PORTINCL} -I${INCL}
LD_LIBFLAGS= -x -r
-AR= ar cruv
+AR= ar cru
RANLIB= ranlib
INSTALL= install
+INSTALL_EXEC=
+INSTALL_LIB=-o bin -g bin
+THREADED= threaded
-SRCS= ns_parse.c ns_print.c ns_netint.c ns_ttl.c ns_name.c
+SRCS= ns_parse.c ns_print.c ns_netint.c ns_ttl.c ns_name.c \
+ ns_sign.c ns_verify.c ns_date.c ns_samedomain.c
-OBJS= ns_parse.${O} ns_print.${O} ns_netint.${O} ns_ttl.${O} ns_name.${O}
+OBJS= ns_parse.${O} ns_print.${O} ns_netint.${O} ns_ttl.${O} ns_name.${O} \
+ ns_sign.${O} ns_verify.${O} ns_date.${O} ns_samedomain.${O}
-all: ${LIBBIND}
+all: ${LIBBIND}
${LIBBIND}: ${OBJS}
+ ( cd ${THREADED} ; \
+ ${AR} ${LIBBINDR} ${ARPREF} ${OBJS} ${ARSUFF} ; \
+ ${RANLIB} ${LIBBINDR} )
${AR} ${LIBBIND} ${ARPREF} ${OBJS} ${ARSUFF}
${RANLIB} ${LIBBIND}
.c.${O}:
- ${CC} ${CPPFLAGS} ${CFLAGS} -c $*.c
- -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} && ${LDS} mv a.out $*.${O}
+ if test ! -d ${THREADED} ; then mkdir ${THREADED} ; fi
+ ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
+ -o ${THREADED}/$*.${O}
+ -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} -o a.out && \
+ ${LDS} mv a.out ${THREADED}/$*.${O}
+ ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c
+ -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} -o a.out && \
+ ${LDS} mv a.out $*.${O}
distclean: clean
clean: FRC
rm -f .depend a.out core ${LIB} tags
rm -f *.${O} *.BAK *.CKP *~
+ rm -f ${THREADED}/*.${O}
+ -rmdir ${THREADED}
depend: FRC
mkdep -I${INCL} -I${PORTINCL} ${CPPFLAGS} ${SRCS}
diff --git a/contrib/bind/lib/nameser/ns_date.c b/contrib/bind/lib/nameser/ns_date.c
new file mode 100644
index 0000000..da593a5
--- /dev/null
+++ b/contrib/bind/lib/nameser/ns_date.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: ns_date.c,v 1.2 1999/10/13 16:39:35 vixie Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static int datepart(const char *, int, int, int, int *);
+
+/* Public. */
+
+/* Convert a date in ASCII into the number of seconds since
+ 1 January 1970 (GMT assumed). Format is yyyymmddhhmmss, all
+ digits required, no spaces allowed. */
+
+u_int32_t
+ns_datetosecs(const char *cp, int *errp) {
+ struct tm time;
+ u_int32_t result;
+ int mdays, i;
+ static const int days_per_month[12] =
+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+ if (strlen(cp) != 14) {
+ *errp = 1;
+ return (0);
+ }
+ *errp = 0;
+
+ memset(&time, 0, sizeof time);
+ time.tm_year = datepart(cp + 0, 4, 1990, 9999, errp) - 1900;
+ time.tm_mon = datepart(cp + 4, 2, 01, 12, errp) - 1;
+ time.tm_mday = datepart(cp + 6, 2, 01, 31, errp);
+ time.tm_hour = datepart(cp + 8, 2, 00, 23, errp);
+ time.tm_min = datepart(cp + 10, 2, 00, 59, errp);
+ time.tm_sec = datepart(cp + 12, 2, 00, 59, errp);
+ if (*errp) /* Any parse errors? */
+ return (0);
+
+ /*
+ * OK, now because timegm() is not available in all environments,
+ * we will do it by hand. Roll up sleeves, curse the gods, begin!
+ */
+
+#define SECS_PER_DAY ((u_int32_t)24*60*60)
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+ result = time.tm_sec; /* Seconds */
+ result += time.tm_min * 60; /* Minutes */
+ result += time.tm_hour * (60*60); /* Hours */
+ result += (time.tm_mday - 1) * SECS_PER_DAY; /* Days */
+
+ /* Months are trickier. Look without leaping, then leap */
+ mdays = 0;
+ for (i = 0; i < time.tm_mon; i++)
+ mdays += days_per_month[i];
+ result += mdays * SECS_PER_DAY; /* Months */
+ if (time.tm_mon > 1 && isleap(1900+time.tm_year))
+ result += SECS_PER_DAY; /* Add leapday for this year */
+
+ /* First figure years without leapdays, then add them in. */
+ /* The loop is slow, FIXME, but simple and accurate. */
+ result += (time.tm_year - 70) * (SECS_PER_DAY*365); /* Years */
+ for (i = 70; i < time.tm_year; i++)
+ if (isleap(1900+i))
+ result += SECS_PER_DAY; /* Add leapday for prev year */
+
+ return (result);
+}
+
+/* Private. */
+
+/*
+ * Parse part of a date. Set error flag if any error.
+ * Don't reset the flag if there is no error.
+ */
+static int
+datepart(const char *buf, int size, int min, int max, int *errp) {
+ int result = 0;
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (!isdigit(buf[i]))
+ *errp = 1;
+ result = (result * 10) + buf[i] - '0';
+ }
+ if (result < min)
+ *errp = 1;
+ if (result > max)
+ *errp = 1;
+ return (result);
+}
diff --git a/contrib/bind/lib/nameser/ns_name.c b/contrib/bind/lib/nameser/ns_name.c
index 86c0bbb..6bd668d 100644
--- a/contrib/bind/lib/nameser/ns_name.c
+++ b/contrib/bind/lib/nameser/ns_name.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ns_name.c,v 8.3 1997/04/24 22:10:54 vixie Exp $";
+static const char rcsid[] = "$Id: ns_name.c,v 8.12 1999/10/13 17:11:23 vixie Exp $";
#endif
#include "port_before.h"
@@ -29,12 +29,13 @@ static char rcsid[] = "$Id: ns_name.c,v 8.3 1997/04/24 22:10:54 vixie Exp $";
#include <errno.h>
#include <resolv.h>
#include <string.h>
+#include <ctype.h>
#include "port_after.h"
/* Data. */
-static char digits[] = "0123456789";
+static const char digits[] = "0123456789";
/* Forward. */
@@ -199,7 +200,7 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
}
return (1);
}
- if (c == 0) {
+ if (c == 0 || *src == '.') {
errno = EMSGSIZE;
return (-1);
}
@@ -237,6 +238,49 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
}
/*
+ * ns_name_ntol(src, dst, dstsiz)
+ * Convert a network strings labels into all lowercase.
+ * return:
+ * Number of bytes written to buffer, or -1 (with errno set)
+ * notes:
+ * Enforces label and domain length limits.
+ */
+
+int
+ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
+ const u_char *cp;
+ u_char *dn, *eom;
+ u_char c;
+ u_int n;
+
+ cp = src;
+ dn = dst;
+ eom = dst + dstsiz;
+
+ while ((n = *cp++) != 0) {
+ if ((n & NS_CMPRSFLGS) != 0) {
+ /* Some kind of compression pointer. */
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ *dn++ = n;
+ if (dn + n >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ for ((void)NULL; n > 0; n--) {
+ c = *cp++;
+ if (isupper(c))
+ *dn++ = tolower(c);
+ else
+ *dn++ = c;
+ }
+ }
+ *dn++ = '\0';
+ return (dn - dst);
+}
+
+/*
* ns_name_unpack(msg, eom, src, dst, dstsiz)
* Unpack a domain name from a message, source may be compressed.
* return:
@@ -248,7 +292,7 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
{
const u_char *srcp, *dstlim;
u_char *dstp;
- int n, c, len, checked;
+ int n, len, checked;
len = -1;
checked = 0;
@@ -366,6 +410,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
srcp += n + 1;
} while (n != 0);
+ /* from here on we need to reset compression pointer array on error */
srcp = src;
do {
/* Look to see if we can use pointers. */
@@ -375,8 +420,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
(const u_char * const *)lpp);
if (l >= 0) {
if (dstp + 1 >= eob) {
- errno = EMSGSIZE;
- return (-1);
+ goto cleanup;
}
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
*dstp++ = l % 256;
@@ -391,12 +435,10 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
}
/* copy label to buffer */
if (n & NS_CMPRSFLGS) { /* Should not happen. */
- errno = EMSGSIZE;
- return (-1);
+ goto cleanup;
}
if (dstp + 1 + n >= eob) {
- errno = EMSGSIZE;
- return (-1);
+ goto cleanup;
}
memcpy(dstp, srcp, n + 1);
srcp += n + 1;
@@ -404,6 +446,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
} while (n != 0);
if (dstp > eob) {
+cleanup:
if (msg != NULL)
*lpp = NULL;
errno = EMSGSIZE;
diff --git a/contrib/bind/lib/nameser/ns_netint.c b/contrib/bind/lib/nameser/ns_netint.c
index 1f640a5..030a2d0 100644
--- a/contrib/bind/lib/nameser/ns_netint.c
+++ b/contrib/bind/lib/nameser/ns_netint.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,21 +16,19 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ns_netint.c,v 8.1 1996/11/18 09:09:57 vixie Exp $";
+static const char rcsid[] = "$Id: ns_netint.c,v 8.4 1999/10/13 16:39:35 vixie Exp $";
#endif
/* Import. */
#include "port_before.h"
-/*#include <sys/types.h>*/
-/*#include <sys/socket.h>*/
-
-/*#include <netinet/in.h>*/
#include <arpa/nameser.h>
#include "port_after.h"
+/* Public. */
+
u_int
ns_get16(const u_char *src) {
u_int dst;
diff --git a/contrib/bind/lib/nameser/ns_parse.c b/contrib/bind/lib/nameser/ns_parse.c
index 800ea19..35f7f40 100644
--- a/contrib/bind/lib/nameser/ns_parse.c
+++ b/contrib/bind/lib/nameser/ns_parse.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,9 +16,11 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ns_parse.c,v 8.8 1998/02/17 17:20:33 vixie Exp $";
+static const char rcsid[] = "$Id: ns_parse.c,v 8.13 1999/10/13 16:39:35 vixie Exp $";
#endif
+/* Import. */
+
#include "port_before.h"
#include <sys/types.h>
@@ -32,6 +34,16 @@ static char rcsid[] = "$Id: ns_parse.c,v 8.8 1998/02/17 17:20:33 vixie Exp $";
#include "port_after.h"
+/* Forward. */
+
+static void setsection(ns_msg *msg, ns_sect sect);
+
+/* Macros. */
+
+#define RETERR(err) do { errno = (err); return (-1); } while (0)
+
+/* Public. */
+
/* These need to be in the same order as the nres.h:ns_flag enum. */
struct _ns_flagdata _ns_flagdata[16] = {
{ 0x8000, 15 }, /* qr. */
@@ -52,8 +64,8 @@ struct _ns_flagdata _ns_flagdata[16] = {
{ 0x0000, 0 }, /* expansion (6/6). */
};
-static int
-skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+int
+ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
const u_char *optr = ptr;
for ((void)NULL; count > 0; count--) {
@@ -61,24 +73,19 @@ skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
b = dn_skipname(ptr, eom);
if (b < 0)
- goto emsgsize;
+ RETERR(EMSGSIZE);
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
if (section != ns_s_qd) {
- if (ptr + NS_INT32SZ > eom)
- goto emsgsize;
+ if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
+ RETERR(EMSGSIZE);
ptr += NS_INT32SZ/*TTL*/;
- if (ptr + NS_INT16SZ > eom)
- goto emsgsize;
NS_GET16(rdlength, ptr);
ptr += rdlength/*RData*/;
}
}
if (ptr > eom)
- goto emsgsize;
+ RETERR(EMSGSIZE);
return (ptr - optr);
- emsgsize:
- errno = EMSGSIZE;
- return (-1);
}
int
@@ -90,22 +97,22 @@ ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
handle->_msg = msg;
handle->_eom = eom;
if (msg + NS_INT16SZ > eom)
- goto emsgsize;
+ RETERR(EMSGSIZE);
NS_GET16(handle->_id, msg);
if (msg + NS_INT16SZ > eom)
- goto emsgsize;
+ RETERR(EMSGSIZE);
NS_GET16(handle->_flags, msg);
for (i = 0; i < ns_s_max; i++) {
if (msg + NS_INT16SZ > eom)
- goto emsgsize;
+ RETERR(EMSGSIZE);
NS_GET16(handle->_counts[i], msg);
}
for (i = 0; i < ns_s_max; i++)
if (handle->_counts[i] == 0)
handle->_sections[i] = NULL;
else {
- int b = skiprr(msg, eom, (ns_sect)i,
- handle->_counts[i]);
+ int b = ns_skiprr(msg, eom, (ns_sect)i,
+ handle->_counts[i]);
if (b < 0)
return (-1);
@@ -113,14 +120,9 @@ ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
msg += b;
}
if (msg != eom)
- goto emsgsize;
- handle->_sect = ns_s_max;
- handle->_rrnum = -1;
- handle->_ptr = NULL;
+ RETERR(EMSGSIZE);
+ setsection(handle, ns_s_max);
return (0);
- emsgsize:
- errno = EMSGSIZE;
- return (-1);
}
int
@@ -129,29 +131,26 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
/* Make section right. */
if (section < 0 || section >= ns_s_max)
- goto enodev;
- if ((int)section != (int)handle->_sect) {
- handle->_sect = section;
- handle->_rrnum = 0;
- handle->_ptr = handle->_sections[(int)section];
- }
+ RETERR(ENODEV);
+ if (section != handle->_sect)
+ setsection(handle, section);
/* Make rrnum right. */
if (rrnum == -1)
rrnum = handle->_rrnum;
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
- goto enodev;
- if (rrnum < handle->_rrnum) {
- handle->_rrnum = 0;
- handle->_ptr = handle->_sections[(int)section];
+ RETERR(ENODEV);
+ if (rrnum < handle->_rrnum)
+ setsection(handle, section);
+ if (rrnum > handle->_rrnum) {
+ b = ns_skiprr(handle->_ptr, handle->_eom, section,
+ rrnum - handle->_rrnum);
+
+ if (b < 0)
+ return (-1);
+ handle->_ptr += b;
+ handle->_rrnum = rrnum;
}
-
- b = skiprr(handle->_msg, handle->_eom, section,
- rrnum - handle->_rrnum);
- if (b < 0)
- return (-1);
- handle->_ptr += b;
- handle->_rrnum = rrnum;
/* Do the parse. */
b = dn_expand(handle->_msg, handle->_eom,
@@ -159,36 +158,41 @@ ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
if (b < 0)
return (-1);
handle->_ptr += b;
- if (handle->_ptr + NS_INT16SZ > handle->_eom)
- goto emsgsize;
+ if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
+ RETERR(EMSGSIZE);
NS_GET16(rr->type, handle->_ptr);
- if (handle->_ptr + NS_INT16SZ > handle->_eom)
- goto emsgsize;
- NS_GET16(rr->class, handle->_ptr);
+ NS_GET16(rr->rr_class, handle->_ptr);
if (section == ns_s_qd) {
rr->ttl = 0;
rr->rdlength = 0;
rr->rdata = NULL;
} else {
- if (handle->_ptr + NS_INT32SZ > handle->_eom)
- goto emsgsize;
+ if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
+ RETERR(EMSGSIZE);
NS_GET32(rr->ttl, handle->_ptr);
- if (handle->_ptr + NS_INT16SZ > handle->_eom)
- goto emsgsize;
NS_GET16(rr->rdlength, handle->_ptr);
if (handle->_ptr + rr->rdlength > handle->_eom)
- goto emsgsize;
+ RETERR(EMSGSIZE);
rr->rdata = handle->_ptr;
handle->_ptr += rr->rdlength;
}
- handle->_rrnum++;
+ if (++handle->_rrnum > handle->_counts[(int)section])
+ setsection(handle, (ns_sect)((int)section + 1));
/* All done. */
return (0);
- enodev:
- errno = ENODEV;
- return (-1);
- emsgsize:
- errno = EMSGSIZE;
- return (-1);
+}
+
+/* Private. */
+
+static void
+setsection(ns_msg *msg, ns_sect sect) {
+ msg->_sect = sect;
+ if (sect == ns_s_max) {
+ msg->_rrnum = -1;
+ msg->_ptr = NULL;
+ } else {
+ msg->_rrnum = 0;
+ msg->_ptr = msg->_sections[(int)sect];
+ }
}
diff --git a/contrib/bind/lib/nameser/ns_print.c b/contrib/bind/lib/nameser/ns_print.c
index 8ab4766..93f1e91 100644
--- a/contrib/bind/lib/nameser/ns_print.c
+++ b/contrib/bind/lib/nameser/ns_print.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ns_print.c,v 8.4 1998/02/13 01:16:37 halley Exp $";
+static const char rcsid[] = "$Id: ns_print.c,v 8.17 1999/10/19 02:06:54 gson Exp $";
#endif
/* Import. */
@@ -30,7 +30,7 @@ static char rcsid[] = "$Id: ns_print.c,v 8.4 1998/02/13 01:16:37 halley Exp $";
#include <arpa/nameser.h>
#include <arpa/inet.h>
-#include <assert.h>
+#include <isc/assertions.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
@@ -58,6 +58,10 @@ static int addstr(const char *src, size_t len,
static int addtab(size_t len, size_t target, int spaced,
char **buf, size_t *buflen);
+/* Proto. */
+
+u_int16_t dst_s_dns_key_id(const u_char *, const int);
+
/* Macros. */
#define T(x) \
@@ -115,7 +119,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
/*
* Owner.
*/
- if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
+ if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
T(addstr("\t\t\t", 3, &buf, &buflen));
} else {
len = prune_origin(name, origin);
@@ -171,7 +175,11 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
rdata += len;
T(addstr(" ", 1, &buf, &buflen));
- /* Second word. */
+
+ /* Second word, optional in ISDN records. */
+ if (type == ns_t_isdn && rdata == edata)
+ break;
+
T(len = charstr(rdata, edata, &buf, &buflen));
if (len == 0)
goto formerr;
@@ -439,7 +447,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
case ns_t_key: {
char base64_key[NS_MD5RSA_MAX_BASE64];
- u_int keyflags, protocol, algorithm;
+ u_int keyflags, protocol, algorithm, key_id;
const char *leader;
int n;
@@ -447,6 +455,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
goto formerr;
/* Key flags, Protocol, Algorithm. */
+ key_id = dst_s_dns_key_id(rdata, edata-rdata);
keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
protocol = *rdata++;
algorithm = *rdata++;
@@ -472,6 +481,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
}
if (len > 15)
T(addstr(" )", 2, &buf, &buflen));
+ n = SPRINTF((tmp, " ; key_tag= %u", key_id));
+ T(addstr(tmp, n, &buf, &buflen));
break;
}
@@ -491,10 +502,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
algorithm = *rdata++;
labels = *rdata++;
t = ns_get32(rdata); rdata += NS_INT32SZ;
- len = SPRINTF((tmp, " %s %d %lu ",
- p_type(type), algorithm, t));
+ len = SPRINTF((tmp, "%s %d %d %lu ",
+ p_type(type), algorithm, labels, t));
T(addstr(tmp, len, &buf, &buflen));
- if (labels != (u_int)dn_count_labels(name))
+ if (labels > (u_int)dn_count_labels(name))
goto formerr;
/* Signature expiry. */
@@ -533,7 +544,6 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
}
if (len > 15)
T(addstr(" )", 2, &buf, &buflen));
-
break;
}
@@ -553,6 +563,63 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
break;
}
+ case ns_t_cert: {
+ u_int c_type, key_tag, alg;
+ int n, siz;
+ char base64_cert[8192], *leader, tmp[40];
+
+ c_type = ns_get16(rdata); rdata += NS_INT16SZ;
+ key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
+ alg = (u_int) *rdata++;
+
+ len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
+ T(addstr(tmp, len, &buf, &buflen));
+ siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
+ if (siz > sizeof(base64_cert) * 3/4) {
+ char *str = "record too long to print";
+ T(addstr(str, strlen(str), &buf, &buflen));
+ }
+ else {
+ len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
+
+ if (len < 0)
+ goto formerr;
+ else if (len > 15) {
+ T(addstr(" (", 2, &buf, &buflen));
+ leader = "\n\t\t";
+ spaced = 0;
+ }
+ else
+ leader = " ";
+
+ for (n = 0; n < len; n += 48) {
+ T(addstr(leader, strlen(leader),
+ &buf, &buflen));
+ T(addstr(base64_cert + n, MIN(len - n, 48),
+ &buf, &buflen));
+ }
+ if (len > 15)
+ T(addstr(" )", 2, &buf, &buflen));
+ }
+ break;
+ }
+
+ case ns_t_tsig: {
+ /* BEW - need to complete this */
+ int n;
+
+ T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
+ T(addstr(" ", 1, &buf, &buflen));
+ rdata += 8; /* time */
+ n = ns_get16(rdata); rdata += INT16SZ;
+ rdata += n; /* sig */
+ n = ns_get16(rdata); rdata += INT16SZ; /* original id */
+ sprintf(buf, "%d", ns_get16(rdata));
+ rdata += INT16SZ;
+ addlen(strlen(buf), &buf, &buflen);
+ break;
+ }
+
default:
comment = "unknown RR type";
goto hexify;
@@ -608,7 +675,7 @@ prune_origin(const char *name, const char *origin) {
const char *oname = name;
while (*name != '\0') {
- if (origin != NULL && strcasecmp(name, origin) == 0)
+ if (origin != NULL && ns_samename(name, origin) == 1)
return (name - oname - (name > oname));
while (*name != '\0') {
if (*name == '\\') {
@@ -712,14 +779,14 @@ addname(const u_char *msg, size_t msglen,
static void
addlen(size_t len, char **buf, size_t *buflen) {
- assert(len <= *buflen);
+ INSIST(len <= *buflen);
*buf += len;
*buflen -= len;
}
static int
addstr(const char *src, size_t len, char **buf, size_t *buflen) {
- if (len > *buflen) {
+ if (len >= *buflen) {
errno = ENOSPC;
return (-1);
}
diff --git a/contrib/bind/lib/nameser/ns_samedomain.c b/contrib/bind/lib/nameser/ns_samedomain.c
new file mode 100644
index 0000000..c847924
--- /dev/null
+++ b/contrib/bind/lib/nameser/ns_samedomain.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 1995,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 vixie Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <string.h>
+
+#include "port_after.h"
+
+/*
+ * int
+ * ns_samedomain(a, b)
+ * Check whether a name belongs to a domain.
+ * Inputs:
+ * a - the domain whose ancestory is being verified
+ * b - the potential ancestor we're checking against
+ * Return:
+ * boolean - is a at or below b?
+ * Notes:
+ * Trailing dots are first removed from name and domain.
+ * Always compare complete subdomains, not only whether the
+ * domain name is the trailing string of the given name.
+ *
+ * "host.foobar.top" lies in "foobar.top" and in "top" and in ""
+ * but NOT in "bar.top"
+ */
+
+int
+ns_samedomain(const char *a, const char *b) {
+ size_t la, lb;
+ int diff, i, escaped;
+ const char *cp;
+
+ la = strlen(a);
+ lb = strlen(b);
+
+ /* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
+ if (la != 0 && a[la - 1] == '.') {
+ escaped = 0;
+ /* Note this loop doesn't get executed if la==1. */
+ for (i = la - 2; i >= 0; i--)
+ if (a[i] == '\\') {
+ if (escaped)
+ escaped = 0;
+ else
+ escaped = 1;
+ } else
+ break;
+ if (!escaped)
+ la--;
+ }
+
+ /* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
+ if (lb != 0 && b[lb - 1] == '.') {
+ escaped = 0;
+ /* note this loop doesn't get executed if lb==1 */
+ for (i = lb - 2; i >= 0; i--)
+ if (b[i] == '\\') {
+ if (escaped)
+ escaped = 0;
+ else
+ escaped = 1;
+ } else
+ break;
+ if (!escaped)
+ lb--;
+ }
+
+ /* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
+ if (lb == 0)
+ return (1);
+
+ /* 'b' longer than 'a' means 'a' can't be in 'b'. */
+ if (lb > la)
+ return (0);
+
+ /* 'a' and 'b' being equal at this point indicates sameness. */
+ if (lb == la)
+ return (strncasecmp(a, b, lb) == 0);
+
+ /* Ok, we know la > lb. */
+
+ diff = la - lb;
+
+ /*
+ * If 'a' is only 1 character longer than 'b', then it can't be
+ * a subdomain of 'b' (because of the need for the '.' label
+ * separator).
+ */
+ if (diff < 2)
+ return (0);
+
+ /*
+ * If the character before the last 'lb' characters of 'b'
+ * isn't '.', then it can't be a match (this lets us avoid
+ * having "foobar.com" match "bar.com").
+ */
+ if (a[diff - 1] != '.')
+ return (0);
+
+ /*
+ * We're not sure about that '.', however. It could be escaped
+ * and thus not a really a label separator.
+ */
+ escaped = 0;
+ for (i = diff - 2; i >= 0; i--)
+ if (a[i] == '\\')
+ if (escaped)
+ escaped = 0;
+ else
+ escaped = 1;
+ else
+ break;
+ if (escaped)
+ return (0);
+
+ /* Now compare aligned trailing substring. */
+ cp = a + diff;
+ return (strncasecmp(cp, b, lb) == 0);
+}
+
+/*
+ * int
+ * ns_subdomain(a, b)
+ * is "a" a subdomain of "b"?
+ */
+int
+ns_subdomain(const char *a, const char *b) {
+ return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
+}
+
+/*
+ * int
+ * ns_makecanon(src, dst, dstsize)
+ * make a canonical copy of domain name "src"
+ * notes:
+ * foo -> foo.
+ * foo. -> foo.
+ * foo.. -> foo.
+ * foo\. -> foo\..
+ * foo\\. -> foo\\.
+ */
+
+int
+ns_makecanon(const char *src, char *dst, size_t dstsize) {
+ size_t n = strlen(src);
+
+ if (n + sizeof "." > dstsize) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
+ strcpy(dst, src);
+ while (n > 0 && dst[n - 1] == '.') /* Ends in "." */
+ if (n > 1 && dst[n - 2] == '\\' && /* Ends in "\." */
+ (n < 2 || dst[n - 3] != '\\')) /* But not "\\." */
+ break;
+ else
+ dst[--n] = '\0';
+ dst[n++] = '.';
+ dst[n] = '\0';
+ return (0);
+}
+
+/*
+ * int
+ * ns_samename(a, b)
+ * determine whether domain name "a" is the same as domain name "b"
+ * return:
+ * -1 on error
+ * 0 if names differ
+ * 1 if names are the same
+ */
+
+int
+ns_samename(const char *a, const char *b) {
+ char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
+
+ if (ns_makecanon(a, ta, sizeof ta) < 0 ||
+ ns_makecanon(b, tb, sizeof tb) < 0)
+ return (-1);
+ if (strcasecmp(ta, tb) == 0)
+ return (1);
+ else
+ return (0);
+}
diff --git a/contrib/bind/lib/nameser/ns_sign.c b/contrib/bind/lib/nameser/ns_sign.c
new file mode 100644
index 0000000..75af894
--- /dev/null
+++ b/contrib/bind/lib/nameser/ns_sign.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 1999 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: ns_sign.c,v 8.8 1999/10/13 16:39:36 vixie Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+#include "fd_setsize.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <isc/dst.h>
+
+#include "port_after.h"
+
+#define BOUNDS_CHECK(ptr, count) \
+ do { \
+ if ((ptr) + (count) > eob) { \
+ errno = EMSGSIZE; \
+ return(NS_TSIG_ERROR_NO_SPACE); \
+ } \
+ } while (0)
+
+/* ns_sign
+ * Parameters:
+ * msg message to be sent
+ * msglen input - length of message
+ * output - length of signed message
+ * msgsize length of buffer containing message
+ * error value to put in the error field
+ * key tsig key used for signing
+ * querysig (response), the signature in the query
+ * querysiglen (response), the length of the signature in the query
+ * sig a buffer to hold the generated signature
+ * siglen input - length of signature buffer
+ * output - length of signature
+ *
+ * Errors:
+ * - bad input data (-1)
+ * - bad key / sign failed (-BADKEY)
+ * - not enough space (NS_TSIG_ERROR_NO_SPACE)
+ */
+int
+ns_sign(u_char *msg, int *msglen, int msgsize, int error, void *k,
+ const u_char *querysig, int querysiglen, u_char *sig, int *siglen,
+ time_t in_timesigned)
+{
+ HEADER *hp = (HEADER *)msg;
+ DST_KEY *key = (DST_KEY *)k;
+ u_char *cp = msg + *msglen, *eob = msg + msgsize;
+ u_char *lenp;
+ u_char *name, *alg;
+ int n;
+ time_t timesigned;
+
+ dst_init();
+ if (msg == NULL || msglen == NULL || sig == NULL || siglen == NULL)
+ return (-1);
+
+ /* Name. */
+ if (key != NULL && error != ns_r_badsig && error != ns_r_badkey)
+ n = dn_comp(key->dk_key_name, cp, eob - cp, NULL, NULL);
+ else
+ n = dn_comp("", cp, eob - cp, NULL, NULL);
+ if (n < 0)
+ return (NS_TSIG_ERROR_NO_SPACE);
+ name = cp;
+ cp += n;
+
+ /* Type, class, ttl, length (not filled in yet). */
+ BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
+ PUTSHORT(ns_t_tsig, cp);
+ PUTSHORT(ns_c_any, cp);
+ PUTLONG(0, cp); /* TTL */
+ lenp = cp;
+ cp += 2;
+
+ /* Alg. */
+ if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
+ if (key->dk_alg != KEY_HMAC_MD5)
+ return (-ns_r_badkey);
+ n = dn_comp(NS_TSIG_ALG_HMAC_MD5, cp, eob - cp, NULL, NULL);
+ }
+ else
+ n = dn_comp("", cp, eob - cp, NULL, NULL);
+ if (n < 0)
+ return (NS_TSIG_ERROR_NO_SPACE);
+ alg = cp;
+ cp += n;
+
+ /* Time. */
+ BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
+ PUTSHORT(0, cp);
+ timesigned = time(NULL);
+ if (error != ns_r_badtime)
+ PUTLONG(timesigned, cp);
+ else
+ PUTLONG(in_timesigned, cp);
+ PUTSHORT(NS_TSIG_FUDGE, cp);
+
+ /* Compute the signature. */
+ if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
+ void *ctx;
+ u_char buf[MAXDNAME], *cp2;
+ int n;
+
+ dst_sign_data(SIG_MODE_INIT, key, &ctx, NULL, 0, NULL, 0);
+
+ /* Digest the query signature, if this is a response. */
+ if (querysiglen > 0 && querysig != NULL) {
+ u_int16_t len_n = htons(querysiglen);
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
+ (u_char *)&len_n, INT16SZ, NULL, 0);
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx,
+ querysig, querysiglen, NULL, 0);
+ }
+
+ /* Digest the message. */
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx, msg, *msglen,
+ NULL, 0);
+
+ /* Digest the key name. */
+ n = ns_name_ntol(name, buf, sizeof(buf));
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);
+
+ /* Digest the class and TTL. */
+ cp2 = buf;
+ PUTSHORT(ns_c_any, cp2);
+ PUTLONG(0, cp2);
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, cp2-buf,
+ NULL, 0);
+
+ /* Digest the algorithm. */
+ n = ns_name_ntol(alg, buf, sizeof(buf));
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);
+
+ /* Digest the time signed, fudge, error, and other data */
+ cp2 = buf;
+ PUTSHORT(0, cp2); /* Top 16 bits of time */
+ if (error != ns_r_badtime)
+ PUTLONG(timesigned, cp2);
+ else
+ PUTLONG(in_timesigned, cp2);
+ PUTSHORT(NS_TSIG_FUDGE, cp2);
+ PUTSHORT(error, cp2); /* Error */
+ if (error != ns_r_badtime)
+ PUTSHORT(0, cp2); /* Other data length */
+ else {
+ PUTSHORT(INT16SZ+INT32SZ, cp2); /* Other data length */
+ PUTSHORT(0, cp2); /* Top 16 bits of time */
+ PUTLONG(timesigned, cp2);
+ }
+ dst_sign_data(SIG_MODE_UPDATE, key, &ctx, buf, cp2-buf,
+ NULL, 0);
+
+ n = dst_sign_data(SIG_MODE_FINAL, key, &ctx, NULL, 0,
+ sig, *siglen);
+ if (n < 0)
+ return (-ns_r_badkey);
+ *siglen = n;
+ } else
+ *siglen = 0;
+
+ /* Add the signature. */
+ BOUNDS_CHECK(cp, INT16SZ + (*siglen));
+ PUTSHORT(*siglen, cp);
+ memcpy(cp, sig, *siglen);
+ cp += (*siglen);
+
+ /* The original message ID & error. */
+ BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
+ PUTSHORT(ntohs(hp->id), cp); /* already in network order */
+ PUTSHORT(error, cp);
+
+ /* Other data. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ if (error != ns_r_badtime)
+ PUTSHORT(0, cp); /* Other data length */
+ else {
+ PUTSHORT(INT16SZ+INT32SZ, cp); /* Other data length */
+ BOUNDS_CHECK(cp, INT32SZ+INT16SZ);
+ PUTSHORT(0, cp); /* Top 16 bits of time */
+ PUTLONG(timesigned, cp);
+ }
+
+ /* Go back and fill in the length. */
+ PUTSHORT(cp - lenp - INT16SZ, lenp);
+
+ hp->arcount = htons(ntohs(hp->arcount) + 1);
+ *msglen = (cp - msg);
+ return (0);
+}
+
+int
+ns_sign_tcp_init(void *k, const u_char *querysig, int querysiglen,
+ ns_tcp_tsig_state *state)
+{
+ dst_init();
+ if (state == NULL || k == NULL || querysig == NULL || querysiglen < 0)
+ return (-1);
+ state->counter = -1;
+ state->key = k;
+ if (state->key->dk_alg != KEY_HMAC_MD5)
+ return (-ns_r_badkey);
+ if (querysiglen > sizeof(state->sig))
+ return (-1);
+ memcpy(state->sig, querysig, querysiglen);
+ state->siglen = querysiglen;
+ return (0);
+}
+
+int
+ns_sign_tcp(u_char *msg, int *msglen, int msgsize, int error,
+ ns_tcp_tsig_state *state, int done)
+{
+ u_char *cp, *eob, *lenp;
+ u_char buf[MAXDNAME], *cp2;
+ HEADER *hp = (HEADER *)msg;
+ time_t timesigned;
+ int n;
+
+ if (msg == NULL || msglen == NULL || state == NULL)
+ return (-1);
+
+ state->counter++;
+ if (state->counter == 0)
+ return (ns_sign(msg, msglen, msgsize, error, state->key,
+ state->sig, state->siglen,
+ state->sig, &state->siglen, 0));
+
+ if (state->siglen > 0) {
+ u_int16_t siglen_n = htons(state->siglen);
+ dst_sign_data(SIG_MODE_INIT, state->key, &state->ctx,
+ NULL, 0, NULL, 0);
+ dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ (u_char *)&siglen_n, INT16SZ, NULL, 0);
+ dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ state->sig, state->siglen, NULL, 0);
+ state->siglen = 0;
+ }
+
+ dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx, msg, *msglen,
+ NULL, 0);
+
+ if (done == 0 && (state->counter % 100 != 0))
+ return (0);
+
+ cp = msg + *msglen;
+ eob = msg + msgsize;
+
+ /* Name. */
+ n = dn_comp(state->key->dk_key_name, cp, eob - cp, NULL, NULL);
+ if (n < 0)
+ return (NS_TSIG_ERROR_NO_SPACE);
+ cp += n;
+
+ /* Type, class, ttl, length (not filled in yet). */
+ BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
+ PUTSHORT(ns_t_tsig, cp);
+ PUTSHORT(ns_c_any, cp);
+ PUTLONG(0, cp); /* TTL */
+ lenp = cp;
+ cp += 2;
+
+ /* Alg. */
+ n = dn_comp(NS_TSIG_ALG_HMAC_MD5, cp, eob - cp, NULL, NULL);
+ if (n < 0)
+ return (NS_TSIG_ERROR_NO_SPACE);
+ cp += n;
+
+ /* Time. */
+ BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
+ PUTSHORT(0, cp);
+ timesigned = time(NULL);
+ PUTLONG(timesigned, cp);
+ PUTSHORT(NS_TSIG_FUDGE, cp);
+
+ /*
+ * Compute the signature.
+ */
+
+ /* Digest the time signed and fudge. */
+ cp2 = buf;
+ PUTSHORT(0, cp2); /* Top 16 bits of time */
+ PUTLONG(timesigned, cp2);
+ PUTSHORT(NS_TSIG_FUDGE, cp2);
+
+ dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ buf, cp2 - buf, NULL, 0);
+
+ n = dst_sign_data(SIG_MODE_FINAL, state->key, &state->ctx, NULL, 0,
+ state->sig, sizeof(state->sig));
+ if (n < 0)
+ return (-ns_r_badkey);
+ state->siglen = n;
+
+ /* Add the signature. */
+ BOUNDS_CHECK(cp, INT16SZ + state->siglen);
+ PUTSHORT(state->siglen, cp);
+ memcpy(cp, state->sig, state->siglen);
+ cp += state->siglen;
+
+ /* The original message ID & error. */
+ BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
+ PUTSHORT(ntohs(hp->id), cp); /* already in network order */
+ PUTSHORT(error, cp);
+
+ /* Other data. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ PUTSHORT(0, cp);
+
+ /* Go back and fill in the length. */
+ PUTSHORT(cp - lenp - INT16SZ, lenp);
+
+ hp->arcount = htons(ntohs(hp->arcount) + 1);
+ *msglen = (cp - msg);
+ return (0);
+}
diff --git a/contrib/bind/lib/nameser/ns_ttl.c b/contrib/bind/lib/nameser/ns_ttl.c
index a71d3c7..67cd976 100644
--- a/contrib/bind/lib/nameser/ns_ttl.c
+++ b/contrib/bind/lib/nameser/ns_ttl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996 by Internet Software Consortium.
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Id: ns_ttl.c,v 8.5 1998/02/13 01:16:38 halley Exp $";
+static const char rcsid[] = "$Id: ns_ttl.c,v 8.8 1999/10/13 16:39:36 vixie Exp $";
#endif
/* Import. */
@@ -52,7 +52,7 @@ int
ns_format_ttl(u_long src, char *dst, size_t dstlen) {
char *odst = dst;
int secs, mins, hours, days, weeks, x;
- char tmp[50], *p;
+ char *p;
secs = src % 60; src /= 60;
mins = src % 60; src /= 60;
diff --git a/contrib/bind/lib/nameser/ns_verify.c b/contrib/bind/lib/nameser/ns_verify.c
new file mode 100644
index 0000000..316da13
--- /dev/null
+++ b/contrib/bind/lib/nameser/ns_verify.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 1999 by Internet Software Consortium, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef lint
+static const char rcsid[] = "$Id: ns_verify.c,v 8.11 1999/10/15 21:06:51 vixie Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+#include "fd_setsize.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <isc/dst.h>
+
+#include "port_after.h"
+
+/* Private. */
+
+#define BOUNDS_CHECK(ptr, count) \
+ do { \
+ if ((ptr) + (count) > eom) { \
+ return (NS_TSIG_ERROR_FORMERR); \
+ } \
+ } while (0)
+
+/* Public. */
+
+u_char *
+ns_find_tsig(u_char *msg, u_char *eom) {
+ HEADER *hp = (HEADER *)msg;
+ int n, type;
+ u_char *cp = msg, *start;
+
+ if (msg == NULL || eom == NULL || msg > eom)
+ return (NULL);
+
+ if (cp + HFIXEDSZ >= eom)
+ return (NULL);
+
+ if (hp->arcount == 0)
+ return (NULL);
+
+ cp += HFIXEDSZ;
+
+ n = ns_skiprr(cp, eom, ns_s_qd, ntohs(hp->qdcount));
+ if (n < 0)
+ return (NULL);
+ cp += n;
+
+ n = ns_skiprr(cp, eom, ns_s_an, ntohs(hp->ancount));
+ if (n < 0)
+ return (NULL);
+ cp += n;
+
+ n = ns_skiprr(cp, eom, ns_s_ns, ntohs(hp->nscount));
+ if (n < 0)
+ return (NULL);
+ cp += n;
+
+ n = ns_skiprr(cp, eom, ns_s_ar, ntohs(hp->arcount) - 1);
+ if (n < 0)
+ return (NULL);
+ cp += n;
+
+ start = cp;
+ n = dn_skipname(cp, eom);
+ if (n < 0)
+ return (NULL);
+ cp += n;
+ if (cp + INT16SZ >= eom)
+ return (NULL);
+
+ GETSHORT(type, cp);
+ if (type != ns_t_tsig)
+ return (NULL);
+ return (start);
+}
+
+/* ns_verify
+ * Parameters:
+ * statp res stuff
+ * msg received message
+ * msglen length of message
+ * key tsig key used for verifying.
+ * querysig (response), the signature in the query
+ * querysiglen (response), the length of the signature in the query
+ * sig (query), a buffer to hold the signature
+ * siglen (query), input - length of signature buffer
+ * output - length of signature
+ *
+ * Errors:
+ * - bad input (-1)
+ * - invalid dns message (NS_TSIG_ERROR_FORMERR)
+ * - TSIG is not present (NS_TSIG_ERROR_NO_TSIG)
+ * - key doesn't match (-ns_r_badkey)
+ * - TSIG verification fails with BADKEY (-ns_r_badkey)
+ * - TSIG verification fails with BADSIG (-ns_r_badsig)
+ * - TSIG verification fails with BADTIME (-ns_r_badtime)
+ * - TSIG verification succeeds, error set to BAKEY (ns_r_badkey)
+ * - TSIG verification succeeds, error set to BADSIG (ns_r_badsig)
+ * - TSIG verification succeeds, error set to BADTIME (ns_r_badtime)
+ */
+int
+ns_verify(u_char *msg, int *msglen, void *k,
+ const u_char *querysig, int querysiglen, u_char *sig, int *siglen,
+ time_t *timesigned, int nostrip)
+{
+ HEADER *hp = (HEADER *)msg;
+ DST_KEY *key = (DST_KEY *)k;
+ u_char *cp = msg, *eom;
+ char name[MAXDNAME], alg[MAXDNAME];
+ u_char *recstart, *rdatastart;
+ u_char *sigstart, *otherstart;
+ int n;
+ int error;
+ u_int16_t type, length;
+ u_int16_t fudge, sigfieldlen, id, otherfieldlen;
+
+ dst_init();
+ if (msg == NULL || msglen == NULL || *msglen < 0)
+ return (-1);
+
+ eom = msg + *msglen;
+
+ recstart = ns_find_tsig(msg, eom);
+ if (recstart == NULL)
+ return (NS_TSIG_ERROR_NO_TSIG);
+
+ cp = recstart;
+
+ /* Read the key name. */
+ n = dn_expand(msg, eom, cp, name, MAXDNAME);
+ if (n < 0)
+ return (NS_TSIG_ERROR_FORMERR);
+ cp += n;
+
+ /* Read the type. */
+ BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ);
+ GETSHORT(type, cp);
+ if (type != ns_t_tsig)
+ return (NS_TSIG_ERROR_NO_TSIG);
+
+ /* Skip the class and TTL, save the length. */
+ cp += INT16SZ + INT32SZ;
+ GETSHORT(length, cp);
+ if (eom - cp != length)
+ return (NS_TSIG_ERROR_FORMERR);
+
+ /* Read the algorithm name. */
+ rdatastart = cp;
+ n = dn_expand(msg, eom, cp, alg, MAXDNAME);
+ if (n < 0)
+ return (NS_TSIG_ERROR_FORMERR);
+ if (ns_samename(alg, NS_TSIG_ALG_HMAC_MD5) != 1)
+ return (-ns_r_badkey);
+ cp += n;
+
+ /* Read the time signed and fudge. */
+ BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
+ cp += INT16SZ;
+ GETLONG((*timesigned), cp);
+ GETSHORT(fudge, cp);
+
+ /* Read the signature. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ GETSHORT(sigfieldlen, cp);
+ BOUNDS_CHECK(cp, sigfieldlen);
+ sigstart = cp;
+ cp += sigfieldlen;
+
+ /* Read the original id and error. */
+ BOUNDS_CHECK(cp, 2*INT16SZ);
+ GETSHORT(id, cp);
+ GETSHORT(error, cp);
+
+ /* Parse the other data. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ GETSHORT(otherfieldlen, cp);
+ BOUNDS_CHECK(cp, otherfieldlen);
+ otherstart = cp;
+ cp += otherfieldlen;
+
+ if (cp != eom)
+ return (NS_TSIG_ERROR_FORMERR);
+
+ /* Verify that the key used is OK. */
+ if (key != NULL) {
+ if (key->dk_alg != KEY_HMAC_MD5)
+ return (-ns_r_badkey);
+ if (error != ns_r_badsig && error != ns_r_badkey) {
+ if (ns_samename(key->dk_key_name, name) != 1)
+ return (-ns_r_badkey);
+ }
+ }
+
+ hp->arcount = htons(ntohs(hp->arcount) - 1);
+
+ /*
+ * Do the verification.
+ */
+
+ if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) {
+ void *ctx;
+ u_char buf[MAXDNAME];
+
+ /* Digest the query signature, if this is a response. */
+ dst_verify_data(SIG_MODE_INIT, key, &ctx, NULL, 0, NULL, 0);
+ if (querysiglen > 0 && querysig != NULL) {
+ u_int16_t len_n = htons(querysiglen);
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx,
+ (u_char *)&len_n, INT16SZ, NULL, 0);
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx,
+ querysig, querysiglen, NULL, 0);
+ }
+
+ /* Digest the message. */
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx, msg, recstart - msg,
+ NULL, 0);
+
+ /* Digest the key name. */
+ n = ns_name_ntol(recstart, buf, sizeof(buf));
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);
+
+ /* Digest the class and TTL. */
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx,
+ recstart + dn_skipname(recstart, eom) + INT16SZ,
+ INT16SZ + INT32SZ, NULL, 0);
+
+ /* Digest the algorithm. */
+ n = ns_name_ntol(rdatastart, buf, sizeof(buf));
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0);
+
+ /* Digest the time signed and fudge. */
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx,
+ rdatastart + dn_skipname(rdatastart, eom),
+ INT16SZ + INT32SZ + INT16SZ, NULL, 0);
+
+ /* Digest the error and other data. */
+ dst_verify_data(SIG_MODE_UPDATE, key, &ctx,
+ otherstart - INT16SZ - INT16SZ,
+ otherfieldlen + INT16SZ + INT16SZ, NULL, 0);
+
+ n = dst_verify_data(SIG_MODE_FINAL, key, &ctx, NULL, 0,
+ sigstart, sigfieldlen);
+
+ if (n < 0)
+ return (-ns_r_badsig);
+
+ if (sig != NULL && siglen != NULL) {
+ if (*siglen < sigfieldlen)
+ return (NS_TSIG_ERROR_NO_SPACE);
+ memcpy(sig, sigstart, sigfieldlen);
+ *siglen = sigfieldlen;
+ }
+ } else {
+ if (sigfieldlen > 0)
+ return (NS_TSIG_ERROR_FORMERR);
+ if (sig != NULL && siglen != NULL)
+ *siglen = 0;
+ }
+
+ /* Reset the counter, since we still need to check for badtime. */
+ hp->arcount = htons(ntohs(hp->arcount) + 1);
+
+ /* Verify the time. */
+ if (abs((*timesigned) - time(NULL)) > fudge)
+ return (-ns_r_badtime);
+
+ if (nostrip == 0) {
+ *msglen = recstart - msg;
+ hp->arcount = htons(ntohs(hp->arcount) - 1);
+ }
+
+ if (error != NOERROR)
+ return (error);
+
+ return (0);
+}
+
+int
+ns_verify_tcp_init(void *k, const u_char *querysig, int querysiglen,
+ ns_tcp_tsig_state *state)
+{
+ dst_init();
+ if (state == NULL || k == NULL || querysig == NULL || querysiglen < 0)
+ return (-1);
+ state->counter = -1;
+ state->key = k;
+ if (state->key->dk_alg != KEY_HMAC_MD5)
+ return (-ns_r_badkey);
+ if (querysiglen > sizeof(state->sig))
+ return (-1);
+ memcpy(state->sig, querysig, querysiglen);
+ state->siglen = querysiglen;
+ return (0);
+}
+
+int
+ns_verify_tcp(u_char *msg, int *msglen, ns_tcp_tsig_state *state,
+ int required)
+{
+ HEADER *hp = (HEADER *)msg;
+ u_char *recstart, *rdatastart, *sigstart;
+ int sigfieldlen, otherfieldlen;
+ u_char *cp, *eom = msg + *msglen, *cp2;
+ char name[MAXDNAME], alg[MAXDNAME];
+ u_char buf[MAXDNAME];
+ int n, type, length, fudge, id, error;
+ time_t timesigned;
+
+ if (msg == NULL || msglen == NULL || state == NULL)
+ return (-1);
+
+ state->counter++;
+ if (state->counter == 0)
+ return (ns_verify(msg, msglen, state->key,
+ state->sig, state->siglen,
+ state->sig, &state->siglen, &timesigned, 0));
+
+ if (state->siglen > 0) {
+ u_int16_t siglen_n = htons(state->siglen);
+
+ dst_verify_data(SIG_MODE_INIT, state->key, &state->ctx,
+ NULL, 0, NULL, 0);
+ dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ (u_char *)&siglen_n, INT16SZ, NULL, 0);
+ dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ state->sig, state->siglen, NULL, 0);
+ state->siglen = 0;
+ }
+
+ cp = recstart = ns_find_tsig(msg, eom);
+
+ if (recstart == NULL) {
+ if (required)
+ return (NS_TSIG_ERROR_NO_TSIG);
+ dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ msg, *msglen, NULL, 0);
+ return (0);
+ }
+
+ hp->arcount = htons(ntohs(hp->arcount) - 1);
+ dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ msg, recstart - msg, NULL, 0);
+
+ /* Read the key name. */
+ n = dn_expand(msg, eom, cp, name, MAXDNAME);
+ if (n < 0)
+ return (NS_TSIG_ERROR_FORMERR);
+ cp += n;
+
+ /* Read the type. */
+ BOUNDS_CHECK(cp, 2*INT16SZ + INT32SZ + INT16SZ);
+ GETSHORT(type, cp);
+ if (type != ns_t_tsig)
+ return (NS_TSIG_ERROR_NO_TSIG);
+
+ /* Skip the class and TTL, save the length. */
+ cp += INT16SZ + INT32SZ;
+ GETSHORT(length, cp);
+ if (eom - cp != length)
+ return (NS_TSIG_ERROR_FORMERR);
+
+ /* Read the algorithm name. */
+ rdatastart = cp;
+ n = dn_expand(msg, eom, cp, alg, MAXDNAME);
+ if (n < 0)
+ return (NS_TSIG_ERROR_FORMERR);
+ if (ns_samename(alg, NS_TSIG_ALG_HMAC_MD5) != 1)
+ return (-ns_r_badkey);
+ cp += n;
+
+ /* Verify that the key used is OK. */
+ if ((ns_samename(state->key->dk_key_name, name) != 1 ||
+ state->key->dk_alg != KEY_HMAC_MD5))
+ return (-ns_r_badkey);
+
+ /* Read the time signed and fudge. */
+ BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
+ cp += INT16SZ;
+ GETLONG(timesigned, cp);
+ GETSHORT(fudge, cp);
+
+ /* Read the signature. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ GETSHORT(sigfieldlen, cp);
+ BOUNDS_CHECK(cp, sigfieldlen);
+ sigstart = cp;
+ cp += sigfieldlen;
+
+ /* Read the original id and error. */
+ BOUNDS_CHECK(cp, 2*INT16SZ);
+ GETSHORT(id, cp);
+ GETSHORT(error, cp);
+
+ /* Parse the other data. */
+ BOUNDS_CHECK(cp, INT16SZ);
+ GETSHORT(otherfieldlen, cp);
+ BOUNDS_CHECK(cp, otherfieldlen);
+ cp += otherfieldlen;
+
+ if (cp != eom)
+ return (NS_TSIG_ERROR_FORMERR);
+
+ /*
+ * Do the verification.
+ */
+
+ /* Digest the time signed and fudge. */
+ cp2 = buf;
+ PUTSHORT(0, cp2); /* Top 16 bits of time. */
+ PUTLONG(timesigned, cp2);
+ PUTSHORT(NS_TSIG_FUDGE, cp2);
+
+ dst_verify_data(SIG_MODE_UPDATE, state->key, &state->ctx,
+ buf, cp2 - buf, NULL, 0);
+
+ n = dst_verify_data(SIG_MODE_FINAL, state->key, &state->ctx, NULL, 0,
+ sigstart, sigfieldlen);
+ if (n < 0)
+ return (-ns_r_badsig);
+
+ if (sigfieldlen > sizeof(state->sig))
+ return (ns_r_badsig);
+
+ if (sigfieldlen > sizeof(state->sig))
+ return (NS_TSIG_ERROR_NO_SPACE);
+
+ memcpy(state->sig, sigstart, sigfieldlen);
+ state->siglen = sigfieldlen;
+
+ /* Verify the time. */
+ if (abs(timesigned - time(NULL)) > fudge)
+ return (-ns_r_badtime);
+
+ *msglen = recstart - msg;
+
+ if (error != NOERROR)
+ return (error);
+
+ return (0);
+}
OpenPOWER on IntegriCloud