summaryrefslogtreecommitdiffstats
path: root/contrib/bind/bin/named/db_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/bin/named/db_load.c')
-rw-r--r--contrib/bind/bin/named/db_load.c1750
1 files changed, 1066 insertions, 684 deletions
diff --git a/contrib/bind/bin/named/db_load.c b/contrib/bind/bin/named/db_load.c
index d05a969..9b6fedb 100644
--- a/contrib/bind/bin/named/db_load.c
+++ b/contrib/bind/bin/named/db_load.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
-static char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: db_load.c,v 8.41 1998/02/13 20:02:28 halley Exp $";
+static const char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91";
+static const char rcsid[] = "$Id: db_load.c,v 8.97 1999/10/30 03:21:35 vixie Exp $";
#endif /* not lint */
/*
@@ -82,7 +82,7 @@ static char rcsid[] = "$Id: db_load.c,v 8.41 1998/02/13 20:02:28 halley Exp $";
*/
/*
- * Portions Copyright (c) 1996, 1997 by Internet Software Consortium.
+ * Portions 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
@@ -110,6 +110,7 @@ static char rcsid[] = "$Id: db_load.c,v 8.41 1998/02/13 20:02:28 halley Exp $";
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
@@ -137,27 +138,28 @@ static char rcsid[] = "$Id: db_load.c,v 8.41 1998/02/13 20:02:28 halley Exp $";
/* Forward. */
static int gettoken(FILE *, const char *);
-static int getttl(FILE *, const char *, int, u_int32_t *, int *);
static int getcharstring(char *, char *, int, int, int, FILE *,
const char *);
-static int makename_ok(char *name, const char *origin, int class,
- struct zoneinfo *zp,
- enum transport transport,
- enum context context,
- const char *owner, const char *filename,
- int lineno, int size);
+static int genname(char *, int, const char *, char *, int);
static int getmlword(char *, size_t, FILE *, int);
static int getallwords(char *, size_t, FILE *, int);
static u_int32_t wordtouint32(char *);
-static int datepart(const char *, int, int, int, int *);
-static u_int32_t datetosecs(const char *, int *);
-static int get_nxt_types(u_char *, FILE *, const char *);
static void fixup_soa(const char *fn, struct zoneinfo *zp);
-#ifdef BIND_NOTIFY
-static void notify_after_delay(evContext ctx, void *uap,
- struct timespec due,
- struct timespec inter);
-#endif
+static int get_nxt_types(u_char *, FILE *, const char *);
+
+static int parse_sig_rr(char *, int, u_char *, int, FILE *,
+ struct zoneinfo *, char *, u_int32_t ,
+ enum context , enum transport , char **);
+static int parse_key_rr(char *, int, u_char *, int, FILE *,
+ struct zoneinfo *, char *, enum context,
+ enum transport, char **);
+
+static int parse_cert_rr(char *, int, u_char *, int, FILE *, char **);
+static int parse_nxt_rr(char *, int, u_char *, int, FILE *,
+ struct zoneinfo *, char *, enum context,
+ enum transport, char **);
+
+
static int wordtouint32_error = 0;
static int empty_token = 0;
static int getmlword_nesting = 0;
@@ -166,37 +168,50 @@ static int getmlword_nesting = 0;
static int clev; /* a zone deeper in a hierarchy has more credibility */
-#ifdef BIND_NOTIFY
-static notify_info_list pending_notifies;
-#endif
-
/*
* Parser token values
*/
-#define CURRENT 1
-#define DOT 2
-#define AT 3
-#define DNAME 4
-#define INCLUDE 5
-#define ORIGIN 6
-#define ERROR 7
+#define CURRENT 1
+#define DOT 2
+#define AT 3
+#define DNAME 4
+#define INCLUDE 5
+#define ORIGIN 6
+#define GENERATE 7
+#define DEFAULTTTL 8
+#define ERRTOK 9
#define MAKENAME_OK(N) \
do { \
if (!makename_ok(N, origin, class, zp, \
- transport, context, \
+ transport, context, \
domain, filename, lineno, \
- sizeof(data) - ((u_char*)N - data))) { \
+ data_size - ((u_char*)N - data))) { \
+ errs++; \
+ sprintf(buf, "bad name \"%s\"", N); \
+ goto err; \
+ } \
+ } while (0)
+
+#define MAKENAME_OKZP(N, SI) \
+ do { \
+ if (!makename_ok(N, zp->z_origin, zp->z_class, zp, \
+ transport, context, \
+ domain, zp->z_source, lineno, \
+ SI - ((u_char*)N - data))) { \
errs++; \
sprintf(buf, "bad name \"%s\"", N); \
goto err; \
} \
} while (0)
+#define RANGE(x, min, max) \
+ (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
+
/* Public. */
/* int
- * db_load(filename, in_origin, zp, def_domain)
+ * db_load(filename, in_origin, zp, def_domain, isixfr)
* load a database from `filename' into zone `zp'. append `in_origin'
* to all nonterminal domain names in the file. `def_domain' is the
* default domain for include files or NULL for zone base files.
@@ -207,18 +222,24 @@ static notify_info_list pending_notifies;
*/
int
db_load(const char *filename, const char *in_origin,
- struct zoneinfo *zp, const char *def_domain)
+ struct zoneinfo *zp, const char *def_domain, int isixfr)
{
static int read_soa, read_ns, rrcount;
+ static u_int32_t default_ttl, default_warn;
+ static struct filenames {
+ struct filenames *next;
+ char *name;
+ } *filenames, *fn;
const char *errtype = "Database";
char *cp;
char domain[MAXDNAME], origin[MAXDNAME], tmporigin[MAXDNAME];
char buf[MAXDATA];
+ char genlhs[MAXDNAME], genrhs[MAXDNAME];
u_char data[MAXDATA];
- const char *op;
- int c, someclass, class, type, dbflags, dataflags, multiline;
- int slineno, i, errs, didinclude, escape, success, dateerror;
+ int data_size = sizeof(data);
+ int c, someclass, class, type, dbflags, dataflags, multiline = 0;
+ int slineno, i, errs, didinclude, ininclude, escape, success;
u_int32_t ttl, n, serial;
u_long tmplong;
struct databuf *dp;
@@ -227,9 +248,10 @@ db_load(const char *filename, const char *in_origin,
struct in_addr ina;
enum transport transport;
enum context context;
- u_int32_t sig_type;
- u_int32_t keyflags;
struct sockaddr_in empty_from;
+ int genstart, genend, genstep;
+ char *thisfile;
+ void *state = NULL;
empty_from.sin_family = AF_INET;
empty_from.sin_addr.s_addr = htonl(INADDR_ANY);
@@ -241,40 +263,57 @@ db_load(const char *filename, const char *in_origin,
* and complains.
*/
#define ERRTO(msg) do { if (1) { errtype = msg; goto err; } } while (0)
+#define ERRTOZ(msg) do { if (1) { errtype = msg; buf[0] = '\0'; goto err; } } while (0)
switch (zp->z_type) {
case Z_PRIMARY:
- case Z_CACHE:
+ case Z_HINT:
transport = primary_trans;
break;
case Z_SECONDARY:
case Z_STUB:
transport = secondary_trans;
break;
+ case Z_CACHE:
+ transport = response_trans;
+ break;
default:
transport = response_trans; /*guessing*/
break;
}
errs = 0;
didinclude = 0;
- if (!def_domain) {
- /* This is not the result of a $INCLUDE. */
+ ininclude = (def_domain != NULL);
+ if (!ininclude) {
rrcount = 0;
read_soa = 0;
read_ns = 0;
+ default_ttl = USE_MINIMUM;
+ default_warn = 1;
clev = nlabels(in_origin);
+ filenames = NULL;
}
+ ttl = default_ttl;
- ns_debug(ns_log_load, 1, "db_load(%s, %s, %d, %s)",
+ ns_debug(ns_log_load, 1, "db_load(%s, %s, %d, %s, %s)",
filename, in_origin, zp - zones,
- def_domain ? def_domain : "Nil");
+ def_domain ? def_domain : "Nil", isixfr ? "IXFR" : "Normal");
+
+ fn = (struct filenames *)memget(sizeof *filenames);
+ if (fn == NULL)
+ ns_panic(ns_log_db, 0, "db_load: memget failed");
+ thisfile = fn->name = savestr(filename, 1);
+ fn->next = filenames;
+ filenames = fn;
strcpy(origin, in_origin);
if ((fp = fopen(filename, "r")) == NULL) {
- ns_warning(ns_log_load, "%s: %s", filename, strerror(errno));
+ ns_warning(ns_log_load, "db_load could not open: %s: %s",
+ filename, strerror(errno));
+ zp->z_ftime = 0;
return (-1);
}
- if (zp->z_type == Z_CACHE) {
+ if (zp->z_type == Z_HINT) {
dbflags = DB_NODATA | DB_NOHINTS;
dataflags = DB_F_HINT;
#ifdef STUBS
@@ -288,7 +327,8 @@ db_load(const char *filename, const char *in_origin,
}
gettime(&tt);
if (fstat(fileno(fp), &sb) < 0) {
- ns_warning(ns_log_load, "%s: %s", filename, strerror(errno));
+ ns_warning(ns_log_load, "fstat failed: %s: %s",
+ filename, strerror(errno));
sb.st_mtime = (int)tt.tv_sec;
}
slineno = lineno;
@@ -302,6 +342,10 @@ db_load(const char *filename, const char *in_origin,
while ((c = gettoken(fp, filename)) != EOF) {
switch (c) {
case INCLUDE:
+ if (isixfr) {
+ c = ERRTOK;
+ break;
+ }
if (!getword(buf, sizeof buf, fp, 0))
/* file name*/
break;
@@ -309,12 +353,12 @@ db_load(const char *filename, const char *in_origin,
strcpy(tmporigin, origin);
else {
if (makename(tmporigin, origin,
- sizeof(tmporigin)) == -1)
+ sizeof(tmporigin)) == -1)
ERRTO("$INCLUDE makename failed");
endline(fp);
}
didinclude = 1;
- errs += db_load(buf, tmporigin, zp, domain);
+ errs += db_load(buf, tmporigin, zp, domain, ISNOTIXFR);
continue;
case ORIGIN:
@@ -329,6 +373,123 @@ db_load(const char *filename, const char *in_origin,
origin);
continue;
+ case GENERATE:
+ if (!getword(buf, sizeof(buf), fp, 0))
+ ERRTOZ("$GENERATE missing RANGE");
+ n = sscanf(buf, "%d-%d/%d", &genstart, &genend,
+ &genstep);
+ if (n != 2 && n != 3)
+ ERRTO("$GENERATE invalid range");
+ if (n == 2)
+ genstep = 1;
+ if ((genend < genstart) || (genstart < 0) ||
+ (genstep < 0))
+ ERRTO("$GENERATE invalid range");
+ if (!getword(genlhs, sizeof(genlhs), fp, 2))
+ ERRTOZ("$GENERATE missing LHS");
+ if (!getword(buf, sizeof(buf), fp, 0))
+ ERRTOZ("GENERATE missing TYPE");
+ type = sym_ston(__p_type_syms, buf, &success);
+ if (success == 0 || type == ns_t_any) {
+ ns_info(ns_log_load,
+ "%s: Line %d: $GENERATE unknown type: %s.",
+ filename, lineno, buf);
+ errs++;
+ endline(fp);
+ continue;
+ }
+ switch (type) {
+ case ns_t_ns:
+ case ns_t_ptr:
+ case ns_t_cname:
+ case ns_t_a:
+ case ns_t_aaaa:
+ break;
+ default:
+ ERRTO("$GENERATE unsupported type");
+ }
+ if (!getword(genrhs, sizeof(genrhs), fp, 2))
+ ERRTOZ("$GENERATE missing RHS");
+ for (i = genstart; i <= genend; i += genstep) {
+ if (genname(genlhs, i, origin, domain,
+ sizeof domain) == -1)
+ ERRTOZ("$GENERATE genname LHS failed");
+ context = ns_ownercontext(type, transport);
+ if (!ns_nameok(NULL, domain, class, zp, transport,
+ context, domain, inaddr_any)) {
+ strcpy(buf, domain);
+ ERRTO("$GENERATE owner name error");
+ }
+ switch (type) {
+ case ns_t_ns:
+ case ns_t_ptr:
+ case ns_t_cname:
+ if (genname(genrhs, i, origin, (char *)data,
+ sizeof data) == -1)
+ ERRTOZ("$GENERATE genname RHS failed");
+ switch (type) {
+ case ns_t_ns:
+ context = hostname_ctx;
+ break;
+ case ns_t_ptr:
+ context = ns_ptrcontext(domain);
+ break;
+ case ns_t_cname:
+ context = domain_ctx;
+ break;
+ }
+ if (!ns_nameok(NULL, (char *)data, class, zp,
+ transport, context,
+ domain, inaddr_any)) {
+ strncpy(buf, domain, sizeof(buf));
+ buf[sizeof(buf)-1] = '\0';
+ ERRTO("$GENERATE name error");
+ }
+ n = strlen((char *)data) + 1;
+ break;
+ case ns_t_a:
+ case ns_t_aaaa:
+ if (genname(genrhs, i, NULL, (char *)data,
+ sizeof data) == -1)
+ ERRTOZ("$GENERATE genname RHS failed");
+ strncpy(buf, (char*)data, sizeof(buf));
+ buf[sizeof(buf)-1] = '\0';
+ switch (type) {
+ case ns_t_a:
+ if (!inet_aton(buf, &ina))
+ ERRTO("IP Address");
+ (void) ina_put(ina, data);
+ n = NS_INT32SZ;
+ break;
+ case ns_t_aaaa:
+ if (inet_pton(AF_INET6, buf, data) <= 0)
+ ERRTO("IPv6 Address");
+ n = NS_IN6ADDRSZ;
+ break;
+ }
+ break;
+ default:
+ ERRTOZ("$GENERATE unsupported context");
+ }
+ dp = savedata(class, type, (u_int32_t)ttl,
+ (u_char *)data, (int)n);
+ dp->d_zone = zp - zones;
+ dp->d_flags = dataflags;
+ dp->d_cred = DB_C_ZONE;
+ dp->d_clev = clev;
+ c = db_set_update(domain, dp, &state, dbflags,
+ (dataflags & DB_F_HINT) != 0 ?
+ &fcachetab : &hashtab,
+ empty_from, &rrcount, lineno,
+ filename);
+ if (c != OK) {
+ if (c == CNAMEANDOTHER)
+ errs++;
+ }
+ }
+ endline(fp);
+ continue;
+
case DNAME:
if (!getword(domain, sizeof(domain), fp, 1))
break;
@@ -336,6 +497,14 @@ db_load(const char *filename, const char *in_origin,
ERRTO("ownername makename failed");
goto gotdomain;
+ case DEFAULTTTL:
+ if (getttl(fp, filename, lineno, &n,
+ &multiline) <= 0 || n > MAXIMUM_TTL) {
+ ERRTO("$TTL bad TTL value");
+ }
+ ttl = default_ttl = n;
+ continue;
+
case AT:
(void) strcpy(domain, origin);
goto gotdomain;
@@ -350,10 +519,19 @@ db_load(const char *filename, const char *in_origin,
continue;
break;
}
- if (ns_parse_ttl(buf, &tmplong) < 0)
- ttl = USE_MINIMUM;
- else {
- ttl = (u_int32_t)tmplong;
+ if (ns_parse_ttl(buf, &tmplong) < 0) {
+ if (zp->z_type == z_master &&
+ default_warn &&
+ (default_ttl == USE_MINIMUM)) {
+ ns_warning(ns_log_load,
+ "Zone \"%s\" (file %s): %s",
+ zp->z_origin, filename,
+ "No default TTL set using SOA minimum instead");
+ default_warn = 0;
+ }
+ ttl = (u_int32_t)default_ttl;
+ } else {
+ ttl = tmplong;
if (ttl > MAXIMUM_TTL) {
ns_info(ns_log_load,
"%s: Line %d: TTL > %u; converted to 0",
@@ -375,6 +553,14 @@ db_load(const char *filename, const char *in_origin,
/* Parse class (IN, etc) */
someclass = sym_ston(__p_class_syms, buf, &success);
+ if (success && someclass != zp->z_class) {
+ ns_info(ns_log_load,
+ "%s: Line %d: wrong class: %s.",
+ filename, lineno,
+ p_class(someclass));
+ errs++;
+ break;
+ }
if (success && someclass != C_ANY) {
class = someclass;
(void) getword(buf, sizeof buf, fp, 0);
@@ -389,9 +575,10 @@ db_load(const char *filename, const char *in_origin,
errs++;
break;
}
-
+ if (ttl == USE_MINIMUM)
+ ttl = zp->z_minimum;
context = ns_ownercontext(type, transport);
- if (!ns_nameok(domain, class, zp, transport, context,
+ if (!ns_nameok(NULL, domain, class, zp, transport, context,
domain, inaddr_any)) {
errs++;
ns_notice(ns_log_load,
@@ -404,6 +591,7 @@ db_load(const char *filename, const char *in_origin,
case ns_t_key:
case ns_t_sig:
case ns_t_nxt:
+ case ns_t_cert:
/*
* Don't do anything here for these types --
* they read their own input separately later.
@@ -451,7 +639,7 @@ db_load(const char *filename, const char *in_origin,
/* FALLTHROUGH */
soa_rp_minfo:
(void) strcpy((char *)data, buf);
-
+
MAKENAME_OK((char *)data);
cp = (char *)(data + strlen((char *)data) + 1);
if (!getword(cp,
@@ -469,13 +657,7 @@ db_load(const char *filename, const char *in_origin,
n = cp - (char *)data;
break;
}
- if (class != zp->z_class) {
- errs++;
- ns_info(ns_log_load, "%s:%d: %s",
- filename, lineno,
- "SOA class not same as zone's");
- }
- if (strcasecmp(zp->z_origin, domain) != 0) {
+ if (ns_samename(zp->z_origin, domain) != 1) {
errs++;
ns_error(ns_log_load,
"%s:%d: SOA for \"%s\" not at zone top \"%s\"",
@@ -509,9 +691,10 @@ db_load(const char *filename, const char *in_origin,
n = INIT_REFRESH;
}
PUTLONG(n, cp);
- zp->z_refresh = MAX(n, MIN_REFRESH);
+ zp->z_refresh = RANGE(n, MIN_REFRESH,
+ MAX_REFRESH);
if (zp->z_type == Z_SECONDARY
-#if defined(STUBS)
+#if defined(STUBS)
|| zp->z_type == Z_STUB
#endif
) {
@@ -520,7 +703,7 @@ db_load(const char *filename, const char *in_origin,
sched_zone_maint(zp);
}
#ifdef BIND_UPDATE
- if ((zp->z_type == Z_PRIMARY) &&
+ if ((zp->z_type == Z_PRIMARY) &&
(zp->z_flags & Z_DYNAMIC))
if ((u_int32_t)zp->z_soaincrintvl >
zp->z_refresh/3) {
@@ -537,14 +720,15 @@ db_load(const char *filename, const char *in_origin,
n = INIT_REFRESH;
}
PUTLONG(n, cp);
- zp->z_retry = MAX(n, MIN_RETRY);
+ zp->z_retry = RANGE(n, MIN_RETRY, MAX_RETRY);
if (getttl(fp, filename, lineno,
- &zp->z_expire, &multiline) <= 0) {
+ &n, &multiline) <= 0) {
errs++;
- zp->z_expire = INIT_REFRESH;
+ n = INIT_REFRESH;
}
- n = zp->z_expire;
PUTLONG(n, cp);
+ zp->z_expire = RANGE(n, zp->z_refresh,
+ MAX_EXPIRE);
if (getttl(fp, filename, lineno, &n,
&multiline) <= 0) {
errs++;
@@ -556,8 +740,10 @@ db_load(const char *filename, const char *in_origin,
"%s: Line %d: SOA minimum TTL > %u; converted to 0",
filename, lineno, MAXIMUM_TTL);
zp->z_minimum = 0;
- } else
+ } else
zp->z_minimum = n;
+ if (default_ttl == USE_MINIMUM)
+ ttl = n;
n = cp - (char *)data;
if (multiline) {
buf[0] = getnonblank(fp, filename);
@@ -584,7 +770,7 @@ db_load(const char *filename, const char *in_origin,
break;
case ns_t_ns:
- if (strcasecmp(zp->z_origin, domain) == 0)
+ if (ns_samename(zp->z_origin, domain) == 1)
read_ns++;
context = hostname_ctx;
goto cname_etc;
@@ -625,22 +811,28 @@ db_load(const char *filename, const char *in_origin,
if (!getword(buf, sizeof buf, fp, 0))
ERRTO("NAPTR Flags");
n = strlen(buf);
+ if (n > 255)
+ ERRTO("NAPTR Flags too big");
*cp++ = n;
memcpy(cp, buf, (int)n);
cp += n;
-
+
/* Service Classes */
if (!getword(buf, sizeof buf, fp, 0))
ERRTO("NAPTR Service Classes");
n = strlen(buf);
+ if (n > 255)
+ ERRTO("NAPTR Service Classes too big");
*cp++ = n;
memcpy(cp, buf, (int)n);
cp += n;
-
+
/* Pattern */
if (!getword(buf, sizeof buf, fp, 0))
ERRTO("NAPTR Pattern");
n = strlen(buf);
+ if (n > 255)
+ ERRTO("NAPTR Pattern too big");
*cp++ = n;
memcpy(cp, buf, (int)n);
cp += n;
@@ -648,6 +840,9 @@ db_load(const char *filename, const char *in_origin,
/* Replacement */
if (!getword(buf, sizeof buf, fp, 1))
ERRTO("NAPTR Replacement");
+ n = strlen(buf);
+ if (n > data_size - ((u_char *)cp - data))
+ ERRTO("NAPTR Replacement too big");
(void) strcpy((char *)cp, buf);
context = domain_ctx;
MAKENAME_OK(cp);
@@ -771,422 +966,31 @@ db_load(const char *filename, const char *in_origin,
endline(fp);
break;
- case ns_t_key: {
- /* The KEY record looks like this in the db file:
- * Name Cl KEY Flags Proto Algid PublicKeyData
- * where:
- * Name,Cl per usual
- * KEY RR type
- * Flags 4 digit hex value (unsigned_16)
- * Proto 8 bit u_int
- * Algid 8 bit u_int
- * PublicKeyData
- * a string of base64 digits,
- * skipping any embedded whitespace.
- */
- u_int32_t al, pr;
- int nk, klen;
- char *expstart;
- u_int expbytes, modbytes;
-
- i = 0;
- data[i] = '\0';
- cp = (char *)data;
- getmlword_nesting = 0; /* KLUDGE err recov. */
- /*>>> Flags (unsigned_16) */
- if (!getmlword((char*)buf, sizeof buf, fp, 0))
- ERRTO("KEY Flags Field");
- keyflags = wordtouint32(buf);
- if (wordtouint32_error || 0xFFFF < keyflags)
+ case ns_t_nxt:
+ case ns_t_key:
+ case ns_t_cert:
+ case ns_t_sig: {
+ char *errmsg = NULL;
+ int ret = parse_sec_rdata(buf, sizeof(buf), 0,
+ data, sizeof(data),
+ fp, zp, domain, ttl,
+ type, domain_ctx,
+ transport, &errmsg);
+ if (ret < 0) {
+ errtype = errmsg;
goto err;
- if (keyflags & NS_KEY_RESERVED_BITMASK)
- ERRTO("KEY Reserved Flag Bit");
- PUTSHORT(keyflags, cp);
-
- /*>>> Protocol (8-bit decimal) */
- if (!getmlword((char*)buf, sizeof buf, fp, 0))
- ERRTO("KEY Protocol Field");
- pr = wordtouint32(buf);
- if (wordtouint32_error || 255 < pr)
- ERRTO("KEY Protocol Field");
- *cp++ = (u_char) pr;
-
- /*>>> Algorithm id (8-bit decimal) */
- if (!getmlword((char*)buf, sizeof buf, fp, 0))
- ERRTO("KEY Algorithm ID");
- al = wordtouint32(buf);
- if (wordtouint32_error ||
- 0 == al || 255 == al || 255 < al)
- ERRTO("KEY Algorithm ID");
- *cp++ = (u_char) al;
-
- /*>>> Public Key data is in BASE64.
- * We don't care what algorithm it uses or what
- * the internal structure of the BASE64 data is.
- */
- if (!getallwords(buf, MAXDATA, fp, 0))
- klen = 0;
- else {
- /* Convert from BASE64 to binary. */
- klen = b64_pton(buf, (u_char*)cp,
- sizeof data -
- (cp - (char *)data));
- if (klen < 0)
- ERRTO("KEY Public Key");
}
-
- /* set total length */
- n = cp + klen - (char *)data;
-
- /*
- * Now check for valid key flags & algs & etc,
- * from the RFC.
- */
-
- if (keyflags & (NS_KEY_ZONEKEY | NS_KEY_IPSEC
- | NS_KEY_EMAIL))
- pr |= 1; /* A nonzero proto. */
- if (NS_KEY_TYPE_NO_KEY ==
- (keyflags & NS_KEY_TYPEMASK))
- nk = 1; /* No-key */
else
- nk = 0; /* have a key */
-
- if ((keyflags & NS_KEY_ZONEKEY) &&
- (NS_KEY_TYPE_CONF_ONLY ==
- (keyflags & NS_KEY_TYPEMASK)))
- /* Zone key must have Auth bit set. */
- ERRTO("KEY Zone Key Auth. bit");
-
- if (al == 0 && nk == 0)
- ERRTO("KEY Algorithm");
- if (al != 0 && pr == 0)
- ERRTO("KEY Protocols");
-
- if (nk == 1 && klen != 0)
- ERRTO("KEY No-Key Flags Set");
-
- if (nk == 0 && klen == 0)
- ERRTO("KEY Type Spec'd");
-
- /* Check algorithm-ID and key structure, for
- the algorithm-ID's that we know about. */
- switch (al) {
- case NS_ALG_MD5RSA:
- if (klen == 0)
- break;
- expstart = cp;
- expbytes = *expstart++;
- if (expbytes == 0)
- GETSHORT(expbytes, expstart);
-
- if (expbytes < 1)
- ERRTO("Exponent too short");
- if (expbytes >
- (NS_MD5RSA_MAX_BITS + 7) / 8
- )
- ERRTO("Exponent too long");
- if (*expstart == 0)
- ERRTO("Exponent w/ 0");
-
- modbytes = klen -
- (expbytes + (expstart - cp));
- if (modbytes <
- (NS_MD5RSA_MIN_BITS + 7) / 8
- )
- ERRTO("Modulus too short");
- if (modbytes >
- (NS_MD5RSA_MAX_BITS + 7) / 8
- )
- ERRTO("Modulus too long");
- if (*(expstart+expbytes) == 0)
- ERRTO("Modulus starts w/ 0");
- break;
-
- case NS_ALG_EXPIRE_ONLY:
- if (klen != 0)
- ERRTO(
- "Key provided for expire-only algorithm"
- );
- break;
- case NS_ALG_PRIVATE_OID:
- if (klen == 0)
- ERRTO("No ObjectID in key");
- break;
- }
-
- endline(fp); /* flush the rest of the line */
+ n = ret;
break;
- } /*T_KEY*/
-
- case ns_t_sig:
- {
- /* The SIG record looks like this in the db file:
- Name Cl SIG RRtype Algid [OTTL] Texp Tsig Kfoot Signer Sig
-
- where: Name and Cl are as usual
- SIG is a keyword
- RRtype is a char string
- ALGid is 8 bit u_int
- OTTL is 32 bit u_int (optionally present)
- Texp is YYYYMMDDHHMMSS
- Tsig is YYYYMMDDHHMMSS
- Kfoot is 16-bit unsigned decimal integer
- Signer is a char string
- Sig is 64 to 319 base-64 digits
- A missing OTTL is detected by the magnitude of the Texp value
- that follows it, which is larger than any u_int.
- The Labels field in the binary RR does not appear in the
- text RR.
-
- It's too crazy to run these pages of SIG code at the right
- margin. I'm exdenting them for readability.
- */
- int siglen;
- u_int32_t al;
- u_int32_t signtime, exptime, timetilexp;
- u_int32_t origTTL;
- time_t now;
-
- /* The TTL gets checked against the Original TTL,
- and bounded by the signature expiration time, which
- are both under the signature. We can't let TTL drift
- based on the SOA record. If defaulted, fix it now.
- (It's not clear to me why USE_MINIMUM isn't eliminated
- before putting ALL RR's into the database. -gnu@toad.com) */
- if (ttl == USE_MINIMUM)
- ttl = zp->z_minimum;
-
- i = 0;
- data[i] = '\0';
- getmlword_nesting = 0; /* KLUDGE err recovery */
-
- /* RRtype (char *) */
- if (!getmlword((char*)buf, sizeof buf, fp, 0))
- ERRTO("SIG record doesn't specify type");
- sig_type = sym_ston(__p_type_syms, buf, &success);
- if (!success || sig_type == ns_t_any) {
- /*
- * We'll also accept a numeric RR type,
- * for signing RR types that this version
- * of named doesn't yet understand.
- * In the ns_t_any case, we rely on wordtouint32
- * to fail when scanning the string "ANY".
- */
- sig_type = wordtouint32 (buf);
- if (wordtouint32_error || sig_type > 0xFFFF)
- ERRTO("Unknown RR type in SIG record");
- }
- cp = (char *)&data[i];
- PUTSHORT((u_int16_t)sig_type, cp);
- i += 2;
-
- /* Algorithm id (8-bit decimal) */
- if (!getmlword(buf, sizeof buf, fp, 0))
- ERRTO("Missing algorithm ID");
- al = wordtouint32(buf);
- if (0 == al || wordtouint32_error || 255 <= al)
- goto err;
- data[i] = (u_char) al;
- i++;
-
- /*
- * Labels (8-bit decimal)
- * Not given in the file. Must compute.
- */
- n = dn_count_labels(domain);
- if (0 >= n || 255 < n)
- ERRTO("SIG label count invalid");
- data[i] = (u_char) n;
- i++;
-
- /*
- * OTTL (optional u_int32_t) and
- * Texp (u_int32_t date)
- */
- if (!getmlword(buf, sizeof buf, fp, 0))
- ERRTO("OTTL and expiration time missing");
- /*
- * See if OTTL is missing and this is a date.
- * This relies on good, silent error checking
- * in datetosecs.
- */
- exptime = datetosecs(buf, &dateerror);
- if (!dateerror) {
- /* Output TTL as OTTL */
- origTTL = ttl;
- cp = (char *)&data[i];
- PUTLONG (origTTL, cp);
- i += 4;
- } else {
- /* Parse and output OTTL; scan TEXP */
- origTTL = wordtouint32(buf);
- if (0 >= origTTL || wordtouint32_error ||
- (origTTL > 0x7fffffff))
- goto err;
- cp = (char *)&data[i];
- PUTLONG(origTTL, cp);
- i += 4;
- if (!getmlword(buf, sizeof buf, fp, 0))
- ERRTO("Expiration time missing");
- exptime = datetosecs(buf, &dateerror);
- }
- if (dateerror || exptime > 0x7fffffff || exptime <= 0)
- ERRTO("Invalid expiration time");
- cp = (char *)&data[i];
- PUTLONG(exptime, cp);
- i += 4;
-
- /* Tsig (u_int32_t) */
- if (!getmlword(buf, sizeof buf, fp, 0))
- ERRTO("Missing signature time");
- signtime = datetosecs(buf, &dateerror);
- if (0 == signtime || dateerror)
- ERRTO("Invalid signature time");
- cp = (char *)&data[i];
- PUTLONG(signtime, cp);
- i += 4;
-
- /* Kfootprint (unsigned_16) */
- if (!getmlword(buf, sizeof buf, fp, 0))
- ERRTO("Missing key footprint");
- n = wordtouint32(buf);
- if (wordtouint32_error || n >= 0x0ffff)
- ERRTO("Invalid key footprint");
- cp = (char *)&data[i];
- PUTSHORT((u_int16_t)n, cp);
- i += 2;
-
- /* Signer's Name */
- if (!getmlword((char*)buf, sizeof buf, fp, 0))
- ERRTO("Missing signer's name");
- cp = (char *)&data[i];
- strcpy(cp,buf);
- context = domain_ctx;
- MAKENAME_OK(cp);
- i += strlen(cp) + 1;
-
- /*
- * Signature (base64 of any length)
- * We don't care what algorithm it uses or what
- * the internal structure of the BASE64 data is.
- */
- if (!getallwords(buf, sizeof buf, fp, 0)) {
- siglen = 0;
- } else {
- cp = (char *)&data[i];
- siglen = b64_pton(buf, (u_char*)cp, sizeof data - i);
- if (siglen < 0)
- goto err;
- }
-
- /* set total length and we're done! */
- n = i + siglen;
-
- /*
- * Check signature time, expiration, and adjust TTL. Note
- * that all time values are in GMT (UTC), *not* local time.
- */
-
- now = time (0);
-
- /* Don't let bogus name servers increase the signed TTL */
- if (ttl > origTTL)
- ERRTO("TTL is greater than signed original TTL");
-
- /* Don't let bogus signers "sign" in the future. */
- if (signtime > (u_int32_t)now)
- ERRTO("signature time is in the future");
-
- /* Ignore received SIG RR's that are already expired. */
- if (exptime <= (u_int32_t)now)
- ERRTO("expiration time is in the past");
-
- /* Lop off the TTL at the expiration time. */
- timetilexp = exptime - now;
- if (timetilexp < ttl) {
- ns_debug(ns_log_load, 1,
- "shrinking expiring %s SIG TTL from %d to %d",
- p_secstodate(exptime), ttl, timetilexp);
- ttl = timetilexp;
- }
-
- /*
- * Check algorithm-ID and key structure, for
- * the algorithm-ID's that we know about.
- */
- switch (al) {
- case NS_ALG_MD5RSA:
- if (siglen == 0)
- ERRTO("No key for RSA algorithm");
- if (siglen < 1)
- ERRTO("Signature too short");
- if (siglen > (NS_MD5RSA_MAX_BITS + 7) / 8)
- ERRTO("Signature too long");
- /* We rely on cp from parse */
- if (*cp == 0)
- ERRTO("Signature starts with zeroes");
- break;
-
- case NS_ALG_EXPIRE_ONLY:
- if (siglen != 0)
- ERRTO(
- "Signature supplied to expire-only algorithm");
- break;
- case NS_ALG_PRIVATE_OID:
- if (siglen == 0)
- ERRTO("No ObjectID in key");
- break;
- }
-
- /* Should we complain about algorithm-ID's that we
- don't understand? It may help debug some obscure
- cases, but in general we should accept any RR whether
- we could cryptographically process it or not; it
- may be being published for some newer DNS clients
- to validate themselves. */
-
- endline(fp); /* flush the rest of the line */
+ }
- break; /* Accept this RR. */
- }
-
- case ns_t_nxt:
- /* The NXT record looks like:
- Name Cl NXT nextname RRT1 RRT2 MX A SOA ...
-
- where: Name and Cl are as usual
- NXT is a keyword
- nextname is the next valid name in
- the zone after "Name". All
- names between the two are
- known to be nonexistent.
- RRT's... are a series of RR type
- names, which indicate that
- RR's of these types are
- published for "Name", and
- that no RR's of any other
- types are published for
- "Name".
-
- When a NXT record is cryptographically
- signed, it proves the nonexistence of an
- RR (actually a whole set of RR's). */
-
- getmlword_nesting = 0; /* KLUDGE err recov. */
- if (!getmlword(buf, sizeof buf, fp, 1))
- goto err;
- (void) strcpy((char *)data, buf);
- MAKENAME_OK((char *)data);
- n = strlen((char *)data) + 1;
- cp = n + (char *)data;
- n += get_nxt_types((u_char *)cp, fp, filename);
- break;
case ns_t_loc:
cp = buf + (n = strlen(buf));
*cp = ' ';
cp++;
+ n++;
while ((i = getc(fp), *cp = i, i != EOF)
&& *cp != '\n'
&& (n < MAXDATA)) {
@@ -1202,6 +1006,7 @@ db_load(const char *filename, const char *in_origin,
endline(fp);
break;
+
default:
goto err;
}
@@ -1209,7 +1014,7 @@ db_load(const char *filename, const char *in_origin,
* Ignore data outside the zone.
*/
if (zp->z_type != Z_CACHE &&
- !samedomain(domain, zp->z_origin))
+ !ns_samedomain(domain, zp->z_origin))
{
ns_info(ns_log_load,
"%s:%d: data \"%s\" outside zone \"%s\" (ignored)",
@@ -1223,42 +1028,44 @@ db_load(const char *filename, const char *in_origin,
dp->d_flags = dataflags;
dp->d_cred = DB_C_ZONE;
dp->d_clev = clev;
- if ((c = db_update(domain, dp, dp, NULL, dbflags,
- (dataflags & DB_F_HINT)
- ? fcachetab
- : hashtab, empty_from))
- != OK) {
- if (c != DATAEXISTS)
- ns_debug(ns_log_load, 1,
- "update failed %s %d",
- domain, type);
- db_freedata(dp);
- } else {
- rrcount++;
- }
+ c = db_set_update(domain, dp, &state, dbflags,
+ (dataflags & DB_F_HINT) != 0 ?
+ &fcachetab : &hashtab,
+ empty_from, &rrcount, lineno,
+ filename);
+ if (c == CNAMEANDOTHER)
+ errs++;
continue;
- case ERROR:
+ case ERRTOK:
break;
}
err:
errs++;
- ns_notice(ns_log_load, "%s:%d: %s error (%s)",
+ ns_notice(ns_log_load, "%s:%d: %s error near (%s)",
filename, empty_token ? (lineno - 1) : lineno,
errtype, buf);
if (!empty_token)
endline(fp);
}
+ c = db_set_update(NULL, NULL, &state, dbflags,
+ (dataflags & DB_F_HINT) ? &fcachetab : &hashtab,
+ empty_from, &rrcount, lineno, filename);
+ if (c != OK) {
+ if (c == CNAMEANDOTHER)
+ errs++;
+ }
+
(void) my_fclose(fp);
lineno = slineno;
- if (!def_domain) {
+ if (!ininclude) {
if (didinclude) {
zp->z_flags |= Z_INCLUDE;
zp->z_ftime = 0;
} else
zp->z_ftime = sb.st_mtime;
zp->z_lastupdate = sb.st_mtime;
- if (zp->z_type != Z_CACHE) {
+ if (zp->z_type != Z_CACHE && zp->z_type != Z_HINT) {
const char *msg = NULL;
if (read_soa == 0)
@@ -1276,62 +1083,45 @@ db_load(const char *filename, const char *in_origin,
zp->z_origin, filename, msg);
}
}
- }
- if (!def_domain) {
- if (errs)
+ while (filenames) {
+ fn = filenames;
+ filenames = filenames->next;
+ freestr(fn->name);
+ memput(fn, sizeof *fn);
+ }
+ if (errs != 0)
ns_warning(ns_log_load,
"%s zone \"%s\" (%s) rejected due to errors (serial %u)",
- zoneTypeString(zp), zp->z_origin,
+ zoneTypeString(zp->z_type), zp->z_origin,
p_class(zp->z_class), zp->z_serial);
else
ns_info(ns_log_load,
"%s zone \"%s\" (%s) loaded (serial %u)",
- zoneTypeString(zp), zp->z_origin,
+ zoneTypeString(zp->z_type), zp->z_origin,
p_class(zp->z_class), zp->z_serial);
}
- if (errs) {
+ if (errs != 0) {
zp->z_flags |= Z_DB_BAD;
zp->z_ftime = 0;
}
#ifdef BIND_NOTIFY
- if (!errs && !def_domain &&
- (zp->z_type == z_master || zp->z_type == z_slave)) {
- static const char no_room[] =
- "%s failed, cannot notify for zone %s";
- notify_info ni;
-
- ni = memget(sizeof *ni);
- if (ni == NULL)
- ns_info(ns_log_load, no_room, "memget", zp->z_origin);
- else {
- ni->name = savestr(zp->z_origin, 0);
- if (ni->name == NULL) {
- memput(ni, sizeof *ni);
- ns_info(ns_log_load, no_room,
- "memget", zp->z_origin);
- } else {
- ni->class = zp->z_class;
- ni->state = notify_info_waitfor;
- if (evWaitFor(ev,
- (const void *)notify_after_load,
- notify_after_load, ni,
- &ni->wait_id) < 0) {
- ns_error(ns_log_load,
- "evWaitFor() failed: %s",
- strerror(errno));
- freestr(ni->name);
- memput(ni, sizeof *ni);
- } else {
- APPEND(pending_notifies, ni, link);
- ns_need(MAIN_NEED_NOTIFY);
- }
- }
- }
- }
+ if (errs == 0 && (!ininclude) &&
+ (zp->z_type == z_master || zp->z_type == z_slave))
+ ns_notify(zp->z_origin, zp->z_class, ns_t_soa);
#endif
return (errs);
}
+void
+db_err(int err, char *domain, int type, const char *filename, int lineno) {
+ if (filename != NULL && err == CNAMEANDOTHER)
+ ns_notice(ns_log_load, "%s:%d:%s: CNAME and OTHER data error",
+ filename, lineno, domain);
+ if (err != DATAEXISTS)
+ ns_debug(ns_log_load, 1, "update failed %s %d",
+ domain, type);
+}
+
static int
gettoken(FILE *fp, const char *src) {
int c;
@@ -1350,11 +1140,15 @@ gettoken(FILE *fp, const char *src) {
return (INCLUDE);
if (!strcasecmp("origin", op))
return (ORIGIN);
+ if (!strcasecmp("generate", op))
+ return (GENERATE);
+ if (!strcasecmp("ttl", op))
+ return (DEFAULTTTL);
}
ns_notice(ns_log_db,
"%s:%d: Unknown $ option: $%s",
src, lineno, op);
- return (ERROR);
+ return (ERRTOK);
case ';':
while ((c = getc(fp)) != EOF && c != '\n')
@@ -1375,6 +1169,10 @@ gettoken(FILE *fp, const char *src) {
lineno++;
continue;
+ case '\r':
+ if (NS_OPTION_P(OPTION_TREAT_CR_AS_SPACE) != 0)
+ return (CURRENT);
+
default:
(void) ungetc(c, fp);
return (DNAME);
@@ -1391,6 +1189,7 @@ gettoken(FILE *fp, const char *src) {
* size - of destination
* fp - file to read from
* preserve - should we preserve \ before \\ and \.?
+ * if preserve == 2, then keep all \
* return value:
* 0 = no word; perhaps EOL or EOF; lineno was incremented.
* 1 = word was read
@@ -1398,10 +1197,12 @@ gettoken(FILE *fp, const char *src) {
int
getword(char *buf, size_t size, FILE *fp, int preserve) {
char *cp = buf;
- int c, spaceok;
+ int c, spaceok, once;
empty_token = 0; /* XXX global side effect. */
+ once = 0;
while ((c = getc(fp)) != EOF) {
+ once++;
if (c == ';') {
/* Comment. Skip to end of line. */
while ((c = getc(fp)) != EOF && c != '\n')
@@ -1427,6 +1228,9 @@ getword(char *buf, size_t size, FILE *fp, int preserve) {
c = '\\';
if (preserve)
switch (c) {
+ default:
+ if (preserve == 1)
+ break;
case '\\':
case '.':
case '0':
@@ -1474,6 +1278,9 @@ getword(char *buf, size_t size, FILE *fp, int preserve) {
c = '\\';
if (preserve)
switch (c) {
+ default:
+ if (preserve == 1)
+ break;
case '\\':
case '.':
case '0':
@@ -1510,6 +1317,8 @@ getword(char *buf, size_t size, FILE *fp, int preserve) {
*cp = '\0';
if (cp == buf)
empty_token = 1;
+ if (!once)
+ lineno++;
return (cp != buf);
}
@@ -1524,7 +1333,7 @@ getword(char *buf, size_t size, FILE *fp, int preserve) {
* side effects:
* *ttl is written if the return value is to be 1.
*/
-static int
+int
getttl(FILE *fp, const char *fn, int lineno, u_int32_t *ttl, int *multiline) {
char buf[MAXDATA];
u_long tmp;
@@ -1748,6 +1557,103 @@ getnonblank(FILE *fp, const char *src) {
}
/*
+ * Replace all single "$"'s in "name" with "it".
+ * ${delta} will add delta to "it" before printing.
+ * ${delta,width} will change print width as well, zero fill is implied
+ * ${delta,width,radix} will change radix as well, can be d, o, x, X.
+ * i.e. ${0,2,X} will produce a two digit hex (upper case) with zero fill.
+ * Append "origin" to name if required and validate result with makename.
+ * To get a "$" or "{" in the output use \ before it.
+ * Return 0 on no error or -1 on error.
+ * Resulting name stored in "buf".
+ */
+
+static int
+genname(char *name, int it, const char *origin, char *buf, int size) {
+ char *bp = buf;
+ char *eom = buf + size;
+ char *cp;
+ char numbuf[32];
+ char fmt[32];
+ int delta = 0;
+ int width;
+
+ while (*name) {
+ if (*name == '$') {
+ if (*(++name) == '$') {
+ /* should be deprecated. how? */
+ if (bp >= eom)
+ return (-1);
+ *bp++ = *name++;
+ } else {
+ strcpy(fmt, "%d");
+ if (*name == '{') {
+ switch (sscanf(name, "{%d,%d,%1[doxX]}", &delta, &width, numbuf)) {
+ case 1:
+ break;
+ case 2:
+ sprintf(fmt, "%%0%dd", width);
+ break;
+ case 3:
+ sprintf(fmt, "%%0%d%c", width, numbuf[0]);
+ break;
+ default:
+ return (-1);
+ }
+ while (*name && *name++ != '}') {
+ continue;
+ }
+ }
+ sprintf(numbuf, fmt, it + delta);
+ cp = numbuf;
+ while (*cp) {
+ if (bp >= eom)
+ return (-1);
+ *bp++ = *cp++;
+ }
+ }
+ } else if (*name == '\\') {
+ if (*(++name) == '\0') {
+ if (bp >= eom)
+ return (-1);
+ *bp++ = '\\';
+ } else {
+ switch (*name) {
+ case '\\':
+ case '.':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (bp >= eom)
+ return (-1);
+ *bp++ = '\\';
+ default:
+ if (bp >= eom)
+ return (-1);
+ *bp++ = *name++;
+ }
+ }
+ } else {
+ if (bp >= eom)
+ return (-1);
+ *bp++ = *name++;
+ }
+ }
+ if (bp >= eom)
+ return (-1);
+ *bp = '\0';
+ return (origin == NULL ? 0 : makename(buf, origin, size));
+}
+
+
+/*
* Take name and fix it according to following rules:
* "." means root.
* "@" means current origin.
@@ -1786,7 +1692,7 @@ makename(char *name, const char *origin, int size) {
return (0);
}
-static int
+int
makename_ok(char *name, const char *origin, int class, struct zoneinfo *zp,
enum transport transport, enum context context,
const char *owner, const char *filename, int lineno, int size)
@@ -1798,7 +1704,7 @@ makename_ok(char *name, const char *origin, int class, struct zoneinfo *zp,
filename, lineno);
return (0);
}
- if (!ns_nameok(name, class, zp, transport, context, owner,
+ if (!ns_nameok(NULL, name, class, zp, transport, context, owner,
inaddr_any)) {
ns_info(ns_log_db, "%s:%d: database naming error",
filename, lineno);
@@ -1928,91 +1834,6 @@ wordtouint32(buf)
return (res2);
}
-
-/*
- * 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);
-}
-
-
-/* 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. */
-
-static u_int32_t
-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);
-}
-
-
-#define MAXCHARSTRING 255
-
static int
getcharstring(char *buf, char *data, int type,
int minfields, int maxfields,
@@ -2029,7 +1850,7 @@ getcharstring(char *buf, char *data, int type,
if (type == ns_t_txt || type == ns_t_x25) {
while (i > MAXCHARSTRING
&& n + MAXCHARSTRING + 1 < MAXDATA) {
- data[n] = MAXCHARSTRING;
+ data[n] = (char)MAXCHARSTRING;
memmove(data + n + 1, b, MAXCHARSTRING);
n += MAXCHARSTRING + 1;
b += MAXCHARSTRING;
@@ -2040,13 +1861,13 @@ getcharstring(char *buf, char *data, int type,
if (i > MAXCHARSTRING) {
ns_info(ns_log_db,
"%s:%d: RDATA field %d too long",
- src, lineno, nfield);
+ src, lineno -1, nfield);
return (0);
}
if (n + i + 1 > MAXDATA) {
ns_info(ns_log_db,
"%s:%d: total RDATA too long",
- src, lineno);
+ src, lineno -1);
return (0);
}
data[n] = i;
@@ -2058,7 +1879,7 @@ getcharstring(char *buf, char *data, int type,
if (nfield < minfields) {
ns_info(ns_log_db,
"%s:%d: expected %d RDATA fields, only saw %d",
- src, lineno, minfields, nfield);
+ src, lineno -1, minfields, nfield);
return (0);
}
@@ -2083,18 +1904,18 @@ getcharstring(char *buf, char *data, int type,
static int
get_nxt_types(u_char *data, FILE *fp, const char *filename) {
char b[MAXLABEL]; /* Not quite the right size, but good enough */
- int maxtype=0;
+ int maxtype=0;
int success;
int type;
int errs = 0;
- memset(data, 0, ns_t_any/NS_NXT_BITS+1);
+ memset(data, 0, NS_NXT_MAX/NS_NXT_BITS+1);
while (getmlword(b, sizeof(b), fp, 0)) {
if (feof(fp) || ferror(fp))
- break;
+ break;
if (strlen(b) == 0 || b[0] == '\n')
- continue;
+ continue;
/* Parse RR type (A, MX, etc) */
type = sym_ston(__p_type_syms, (char *)b, &success);
@@ -2106,7 +1927,7 @@ get_nxt_types(u_char *data, FILE *fp, const char *filename) {
continue;
}
NS_NXT_BIT_SET(type, data);
- if (type > maxtype)
+ if (type > maxtype)
maxtype = type;
}
if (errs)
@@ -2157,62 +1978,623 @@ fixup_soa(const char *fn, struct zoneinfo *zp) {
fn, zp->z_refresh, zp->z_retry);
}
-#ifdef BIND_NOTIFY
-static void
-free_notify_info(notify_info ni) {
- if (ni->state == notify_info_waitfor)
- evUnwait(ev, ni->wait_id);
- else if (ni->state == notify_info_delay)
- evClearTimer(ev, ni->timer_id);
- freestr(ni->name);
- memput(ni, sizeof *ni);
-}
+/* this function reads in the sig record rdata from the input file and
+ * returns the following codes
+ * > 0 length of the recrod
+ * ERR_EOF end of file
+ *
+ */
-void
-notify_after_load(evContext ctx, void *uap, const void *tag) {
- int delay, max_delay;
- notify_info ni = uap;
+static int
+parse_sig_rr(char *buf, int buf_len, u_char *data, int data_size,
+ FILE *fp, struct zoneinfo *zp, char *domain, u_int32_t ttl,
+ enum context domain_ctx, enum transport transport, char **errmsg)
+{
+/* The SIG record looks like this in the db file:
+ Name Cl SIG RRtype Algid [OTTL] Texp Tsig Kfoot Signer Sig
+
+ where: Name and Cl are as usual
+ SIG is a keyword
+ RRtype is a char string
+ ALGid is 8 bit u_int
+ Labels is 8 bit u_int
+ OTTL is 32 bit u_int (optionally present)
+ Texp is YYYYMMDDHHMMSS
+ Tsig is YYYYMMDDHHMMSS
+ Kfoot is 16-bit unsigned decimal integer
+ Signer is a char string
+ Sig is 64 to 319 base-64 digits
+ A missing OTTL is detected by the magnitude of the Texp value
+ that follows it, which is larger than any u_int.
+ The Labels field in the binary RR does not appear in the
+ text RR.
+
+ It's too crazy to run these pages of SIG code at the right
+ margin. I'm exdenting them for readability.
+*/
+ u_int32_t sig_type;
+ int dateerror;
+ int siglen, success;
+ u_char *cp;
+ u_int32_t al, la, n;
+ u_int32_t signtime, exptime, timetilexp;
+ u_int32_t origTTL;
+ enum context context;
+ time_t now;
+ char *errtype = "SIG error";
+ int i, my_buf_size = MAXDATA, errs = 0;
+
+
+ /* The TTL gets checked against the Original TTL,
+ and bounded by the signature expiration time, which
+ are both under the signature. We can't let TTL drift
+ based on the SOA record. If defaulted, fix it now.
+ (It's not clear to me why USE_MINIMUM isn't eliminated
+ before putting ALL RR's into the database. -gnu@toad.com) */
+ if (ttl == USE_MINIMUM)
+ ttl = zp->z_minimum;
+
+ i = 0;
+ data[i] = '\0';
+
+ getmlword_nesting = 0; /* KLUDGE err recovery */
- INSIST(tag == (const void *)notify_after_load);
-
- /* delay notification for from five seconds up to fifteen minutes */
- max_delay = MIN(nzones/5, 895);
- max_delay = MAX(max_delay, 25);
- delay = 5 + (rand() % max_delay);
- ns_debug(ns_log_notify, 3, "notify_after_load: uap %p tag %p delay %d",
- uap, tag, delay);
- if (evSetTimer(ctx, notify_after_delay, ni,
- evAddTime(evNowTime(), evConsTime(delay, 0)),
- evConsTime(0, 0), &ni->timer_id) < 0) {
- ns_error(ns_log_notify, "evSetTimer() failed: %s",
- strerror(errno));
- UNLINK(pending_notifies, ni, link);
- ni->state = notify_info_error;
- free_notify_info(ni);
+ /* RRtype (char *)
+ * if old style inp will contain the next token
+ *copy that into buffer, otherwise read from file
+ */
+ if (buf && buf_len == 0)
+ if (!getmlword((char*)buf, my_buf_size, fp, 0))
+ ERRTO("SIG record doesn't specify type");
+ sig_type = sym_ston(__p_type_syms, buf, &success);
+ if (!success || sig_type == ns_t_any) {
+ /*
+ * We'll also accept a numeric RR type,
+ * for signing RR types that this version
+ * of named doesn't yet understand.
+ * In the ns_t_any case, we rely on wordtouint32
+ * to fail when scanning the string "ANY".
+ */
+ sig_type = wordtouint32 (buf);
+ if (wordtouint32_error || sig_type > 0xFFFF)
+ ERRTO("Unknown RR type in SIG record");
+ }
+ cp = &data[i];
+ PUTSHORT((u_int16_t)sig_type, cp);
+ i += 2;
+
+ /* Algorithm id (8-bit decimal) */
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("Missing algorithm ID");
+ al = wordtouint32(buf);
+ if (0 == al || wordtouint32_error || 255 <= al)
+ ERRTO("Bad algorithm number");
+ data[i] = (u_char) al;
+ i++;
+
+ /*
+ * Labels (8-bit decimal)
+ */
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("Missing label count");
+ la = wordtouint32(buf);
+ if (0 == la || wordtouint32_error || 255 <= la)
+ ERRTO("Bad label count number");
+ data[i] = (u_char) la;
+ i++;
+
+ /*
+ * OTTL (optional u_int32_t) and
+ * Texp (u_int32_t date)
+ */
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("OTTL and expiration time missing");
+ /*
+ * See if OTTL is missing and this is a date.
+ * This relies on good, silent error checking
+ * in ns_datetosecs.
+ */
+ exptime = ns_datetosecs(buf, &dateerror);
+ if (!dateerror) {
+ /* Output TTL as OTTL */
+ origTTL = ttl;
+ cp = &data[i];
+ PUTLONG (origTTL, cp);
+ i += 4;
+ } else {
+ /* Parse and output OTTL; scan TEXP */
+ origTTL = wordtouint32(buf);
+ if (0 >= origTTL || wordtouint32_error ||
+ (origTTL > 0x7fffffff))
+ ERRTO("Original TTL value bad");
+ cp = &data[i];
+ PUTLONG(origTTL, cp);
+ i += 4;
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("Expiration time missing");
+ exptime = ns_datetosecs(buf, &dateerror);
}
- ni->state = notify_info_delay;
+ if (dateerror || exptime > 0x7fffffff || exptime <= 0)
+ ERRTO("Invalid expiration time");
+ cp = &data[i];
+ PUTLONG(exptime, cp);
+ i += 4;
+
+ /* Tsig (u_int32_t) */
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("Missing signature time");
+ signtime = ns_datetosecs(buf, &dateerror);
+ if (0 == signtime || dateerror)
+ ERRTO("Invalid signature time");
+ cp = &data[i];
+ PUTLONG(signtime, cp);
+ i += 4;
+
+ /* Kfootprint (unsigned_16) */
+ if (!getmlword(buf, my_buf_size, fp, 0))
+ ERRTO("Missing key footprint");
+ n = wordtouint32(buf);
+ if (wordtouint32_error || n >= 0x0ffff)
+ ERRTO("Invalid key footprint");
+ cp = &data[i];
+ PUTSHORT((u_int16_t)n, cp);
+ i += 2;
+
+ /* Signer's Name */
+ if (!getmlword((char*)buf, my_buf_size, fp, 0))
+ ERRTO("Missing signer's name");
+ cp = &data[i];
+ strcpy((char *)cp, buf);
+ context = domain_ctx;
+ MAKENAME_OKZP((char *)cp, data_size);
+ i += strlen((char *)cp) + 1;
+
+ /*
+ * Signature (base64 of any length)
+ * We don't care what algorithm it uses or what
+ * the internal structure of the BASE64 data is.
+ */
+ if (!getallwords(buf, my_buf_size, fp, 0)) {
+ siglen = 0;
+ } else {
+ cp = &data[i];
+ siglen = b64_pton(buf, (u_char*)cp, data_size - i);
+ if (siglen < 0)
+ ERRTO("Signature block bad");
+ }
+
+ /* set total length and we're done! */
+ n = i + siglen;
+
+ /*
+ * Check signature time, expiration, and adjust TTL. Note
+ * that all time values are in GMT (UTC), *not* local time.
+ */
+
+ now = time (0); /* need to find a better place for this XXX ogud */
+ /* Don't let bogus name servers increase the signed TTL */
+ if (ttl > origTTL)
+ ERRTO("TTL is greater than signed original TTL");
+
+ /* Don't let bogus signers "sign" in the future. */
+ if (signtime > (u_int32_t)now)
+ ERRTO("signature time is in the future");
+
+ /* Ignore received SIG RR's that are already expired. */
+ if (exptime <= (u_int32_t)now)
+ ERRTO("expiration time is in the past");
+
+ /* Lop off the TTL at the expiration time. */
+ timetilexp = exptime - now;
+ if (timetilexp < ttl) {
+ ns_debug(ns_log_load, 1,
+ "shrinking expiring %s SIG TTL from %d to %d",
+ p_secstodate(exptime), ttl, timetilexp);
+ ttl = timetilexp;
+ }
+
+ /*
+ * Check algorithm-ID and key structure, for
+ * the algorithm-ID's that we know about.
+ */
+ switch (al) {
+ case NS_ALG_MD5RSA:
+ if (siglen == 0)
+ ERRTO("No key for RSA algorithm");
+ if (siglen < 1)
+ ERRTO("Signature too short");
+ if (siglen > (NS_MD5RSA_MAX_BITS + 7) / 8)
+ ERRTO("Signature too long");
+ break;
+
+ case NS_ALG_DH:
+ if (siglen < 1)
+ ERRTO("DH Signature too short");
+ break; /* need more tests here */
+
+ case NS_ALG_DSA:
+ if (siglen < NS_DSA_SIG_SIZE)
+ ERRTO("DSS Signature too short");
+ else if (siglen > NS_DSA_SIG_SIZE)
+ ERRTO("DSS Signature too long ");
+ break; /* need more tests here */
+
+ case NS_ALG_EXPIRE_ONLY:
+ if (siglen != 0)
+ ERRTO(
+ "Signature supplied to expire-only algorithm");
+ break;
+ case NS_ALG_PRIVATE_OID:
+ if (siglen == 0)
+ ERRTO("No ObjectID in key");
+ break;
+ default:
+ ERRTO("UNKOWN SIG algorithm");
+ }
+
+ /* Should we complain about algorithm-ID's that we
+ don't understand? It may help debug some obscure
+ cases, but in general we should accept any RR whether
+ we could cryptographically process it or not; it
+ may be being published for some newer DNS clients
+ to validate themselves. */
+
+ endline(fp); /* flush the rest of the line */
+
+ return (n);
+ err:
+ *errmsg = errtype;
+ return (-1);
}
-static void
-notify_after_delay(evContext ctx, void *uap,
- struct timespec due,
- struct timespec inter)
+static int
+parse_nxt_rr(char *buf, int buf_len, u_char *data, int data_size,
+ FILE *fp, struct zoneinfo *zp, char *domain, enum context context,
+ enum transport transport, char **errmsg)
{
- notify_info ni = uap;
+
+ /* The NXT record looks like:
+ Name Cl NXT nextname RRT1 RRT2 MX A SOA ...
+
+ where: Name and Cl are as usual
+ NXT is a keyword
+ nextname is the next valid name in the zone after "Name".
+ All names between the two are known to be nonexistent.
+ RRT's... are a series of RR type names, which indicate that
+ RR's of these types are published for "Name", and
+ that no RR's of any other types are published for "Name".
+
+ When a NXT record is cryptographically signed, it proves the
+ nonexistence of an RR (actually a whole set of RR's).
+ */
+ int n, errs = 0, i;
+ u_char *cp;
+/* char *origin = zp->z_origin;
+ int class = zp->z_class; */
+ *errmsg = "NXT name error";
+
+ (void) strcpy((char *)data, buf);
+ MAKENAME_OKZP((char *)data, data_size);
+ n = strlen((char *)data) + 1;
+ cp = n + data;
+ i = get_nxt_types(cp, fp, zp->z_source);
+ if( i > 0)
+ return (n + i);
+ *errmsg = "NXT type error";
+ err:
+ return (-1);
+}
- UNLINK(pending_notifies, ni, link);
- ni->state = notify_info_done;
- sysnotify(ni->name, ni->class, ns_t_soa);
- free_notify_info(ni);
+
+static int
+parse_cert_rr(char *buf, int buf_len, u_char *data, int data_size,
+ FILE *fp, char **errmsg)
+{
+ /* Cert record looks like:
+ * Type Key_tag Alg Cert
+ * Type: certification type number (16)
+ * Key_tag: tag of corresponding KEY RR (16)
+ * Alg: algorithm of the KEY RR (8)
+ * Cert: base64 enocded block
+ */
+ u_char *cp;
+ u_int32_t cert_type, key_tag, alg;
+ char *errtype = "CERT parse error";
+ int certlen, i, n, success;
+
+ i = 0;
+ cp = &data[i];
+ cert_type = sym_ston(__p_cert_syms, buf, &success);
+ if (!success) {
+ cert_type = wordtouint32(buf);
+ if (wordtouint32_error || cert_type > 0xFFFF)
+ ERRTO("CERT type out of range");
+ }
+ PUTSHORT((u_int16_t)cert_type, cp);
+ i += INT16SZ;
+
+ if (!getmlword((char*)buf, buf_len, fp, 0))
+ ERRTO("CERT doesn't specify type");
+
+ key_tag = wordtouint32(buf);
+ if (wordtouint32_error || key_tag > 0xFFFF)
+ ERRTO("CERT KEY tag out of range");
+
+ PUTSHORT((u_int16_t)key_tag, cp);
+ i += INT16SZ;
+
+ if (!getmlword(buf, buf_len, fp, 0))
+ ERRTO("CERT missing algorithm ID");
+
+ alg = sym_ston(__p_key_syms, buf, &success);
+ if (!success) {
+ alg = wordtouint32(buf);
+ if (wordtouint32_error || alg > 0xFF)
+ ERRTO("CERT KEY alg out of range");
+ }
+
+ data[i++] = (u_char)alg;
+
+ if (!getallwords(buf, buf_len, fp, 0)) {
+ certlen = 0;
+ }
+ else {
+ cp = &data[i];
+ certlen = b64_pton(buf, (u_char*)cp, sizeof(data) - i);
+ if (certlen < 0)
+ ERRTO("CERT blob has encoding error");
+ }
+ /* set total length */
+ n = i + certlen;
+ return (n);
+ err:
+ *errmsg = errtype;
+ return (-1);
+
}
-void
-db_cancel_pending_notifies(void) {
- notify_info ni, ni_next;
- for (ni = HEAD(pending_notifies); ni != NULL; ni = ni_next) {
- ni_next = NEXT(ni, link);
- free_notify_info(ni);
+static int
+parse_key_rr(char *buf, int buf_len, u_char *data, int data_size,
+ FILE *fp, struct zoneinfo *zp, char *domain, enum context context,
+ enum transport transport, char **errmsg)
+{
+ /* The KEY record looks like this in the db file:
+ * Name Cl KEY Flags Proto Algid PublicKeyData
+ * where:
+ * Name,Cl per usual
+ * KEY RR type
+ * Flags 4 digit hex value (unsigned_16)
+ * Proto 8 bit u_int
+ * Algid 8 bit u_int
+ * PublicKeyData
+ * a string of base64 digits,
+ * skipping any embedded whitespace.
+ */
+ u_int32_t al, pr;
+ int nk, klen,i, n;
+ u_int32_t keyflags;
+ char *errtype = "KEY error";
+ u_char *cp, *expstart;
+ u_int expbytes, modbytes;
+
+ i = n = 0;
+ data[i] = '\0';
+ cp = data;
+ getmlword_nesting = 0; /* KLUDGE err recov. */
+
+ /*>>> Flags (unsigned_16) */
+ keyflags = wordtouint32(buf);
+ if (wordtouint32_error || 0xFFFF < keyflags)
+ ERRTO("KEY flags error");
+ if (keyflags & NS_KEY_RESERVED_BITMASK)
+ ERRTO("KEY Reserved Flag Bit");
+ PUTSHORT(keyflags, cp);
+
+ /*>>> Protocol (8-bit decimal) */
+ if (!getmlword((char*)buf, buf_len, fp, 0))
+ ERRTO("KEY Protocol Field");
+ pr = wordtouint32(buf);
+ if (wordtouint32_error || 255 < pr)
+ ERRTO("KEY Protocol Field");
+ *cp++ = (u_char) pr;
+
+ /*>>> Algorithm id (8-bit decimal) */
+ if (!getmlword((char*)buf, buf_len, fp, 0))
+ ERRTO("KEY Algorithm ID");
+ al = wordtouint32(buf);
+ if (wordtouint32_error || 0 == al || 255 == al || 255 < al)
+ ERRTO("KEY Algorithm ID");
+ *cp++ = (u_char) al;
+
+ /*>>> Extended KEY flag field in bytes 5 and 6 */
+ if (NS_KEY_EXTENDED_FLAGS & keyflags) {
+ u_int32_t keyflags2;
+
+ if (!getmlword((char*)buf, buf_len, fp, 0))
+ ERRTO("KEY Flags Field");
+ keyflags2 = wordtouint32(buf);
+ if (wordtouint32_error || 0xFFFF < keyflags2)
+ ERRTO("Extended key flags error");
+ if (keyflags2 & NS_KEY_RESERVED_BITMASK2)
+ ERRTO("KEY Reserved Flag2 Bit");
+ PUTSHORT(keyflags2, cp);
+ }
+
+ /*>>> Public Key data is in BASE64.
+ * We don't care what algorithm it uses or what
+ * the internal structure of the BASE64 data is.
+ */
+ if (!getallwords(buf, MAXDATA, fp, 0))
+ klen = 0;
+ else {
+ /* Convert from BASE64 to binary. */
+ klen = b64_pton(buf, (u_char*)cp,
+ data_size - (cp - data));
+ if (klen < 0)
+ ERRTO("KEY Public Key");
+ }
+
+ /* set total length */
+ n = klen + (cp - data);
+
+ /*
+ * Now check for valid key flags & algs & etc, from the RFC.
+ */
+
+ if (NS_KEY_TYPE_NO_KEY == (keyflags & NS_KEY_TYPEMASK))
+ nk = 1; /* No-key */
+ else
+ nk = 0; /* have a key */
+
+ if ((keyflags & (NS_KEY_NAME_TYPE | NS_KEY_TYPEMASK)) ==
+ (NS_KEY_NAME_ZONE | NS_KEY_TYPE_CONF_ONLY))
+ /* Zone key must have Auth bit set. */
+ ERRTO("KEY Zone Key Auth. bit");
+
+ if (al == 0 && nk == 0)
+ ERRTO("KEY Algorithm");
+ if (al != 0 && pr == 0)
+ ERRTO("KEY Protocols");
+
+ if (nk == 1 && klen != 0)
+ ERRTO("KEY No-Key Flags Set");
+
+ if (nk == 0 && klen == 0)
+ ERRTO("KEY Type Spec'd");
+
+ /*
+ * Check algorithm-ID and key structure, for the algorithm-ID's
+ * that we know about.
+ */
+ switch (al) {
+ case NS_ALG_MD5RSA:
+ if (klen == 0)
+ break;
+ expstart = cp;
+ expbytes = *expstart++;
+ if (expbytes == 0)
+ GETSHORT(expbytes, expstart);
+
+ if (expbytes < 1)
+ ERRTO("Exponent too short");
+ if (expbytes > (NS_MD5RSA_MAX_BITS + 7) / 8)
+ ERRTO("Exponent too long");
+ if (*expstart == 0)
+ ERRTO("Exponent w/ 0");
+
+ modbytes = klen - (expbytes + (expstart - cp));
+ if (modbytes < (NS_MD5RSA_MIN_BITS + 7) / 8)
+ ERRTO("Modulus too short");
+ if (modbytes > (NS_MD5RSA_MAX_BITS + 7) / 8)
+ ERRTO("Modulus too long");
+ if (*(expstart+expbytes) == 0)
+ ERRTO("Modulus starts w/ 0");
+ break;
+
+ case NS_ALG_DH: {
+ u_char *dh_cp;
+ u_int16_t dh_len, plen, glen, ulen;
+
+ dh_cp = (u_char *)cp;
+ GETSHORT(plen, dh_cp);
+ if(plen < 16)
+ ERRTO("DH short plen");
+ dh_len = 2 + plen;
+ if(dh_len > klen)
+ ERRTO("DH plen > klen");
+
+ GETSHORT(glen, dh_cp);
+ if(glen <= 0 || glen > plen)
+ ERRTO("DH glen bad");
+ dh_len = 2 + glen;
+ if(dh_len > klen)
+ ERRTO("DH glen > klen");
+
+ GETSHORT(ulen, dh_cp);
+ if(ulen <= 0 || ulen > plen)
+ ERRTO("DH ulen bad");
+ dh_len = 2 + ulen;
+ if(dh_len > klen)
+ ERRTO("DH ulen > klen");
+ else if (dh_len < klen)
+ ERRTO("DH *len < klen");
+ break;
}
- INIT_LIST(pending_notifies);
+
+ case NS_ALG_DSA: {
+ u_int8_t t;
+
+ if ( klen == 0)
+ break;
+ t = *cp;
+ if (t > 8)
+ ERRTO("DSA T value");
+ if (klen != (1 + 20 + 3 *(64+8*t)))
+ ERRTO("DSA length");
+ break;
+ }
+
+ case NS_ALG_PRIVATE_OID:
+ if (klen == 0)
+ ERRTO("No ObjectID in key");
+ break;
+ default:
+ ERRTO("Unknown Key algorithm");
+ }
+
+ endline(fp); /* flush the rest of the line */
+ return (n);
+ err:
+ *errmsg = errtype;
+ return (-1);
+} /*T_KEY*/
+
+/*
+ * function to invoke DNSSEC specific parsing routines.
+ * this is simpler than copying these complicated blocks into the
+ * multiple souce files that read files (ixfr, nsupdate etc..).
+ * this code should be in a library rather than in this file but
+ * what the heck for now (ogud@tislabs.com)
+ */
+int
+parse_sec_rdata(char *buf, int buf_len, int buf_full, u_char *data,
+ int data_size, FILE *fp, struct zoneinfo *zp,
+ char *domain, u_int32_t ttl, int type, enum context context,
+ enum transport transport, char **errmsg)
+{
+ int ret = -1;
+
+ getmlword_nesting = 0; /* KLUDGE err recov. */
+ if (!buf_full && buf && buf_len != 0) /* check if any data in buf */
+ if (!getmlword(buf, buf_len, fp, 1)) {
+ *errmsg = "unexpected end of input";
+ goto err;
+ }
+
+ switch (type) {
+ case ns_t_sig:
+ ret = parse_sig_rr(buf, buf_len, data, data_size, fp, zp,
+ domain, ttl, context, transport, errmsg);
+ break;
+ case ns_t_key:
+ ret = parse_key_rr(buf, buf_len, data, data_size, fp, zp,
+ domain, context, transport, errmsg);
+ break;
+ case ns_t_nxt:
+ ret = parse_nxt_rr(buf, buf_len, data, data_size, fp, zp,
+ domain, context, transport, errmsg);
+ break;
+ case ns_t_cert:
+ ret = parse_cert_rr(buf, buf_len, data, data_size, fp, errmsg);
+ break;
+ default:
+ ret = -1;
+ *errmsg = "parse_sec_rdata():Unsupported SEC type type";
+ goto err;
+ }
+ return (ret);
+ err:
+ endline(fp);
+ return (ret);
}
-#endif
+
OpenPOWER on IntegriCloud