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