Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-6]: src/dist/bind/bin/named-xfer Pull up revisions 1.5-1.6 (req...
details: https://anonhg.NetBSD.org/src/rev/3736fb17a7df
branches: netbsd-1-6
changeset: 528126:3736fb17a7df
user: lukem <lukem%NetBSD.org@localhost>
date: Fri Jun 28 11:29:19 2002 +0000
description:
Pull up revisions 1.5-1.6 (requested by itojun in ticket #387):
Update to BIND 8.3.3. Fixes buffer overrun in resolver code.
diffstat:
dist/bind/bin/named-xfer/named-xfer.c | 1178 ++++++++++++++------------------
1 files changed, 532 insertions(+), 646 deletions(-)
diffs (truncated from 1738 to 300 lines):
diff -r da602ddf0ace -r 3736fb17a7df dist/bind/bin/named-xfer/named-xfer.c
--- a/dist/bind/bin/named-xfer/named-xfer.c Fri Jun 28 11:29:07 2002 +0000
+++ b/dist/bind/bin/named-xfer/named-xfer.c Fri Jun 28 11:29:19 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: named-xfer.c,v 1.4 2001/05/17 22:59:41 itojun Exp $ */
+/* $NetBSD: named-xfer.c,v 1.4.2.1 2002/06/28 11:29:19 lukem Exp $ */
/*
* The original version of named-xfer by Kevin Dunlap.
@@ -132,7 +132,7 @@
#if !defined(lint) && !defined(SABER)
static const char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91";
-static const char rcsid[] = "Id: named-xfer.c,v 8.105.2.1 2001/04/26 02:56:09 marka Exp";
+static const char rcsid[] = "Id: named-xfer.c,v 8.121 2002/06/26 03:27:22 marka Exp";
#endif /* not lint */
#include "port_before.h"
@@ -217,7 +217,7 @@
writemsg(int, const u_char *, int);
static int ixfr_log(const u_char *msg, int len, int *delete,
FILE *file, struct sockaddr_in *sin,
- char *domain, u_int32_t *serial_no, int *);
+ u_int32_t *serial_no, int *);
static SIG_FN read_alarm(void);
static SIG_FN term_handler(void);
static const char *soa_zinfo(struct zoneinfo *, u_char *, u_char*),
@@ -290,7 +290,8 @@
return (1);
}
-void cleanup_for_exit(void) {
+static void
+cleanup_for_exit(void) {
#ifdef DEBUG
if (!debug)
#endif
@@ -324,7 +325,7 @@
struct in_addr axfr_src;
char *dbfile = NULL, *tracefile = NULL, *tm = NULL, *tsigfile = NULL;
char *ixfrfile = NULL;
- int dbfd, ddtd, result, c, ixfd;
+ int dbfd, ddtd, result, c, ixfd = -1;
u_int32_t serial_no = 0;
u_int port = htons(NAMESERVER_PORT);
struct stat statbuf;
@@ -497,12 +498,16 @@
if (!quiet)
syslog(LOG_ERR, "can't [f]chmod tmpfile (%s): %s\n",
tmpname, strerror(errno));
+ close(dbfd);
+ unlink(tmpname);
exit(XFER_FAIL);
}
if ((dbfp = fdopen(dbfd, "r+")) == NULL) {
perror(tmpname);
if (!quiet)
syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname);
+ close(dbfd);
+ unlink(tmpname);
exit(XFER_FAIL);
}
if (ixfrfile) {
@@ -549,9 +554,13 @@
#endif
{
perror(ddtfile);
+ close(ddtd);
+ unlink(ddtfile);
debug = 0;
} else if ((ddt = fdopen(ddtd, "w")) == NULL) {
perror(ddtfile);
+ close(ddtd);
+ unlink(ddtfile);
debug = 0;
} else
setvbuf(ddt, NULL, _IOLBF, 0);
@@ -743,6 +752,7 @@
default:
result = XFER_FAIL;
/* fall through */
+ case XFER_REFUSED:
case XFER_TIMEOUT:
case XFER_FAIL:
(void) unlink(tmpname);
@@ -753,7 +763,7 @@
return (0); /* Make gcc happy. */
}
-static char *UsageText[] = {
+static const char *UsageText[] = {
"\t-z zone_to_transfer\n",
"\t-f db_file\n",
"\t[-i ixfr_file]\n",
@@ -772,11 +782,11 @@
static void
usage(const char *msg) {
- char * const *line;
+ const char **line;
fprintf(stderr, "Usage error: %s\n", msg);
fprintf(stderr, "Usage: %s\n", ProgName);
- for (line = UsageText; *line; line++)
+ for (line = UsageText; *line; line++)
fputs(*line, stderr);
exit(XFER_FAIL);
}
@@ -855,6 +865,179 @@
char prev_dname[MAXDNAME] = { DEF_DNAME }; /* from previous record */
char prev_ns_dname[MAXDNAME] = { DEF_DNAME }; /* from most recent NS record */
+/*
+ * TSIG state
+ */
+static int tsig_signed;
+static ns_tcp_tsig_state tsig_state;
+
+static int
+make_query(int fd, struct zoneinfo *zp, int type, u_int32_t serial_no,
+ DST_KEY *tsig_key, u_char *buf, u_int bufsize)
+{
+ HEADER *hp;
+ u_char *cp;
+ int n, ret;
+ time_t timesigned = 0;
+
+ n = res_nmkquery(&res, QUERY, zp->z_origin, curclass,
+ type, NULL, 0, NULL, buf, bufsize);
+ if (n < 0) {
+ if (!quiet)
+ syslog(LOG_INFO, "zone %s: res_nmkquery %s failed",
+ p_type(query_type), zp->z_origin);
+ return (n);
+ }
+
+ if (type == T_IXFR) {
+ hp = (HEADER *) buf;
+ cp = buf;
+ dprintf(1, "len = %d\n", n);
+ hp->nscount = htons(1+ntohs(hp->nscount));
+ cp += n;
+ n = dn_comp(zp->z_origin, cp, bufsize - (cp - buf), NULL, NULL);
+ if (n < 0)
+ return (n);
+ cp += n;
+ if (cp + 3 * INT16SZ + 6 * INT32SZ + 2 > buf + bufsize)
+ return (-1);
+ PUTSHORT(T_SOA, cp); /* type */
+ PUTSHORT(C_IN, cp); /* class */
+ PUTLONG(0, cp); /* ttl */
+ PUTSHORT(22, cp); /* dlen */
+ *cp++ = 0; /* mname */
+ *cp++ = 0; /* rname */
+ PUTLONG(serial_no, cp);
+ PUTLONG(0xDEAD, cp); /* Refresh */
+ PUTLONG(0xBEEF, cp); /* Retry */
+ PUTLONG(0xABCD, cp); /* Expire */
+ PUTLONG(0x1776, cp); /* Min TTL */
+ n = cp - buf;
+ dprintf(1, "len = %d\n", cp-buf);
+ }
+
+ tsig_signed = 0;
+ if (tsig_key != NULL) {
+ int siglen;
+ u_char sig[64];
+
+ siglen = sizeof(sig);
+ ret = ns_sign(buf, &n, bufsize, NOERROR, tsig_key,
+ NULL, 0, sig, &siglen, timesigned);
+ if (ret == 0) {
+ tsig_signed = 1;
+ ns_verify_tcp_init(tsig_key, sig, siglen, &tsig_state);
+ }
+ }
+
+ if (debug)
+ res_pquery(&res, buf, n, ddt);
+
+ if (writemsg(fd, buf, n) < 0) {
+ syslog(LOG_INFO, "writemsg: %m");
+ return (-1);
+ }
+
+ return (n);
+}
+
+static u_int
+readandverify(int fd, u_char **bufp, u_int *bufsizep,
+ struct sockaddr_in *sin, char *z_origin, int sig_req)
+{
+ u_char *buf = *bufp;
+ u_char *newbuf;
+ u_int bufsize = *bufsizep;
+ u_int len;
+
+ if (netread(fd, (char *)buf, INT16SZ, XFER_TIMER) < 0)
+ return (0);
+
+ if ((len = ns_get16(buf)) == 0)
+ return (0);
+
+ if (len > bufsize) {
+ newbuf = realloc(buf, len);
+ if (newbuf == NULL) {
+ syslog(LOG_INFO, "realloc(%u) failed\n", len);
+ return (0);
+ }
+ *bufp = buf = newbuf;
+ *bufsizep = bufsize = len;
+ }
+
+ if (netread(fd, (char *)buf, len, XFER_TIMER) < 0)
+ return (0);
+
+#ifdef DEBUG
+ if (debug >= 3) {
+ (void)fprintf(ddt,"len = %d\n", len);
+ res_pquery(&res, buf, len, ddt);
+ }
+ if (fp)
+ res_pquery(&res, buf, len, fp);
+#endif
+
+ if (tsig_signed) {
+ int ret;
+
+ ret = ns_verify_tcp(buf, (int *)&len, &tsig_state, sig_req);
+ if (ret != 0) {
+ syslog(LOG_NOTICE, "%s [%s] %s %s: %s (%d)\n",
+ "TSIG verification from server",
+ inet_ntoa(sin->sin_addr), "zone", z_origin,
+ tsig_rcode(ret), ret);
+ return (0);
+ }
+ }
+
+ return (len);
+}
+
+static void
+print_comment(int s, struct sockaddr_in *sin, int check_serial,
+ u_int32_t serial_no, DST_KEY *tsig_key)
+{
+ struct sockaddr_in local;
+ ISC_SOCKLEN_T locallen;
+ const char *l, *nl;
+
+ gettime(&tt);
+ locallen = sizeof local;
+ if (getsockname(s, (struct sockaddr *)&local, &locallen) < 0)
+ memset(&local, 0, sizeof local);
+
+ for (l = Version; l; l = nl) {
+ size_t len;
+ if ((nl = strchr(l, '\n')) != NULL) {
+ len = nl - l;
+ nl = nl + 1;
+ } else {
+ len = strlen(l);
+ nl = NULL;
+ }
+ while (isspace((unsigned char) *l))
+ l++;
+ if (*l)
+ fprintf(dbfp, "; BIND version %.*s\n", (int)len, l);
+ }
+
+ fprintf(dbfp, check_serial ?
+ "; zone '%s' last serial %u\n" :
+ "; zone '%s' first transfer\n",
+ domain, serial_no);
+ fprintf(dbfp, "; from %s:%d",
+ inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ fprintf(dbfp, " (local %s) using %s at %s",
+ inet_ntoa(local.sin_addr), (methode == ISIXFR) ? "IXFR":"AXFR",
+ ctimel(tt.tv_sec));
+ if (tsig_signed != 0)
+ fprintf(dbfp, "; TSIG verified: key %s.\n",
+ tsig_key->dk_key_name);
+ else
+ fprintf(dbfp, "; NOT TSIG verified\n");
+}
+
static int
getzone(struct zoneinfo *zp, u_int32_t serial_no, int port) {
HEADER *hp;
@@ -863,34 +1046,31 @@
int was_ixfr = 0;
u_int cnt;
u_char *cp, *nmp, *eom, *tmp ;
- u_char *buf = NULL, *cpp = NULL;
+ u_char *buf = NULL;
u_char *bp;
u_int bufsize = 0;
u_char *buf2 = NULL;
u_int buf2size = 0;
char name2[MAXDNAME];
struct sockaddr_in sin;
Home |
Main Index |
Thread Index |
Old Index