Commit Diff
Diff:
63fcbadbaf50917680bf9173bf3c589936c93c30
300f70a6507a03c9b486e640cabcea062aed47d2
Commit:
300f70a6507a03c9b486e640cabcea062aed47d2
Tree:
b4add73e1e0619fdb4dd2a5bb383bfaac043b409
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Tue Feb 26 07:45:56 2019 UTC
Message:
TSIG support for notify (part of axfr.c), while we did that improve TSIG considerably.
blob - 5c04605229730524124f8e001c8b6f560e202889
blob + 2e7ca6073a4164d30b96b25cf9b09255c2ede7e8
--- additional.c
+++ additional.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: additional.c,v 1.22 2019/02/24 14:53:02 pjp Exp $
+ * $Id: additional.c,v 1.23 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -442,7 +442,11 @@ additional_tsig(struct question *question, char *reply
/* rdlen */
sval = (u_int16_t *)&reply[offset];
- *sval = htons(2 + 8 + question->tsig.tsigalglen + question->tsig.tsigmaclen + 2 + 2 + 2);
+ if (question->tsig.tsigerrorcode == DNS_BADTIME) {
+ *sval = htons(2 + 8 + question->tsig.tsigalglen + question->tsig.tsigmaclen + 2 + 2 + 2 + 6);
+ } else {
+ *sval = htons(2 + 8 + question->tsig.tsigalglen + question->tsig.tsigmaclen + 2 + 2 + 2);
+ }
offset += 2;
memcpy(&reply[offset], question->tsig.tsigalg, question->tsig.tsigalglen);
@@ -451,10 +455,14 @@ additional_tsig(struct question *question, char *reply
memcpy(&pseudo_packet[ppoffset], question->tsig.tsigalg, question->tsig.tsigalglen);
ppoffset += question->tsig.tsigalglen;
- now = time(NULL);
answer = (struct dns_tsigrr *)&reply[offset];
- answer->timefudge = htobe64((u_int64_t)(now << 16) | (300 & 0xffff));
+ if (request == 0) {
+ answer->timefudge = question->tsig.tsig_timefudge;
+ } else {
+ now = time(NULL);
+ answer->timefudge = htobe64((now << 16) | (300 & 0xffff));
+ }
answer->macsize = htons(question->tsig.tsigmaclen);
offset += (8 + 2);
@@ -469,12 +477,32 @@ additional_tsig(struct question *question, char *reply
*sval = htons(question->tsig.tsigerrorcode);
offset += 2;
- sval = (u_int16_t *)&reply[offset];
- *sval = htons(0);
- offset += 2;
+ if (question->tsig.tsigerrorcode == DNS_BADTIME) {
+ now = time(NULL);
+ sval = (u_int16_t *)&reply[offset];
+ *sval = htons(6);
+ offset += 2;
+
+ sval = (u_int16_t *)&reply[offset];
+ *sval = 0;
+ offset += 2;
+
+ lval = (u_int32_t *)&reply[offset];
+ *lval = htonl(now & 0xffffffff);
+ offset += 4;
+
+ } else {
+ sval = (u_int16_t *)&reply[offset];
+ *sval = htons(0);
+ offset += 2;
+ }
+
ppanswer = (struct dns_tsigrr *)&pseudo_packet[ppoffset];
- ppanswer->timefudge = htobe64((u_int64_t)(now << 16) | (300 & 0xffff));
+ if (request == 0)
+ ppanswer->timefudge = question->tsig.tsig_timefudge;
+ else
+ ppanswer->timefudge = htobe64((now << 16) | (300 & 0xffff));
ppoffset += 8;
@@ -484,10 +512,23 @@ additional_tsig(struct question *question, char *reply
ppoffset += 2;
/* other len */
- sval = (u_int16_t *)&pseudo_packet[ppoffset];
- *sval = htons(0);
- ppoffset += 2;
+ if (question->tsig.tsigerrorcode == DNS_BADTIME) {
+ sval = (u_int16_t *)&pseudo_packet[ppoffset];
+ *sval = htons(6);
+ ppoffset += 2;
+ sval = (u_int16_t *)&pseudo_packet[ppoffset];
+ *sval = 0;
+ ppoffset += 2;
+
+ lval = (u_int32_t *)&pseudo_packet[ppoffset];
+ *lval = htonl(now & 0xffffffff);
+ ppoffset += 4;
+ } else {
+ sval = (u_int16_t *)&pseudo_packet[ppoffset];
+ *sval = htons(0);
+ ppoffset += 2;
+ }
if (question->tsig.tsigerrorcode == DNS_BADTIME) {
HMAC(EVP_sha256(), tsigkey, tsignamelen,
@@ -499,6 +540,8 @@ additional_tsig(struct question *question, char *reply
HMAC(EVP_sha256(), tsigkey, tsignamelen,
(unsigned char *)pseudo_packet, ppoffset,
(unsigned char *)&answer->mac[0], (u_int *)&macsize);
+
+ memcpy(question->tsig.tsigmac, &answer->mac[0], macsize);
}
free(pseudo_packet);
blob - 02818668e483a78f24add75fe15cbc7a9407781c
blob + 64bad536e064659bbe6f626bcaf69c28df87b0c9
--- axfr.c
+++ axfr.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: axfr.c,v 1.21 2019/02/19 11:49:54 pjp Exp $
+ * $Id: axfr.c,v 1.22 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -45,7 +45,7 @@ void gather_notifydomains(ddDB *);
void init_axfr(void);
void init_notifyslave(void);
int insert_axfr(char *, char *);
-int insert_notifyslave(char *, char *);
+int insert_notifyslave(char *, char *, char *);
void notifypacket(int, void *, void *, int);
void notifyslaves(int *);
void reap(int);
@@ -58,8 +58,8 @@ extern void reply_nxdomain(struct sreply *, ddDB *);
extern struct rbtree * get_soa(ddDB *, struct question *);
extern int compress_label(u_char *, int, int);
extern u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
-extern struct question *build_fake_question(char *, int, u_int16_t);
-extern struct question *build_question(char *, int, int);
+extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
+extern struct question *build_question(char *, int, int, char *);
extern int free_question(struct question *);
extern void dolog(int, char *, ...);
extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct rbtree *, struct rbtree *, u_int8_t, int, int, struct recurses *);
@@ -70,13 +70,16 @@ extern int display_rr(struct rrset *rrset);
extern int rotate_rr(struct rrset *rrset);
extern int domaincmp(struct node *e1, struct node *e2);
+extern char * dns_label(char *, int *);
+extern int additional_tsig(struct question *, char *, int, int, int);
int notify = 0; /* do not notify when set to 0 */
extern int debug, verbose;
extern time_t time_changed;
+extern int tsig;
-SLIST_HEAD(listhead, axfrentry) axfrhead;
+SLIST_HEAD(, axfrentry) axfrhead;
static struct axfrentry {
char name[INET6_ADDRSTRLEN];
@@ -87,7 +90,7 @@ static struct axfrentry {
SLIST_ENTRY(axfrentry) axfr_entry;
} *an2, *anp;
-SLIST_HEAD(notifyslavelisthead, notifyslaveentry) notifyslavehead;
+SLIST_HEAD(, notifyslaveentry) notifyslavehead;
static struct notifyslaveentry {
char name[INET6_ADDRSTRLEN];
@@ -95,6 +98,9 @@ static struct notifyslaveentry {
struct sockaddr_storage hostmask;
struct sockaddr_storage netmask;
u_int8_t prefixlen;
+ char *tsigname;
+ int tsignamelen;
+ char tsigrequestmac[32];
SLIST_ENTRY(notifyslaveentry) notifyslave_entry;
} *nfslnp2, *nfslnp;
@@ -113,6 +119,7 @@ static struct notifyentry {
extern int domaincmp(struct node *e1, struct node *e2);
static int check_notifyreply(struct dns_header *, struct question *, struct sockaddr_storage *, int, struct notifyentry *, int);
+
/*
* INIT_AXFR - initialize the axfr singly linked list
*/
@@ -262,13 +269,19 @@ init_notifyslave(void)
*/
int
-insert_notifyslave(char *address, char *prefixlen)
+insert_notifyslave(char *address, char *prefixlen, char *tsigkey)
{
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
- int pnum;
+ int pnum, tsignamelen;
int ret;
+ tsignamelen = strlen(tsigkey);
+ if (strcmp(tsigkey, "NOKEY") == 0) {
+ tsigkey = NULL;
+ tsignamelen = 0;
+ }
+
pnum = atoi(prefixlen);
nfslnp2 = calloc(1, sizeof(struct notifyslaveentry)); /* Insert after. */
if (nfslnp2 == NULL)
@@ -301,6 +314,17 @@ insert_notifyslave(char *address, char *prefixlen)
}
+ if (tsignamelen != 0) {
+ nfslnp2->tsigname = dns_label(tsigkey, &tsignamelen);
+ if (nfslnp2->tsigname == NULL) {
+ return -1;
+ }
+ nfslnp2->tsignamelen = tsignamelen;
+ } else {
+ nfslnp2->tsigname = NULL;
+ nfslnp2->tsignamelen = 0;
+ }
+
SLIST_INSERT_HEAD(&notifyslavehead, nfslnp2, notifyslave_entry);
return (0);
@@ -329,6 +353,7 @@ axfrloop(int *afd, int sockcount, char **ident, ddDB *
socklen_t fromlen;
char buf[512];
char *packet;
+ char requestmac[32];
time_t now;
pid_t pid;
@@ -610,7 +635,21 @@ axfrloop(int *afd, int sockcount, char **ident, ddDB *
continue;
}
- question = build_question(buf, len, ntohs(dh->additional));
+ /* get our request mac */
+ SLIST_FOREACH(nfslnp, &notifyslavehead, notifyslave_entry) {
+ struct sockaddr_in *sin2 = (struct sockaddr_in *)&nfslnp->hostmask;
+
+ if (memcmp((char *)&sin->sin_addr.s_addr, (char *)&sin2->sin_addr.s_addr, sizeof(struct in_addr)) == 0) {
+ memcpy(requestmac, nfslnp->tsigrequestmac, 32);
+ break;
+ }
+ }
+
+ if (nfslnp == NULL)
+ question = build_question(buf, len, ntohs(dh->additional), NULL);
+ else
+ question = build_question(buf, len, ntohs(dh->additional), requestmac);
+
if (question == NULL) {
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
continue;
@@ -672,14 +711,28 @@ axfrloop(int *afd, int sockcount, char **ident, ddDB *
continue;
}
- question = build_question(buf, len, ntohs(dh->additional));
+ sin6 = (struct sockaddr_in6 *)&from;
+ inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
+
+ /* get our request mac */
+ SLIST_FOREACH(nfslnp, &notifyslavehead, notifyslave_entry) {
+ struct sockaddr_in6 *sin2 = (struct sockaddr_in6 *)&nfslnp->hostmask;
+
+ if (memcmp((char *)&sin6->sin6_addr, (char *)&sin2->sin6_addr, sizeof(struct in6_addr)) == 0) {
+ memcpy(requestmac, nfslnp->tsigrequestmac, 32);
+ break;
+ }
+ }
+
+ if (nfslnp == NULL)
+ question = build_question(buf, len, ntohs(dh->additional), NULL);
+ else
+ question = build_question(buf, len, ntohs(dh->additional), requestmac);
if (question == NULL) {
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
continue;
}
- sin6 = (struct sockaddr_in6 *)&from;
- inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
#ifdef __linux
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
@@ -805,7 +858,7 @@ axfr_connection(int so, char *address, int is_ipv6, dd
goto drop;
}
- if ((question = build_question((p + 2), dnslen, 0)) == NULL) {
+ if ((question = build_question((p + 2), dnslen, 0, NULL)) == NULL) {
dolog(LOG_INFO, "AXFR malformed question, drop\n");
goto drop;
}
@@ -917,7 +970,7 @@ axfr_connection(int so, char *address, int is_ipv6, dd
memcpy((char*)saverbt,(char*)n->data, sizeof(struct rbtree));
if (checklabel(db, rbt, soa, question)) {
- fq = build_fake_question(rbt->zone, rbt->zonelen, 0);
+ fq = build_fake_question(rbt->zone, rbt->zonelen, 0, NULL, 0);
build_reply(&sreply, so, (p + 2), dnslen, fq, NULL, 0, rbt, NULL, 0xff, 1, 0, NULL);
outlen = create_anyreply(&sreply, (reply + 2), 65535, outlen, 0);
free_question(fq);
@@ -928,7 +981,7 @@ axfr_connection(int so, char *address, int is_ipv6, dd
((struct ns *)rrp->rdata)->ns_type & NS_TYPE_DELEGATE) {
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
fq = build_fake_question(((struct ns *)rrp->rdata)->nsserver,
- ((struct ns *)rrp->rdata)->nslen, 0);
+ ((struct ns *)rrp->rdata)->nslen, 0, NULL, 0);
rbt2 = find_rrset(db, fq->hdr->name, fq->hdr->namelen);
if (rbt2 == NULL) {
free_question(fq);
@@ -1389,6 +1442,7 @@ notifypacket(int so, void *vnse, void *vnotnp, int pac
char *questionname;
u_int16_t *classtype;
struct dns_header *dnh;
+ struct question *fq = NULL;
int outlen = 0, slen, ret;
memset(&packet, 0, sizeof(packet));
@@ -1413,6 +1467,21 @@ notifypacket(int so, void *vnse, void *vnotnp, int pac
classtype[1] = htons(DNS_CLASS_IN);
outlen += (2 * sizeof(u_int16_t));
+
+ /* work out the tsig stuff */
+ if (nse->tsignamelen != 0) {
+ if ((fq = build_fake_question(notnp->domain, notnp->domainlen, 0, nse->tsigname, nse->tsignamelen)) == NULL) {
+ return;
+ }
+
+ outlen = additional_tsig(fq, packet, sizeof(packet), outlen, 1);
+
+ dnh->additional = htons(1);
+
+ memcpy(nse->tsigrequestmac, fq->tsig.tsigmac, 32);
+
+ free_question(fq);
+ }
if (nse->family == AF_INET) {
slen = sizeof(struct sockaddr_in);
@@ -1478,6 +1547,11 @@ check_notifyreply(struct dns_header *dh, struct questi
#else
SLIST_FOREACH_SAFE(nfslnp, &notifyslavehead, notifyslave_entry, nfslnp2) {
#endif
+ if (tsig && nfslnp->tsignamelen != 0 && question->tsig.tsigverified != 1) {
+ dolog(LOG_ERR, "tsig'ed notify answer was not validated, errorcode = %02x\n", question->tsig.tsigerrorcode);
+ continue;
+ }
+
if (nfslnp->family != af)
continue;
blob - 8079b6973dfc5848814f8eded406fec23d05ec9d
blob + bfa0b8f85f3ff6e307edc3f270f347c91ee56e47
--- dddctl.c
+++ dddctl.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: dddctl.c,v 1.56 2019/02/24 07:14:02 pjp Exp $
+ * $Id: dddctl.c,v 1.57 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -252,7 +252,7 @@ extern char * convert_name(char *name, int namelen);
extern int mybase64_encode(u_char const *, size_t, char *, size_t);
extern int mybase64_decode(char const *, u_char *, size_t);
extern struct rbtree * lookup_zone(ddDB *, struct question *, int *, int *, char *);
-extern struct question *build_fake_question(char *, int, u_int16_t);
+extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
extern char * dns_label(char *, int *);
extern int label_count(char *);
extern char *get_dns_type(int, int);
@@ -260,7 +260,7 @@ extern char * hash_name(char *, int, struct nsec3param
extern char * base32hex_encode(u_char *input, int len);
extern int init_entlist(ddDB *);
extern int check_ent(char *, int);
-extern struct question *build_question(char *, int, int);
+extern struct question *build_question(char *, int, int, char *);
extern int free_question(struct question *);
struct rrtab *rrlookup(char *);
@@ -1036,7 +1036,7 @@ dump_db(ddDB *db, FILE *of, char *zonename)
if (dnsname == NULL)
return -1;
- q = build_fake_question(dnsname, labellen, DNS_TYPE_SOA);
+ q = build_fake_question(dnsname, labellen, DNS_TYPE_SOA, NULL, 0);
if (q == NULL) {
return -1;
}
@@ -5186,7 +5186,7 @@ create_ds(ddDB *db, char *zonename, struct keysentry *
return -1;
}
- qp = build_fake_question(dnsname, labellen, DNS_TYPE_SOA);
+ qp = build_fake_question(dnsname, labellen, DNS_TYPE_SOA, NULL, 0);
if (qp == NULL) {
dolog(LOG_INFO, "qp == NULL\n");
return -1;
@@ -6090,7 +6090,7 @@ construct_nsec3(ddDB *db, char *zone, int iterations,
if (dnsname == NULL)
return -1;
- q = build_fake_question(dnsname, labellen, DNS_TYPE_NSEC3PARAM);
+ q = build_fake_question(dnsname, labellen, DNS_TYPE_NSEC3PARAM, NULL, 0);
if (q == NULL) {
return -1;
}
@@ -7061,7 +7061,7 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
segmentcount = ntohs(rwh->dh.answer);
answers += segmentcount;
- q = build_question((char *)&wh->dh, len, wh->dh.additional);
+ q = build_question((char *)&wh->dh, len, wh->dh.additional, NULL);
if (q == NULL) {
fprintf(stderr, "failed to build_question\n");
return -1;
@@ -7324,7 +7324,7 @@ lookup_name(FILE *f, int so, char *zonename, u_int16_t
}
- q = build_question((char *)&wh->dh, len, wh->dh.additional);
+ q = build_question((char *)&wh->dh, len, wh->dh.additional, NULL);
if (q == NULL) {
fprintf(stderr, "failed to build_question\n");
return -1;
@@ -7849,7 +7849,7 @@ dump_db_bind(ddDB *db, FILE *of, char *zonename)
if (dnsname == NULL)
return -1;
- q = build_fake_question(dnsname, labellen, DNS_TYPE_SOA);
+ q = build_fake_question(dnsname, labellen, DNS_TYPE_SOA, NULL, 0);
if (q == NULL) {
return -1;
}
blob - 519f3d47116ff6553eaff44ea4e74c691f45d373
blob + ee3e0d651e8e35baa3974cd8a6062ecf5c41731c
--- delphinusdns.conf.5
+++ delphinusdns.conf.5
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2014-2018 Peter J. Philipp
+.\" Copyright (c) 2014-2019 Peter J. Philipp
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -72,7 +72,7 @@ axfr-for "these hosts" {
notify "these hosts" {
192.168.34.1;
- 192.168.35.1;
+ 192.168.35.1 DNSKEY;
::1;
}
@@ -203,7 +203,7 @@ axfr-for "these hosts" {
axfrport "10053";
notify "these hosts" {
- 10.110.99.88;
+ 10.110.99.88 DNSKEY;
::1;
}
@@ -243,11 +243,14 @@ ttl = number
region = "region" ("string") [ "{" cidrlist "}"
+
cidrlist = { [ cidr-address ] ; ... }
axfr = "axfr-for" ("string") [ "{" cidrlist "}" ]
-notify = "notify" ("string") [ "{" cidrlist "}" ]
+notifylist = { [ cidr-address ] [ tsig-keyname ] ; ... }
+
+notify = "notify" ("string") [ "{" notifylist "}" ]
whitelist = "whitelist" ("string") [ "{" cidrlist "}" ]
blob - 2211883c3d2647961f6f97c149cfe1b98785a62c
blob + d2fa843d04677f9c1d38d5211f7bbde3dc39a7bb
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.58 2019/02/24 14:53:02 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.59 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -39,7 +39,7 @@
extern void add_rrlimit(int, u_int16_t *, int, char *);
extern void axfrloop(int *, int, char **, ddDB *, struct imsgbuf *);
-extern struct question *build_fake_question(char *, int, u_int16_t);
+extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
extern int check_ent(char *, int);
extern int check_rrlimit(int, u_int16_t *, int, char *);
extern void collects_init(void);
@@ -93,7 +93,7 @@ extern char *rrlimit_setup(int);
extern char *dns_label(char *, int *);
extern void slave_shutdown(void);
extern int get_record_size(ddDB *, char *, int);
-extern struct question *build_question(char *, int, int);
+extern struct question *build_question(char *, int, int, char *);
extern int free_question(struct question *);
extern struct rbtree * create_rr(ddDB *db, char *name, int len, int type, void *rdata);
extern struct rbtree * find_rrset(ddDB *db, char *name, int len);
@@ -1917,7 +1917,7 @@ axfrentry:
if (rr_csd == NULL)
break;
- fakequestion = build_fake_question(((struct cname *)rr_csd)->cname, ((struct cname *)rr_csd)->cnamelen, question->hdr->qtype);
+ fakequestion = build_fake_question(((struct cname *)rr_csd)->cname, ((struct cname *)rr_csd)->cnamelen, question->hdr->qtype, NULL, 0);
if (fakequestion == NULL) {
dolog(LOG_INFO, "fakequestion failed\n");
break;
@@ -2777,7 +2777,7 @@ tcploop(struct cfg *cfg, struct imsgbuf **ibuf)
if (rr_csd == NULL)
break;
- fakequestion = build_fake_question(((struct cname *)rr_csd)->cname, ((struct cname *)rr_csd)->cnamelen, question->hdr->qtype);
+ fakequestion = build_fake_question(((struct cname *)rr_csd)->cname, ((struct cname *)rr_csd)->cnamelen, question->hdr->qtype, NULL, 0);
if (fakequestion == NULL) {
dolog(LOG_INFO, "fakequestion failed\n");
break;
@@ -3024,7 +3024,7 @@ parseloop(struct cfg *cfg, struct imsgbuf **ibuf)
break;
}
- if ((question = build_question(packet, datalen, ntohs(dh->additional))) == NULL) {
+ if ((question = build_question(packet, datalen, ntohs(dh->additional), NULL)) == NULL) {
/* XXX reply nak here */
pq.rc = PARSE_RETURN_MALFORMED;
imsg_compose(mybuf, IMSG_PARSEREPLY_MESSAGE, 0, 0, -1, &pq, sizeof(struct parsequestion));
blob - 3f2132a5939808015d4626cc07d639bd656644f7
blob + 05321c9ebab13d424522da767cc5ad078da70010
--- dnssec.c
+++ dnssec.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: dnssec.c,v 1.22 2019/02/18 14:59:55 pjp Exp $
+ * $Id: dnssec.c,v 1.23 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -63,7 +63,6 @@ extern int get_record_size(ddDB *, char *
extern char * dns_label(char *, int *);
extern void dolog(int, char *, ...);
extern int checklabel(ddDB *, struct rbtree *, struct rbtree *, struct question *);
-extern struct question *build_fake_question(char *, int, u_int16_t);
extern int free_question(struct question *);
extern int check_ent(char *, int);
extern int memcasecmp(u_char *, u_char *, int);
blob - 1359d2929aecbfcf2a76561d91171a9dab49de5a
blob + d2509f48a73b67ea5e399af6f54581e7555d6615
--- parse.y
+++ parse.y
@@ -21,7 +21,7 @@
*/
/*
- * $Id: parse.y,v 1.62 2019/02/24 07:14:02 pjp Exp $
+ * $Id: parse.y,v 1.63 2019/02/26 07:45:56 pjp Exp $
*/
%{
@@ -41,7 +41,7 @@ extern int insert_apex(char *, char *, int);
extern int insert_nsec3(char *, char *, char *, int);
extern int insert_region(char *, char *, u_int8_t);
extern int insert_axfr(char *, char *);
-extern int insert_notifyslave(char *, char *);
+extern int insert_notifyslave(char *, char *, char *);
extern int insert_filter(char *, char *);
extern int insert_whitelist(char *, char *);
extern int insert_tsig(char *, char *);
@@ -1305,7 +1305,7 @@ notifystatements :
| notifystatement
;
-notifystatement : ipcidr SEMICOLON CRLF
+notifystatement : ipcidr STRING SEMICOLON CRLF
{
char prefixlength[INET_ADDRSTRLEN];
char *dst;
@@ -1316,7 +1316,7 @@ notifystatement : ipcidr SEMICOLON CRLF
return (-1);
}
- if (insert_notifyslave(dst, prefixlength) < 0) {
+ if (insert_notifyslave(dst, prefixlength, $2) < 0) {
dolog(LOG_ERR, "insert_notifyslave, line %d\n", file->lineno);
return (-1);
}
@@ -1327,6 +1327,7 @@ notifystatement : ipcidr SEMICOLON CRLF
}
free ($1);
+ free ($2);
}
| comment CRLF
;
@@ -1473,7 +1474,7 @@ struct tab cmdtab[] = {
{ "version", VERSION, 0 },
{ "zinclude", ZINCLUDE, 0 },
{ "zone", ZONE, 0 },
- { "notify", NOTIFY, STATE_IP },
+ { "notify", NOTIFY, 0 },
{ NULL, 0, 0}};
blob - 0858dd6a045ff33677b9d54026ce8b97c11e756d
blob + 679360acbd7a3e8b96ddb74ceb8cbd44ee6cbbe7
--- reply.c
+++ reply.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: reply.c,v 1.71 2019/02/24 14:53:02 pjp Exp $
+ * $Id: reply.c,v 1.72 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -47,7 +47,7 @@ extern int additional_opt(struct question *, char *,
extern int additional_tsig(struct question *, char *, int, int, int);
extern int additional_rrsig(char *, int, int, struct rbtree *, char *, int, int, int);
extern int additional_nsec(char *, int, int, struct rbtree *, char *, int, int);
-extern struct question *build_fake_question(char *, int, u_int16_t);
+extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
extern int compress_label(u_char *, int, int);
extern void dolog(int, char *, ...);
extern int free_question(struct question *);
@@ -4965,7 +4965,7 @@ Lookup_zone(ddDB *db, char *name, u_int16_t namelen, u
int mytype;
int lzerrno;
- fakequestion = build_fake_question(name, namelen, type);
+ fakequestion = build_fake_question(name, namelen, type, NULL, 0);
if (fakequestion == NULL) {
dolog(LOG_INFO, "fakequestion(2) failed\n");
return (NULL);
blob - 8e477db73ec92ddd198934c66107dea0f50925a7
blob + 0f4c77a6594bf3fa37c79bf2bc5bca6a4213750e
--- util.c
+++ util.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: util.c,v 1.25 2019/02/24 14:53:03 pjp Exp $
+ * $Id: util.c,v 1.26 2019/02/26 07:45:56 pjp Exp $
*/
#include "ddd-include.h"
@@ -47,11 +47,11 @@ void slave_shutdown(void);
int get_record_size(ddDB *, char *, int);
struct rbtree * lookup_zone(ddDB *, struct question *, int *, int *, char *);
u_int16_t check_qtype(struct rbtree *, u_int16_t, int, int *);
-struct question *build_fake_question(char *, int, u_int16_t);
+struct question *build_fake_question(char *, int, u_int16_t, char *, int);
char *get_dns_type(int, int);
int memcasecmp(u_char *, u_char *, int);
-struct question *build_question(char *, int, int);
+struct question *build_question(char *, int, int, char *);
int free_question(struct question *);
struct rrtab *rrlookup(char *);
char * expand_compression(u_char *, u_char *, u_char *, u_char *, int *, int);
@@ -520,7 +520,7 @@ check_qtype(struct rbtree *rbt, u_int16_t type, int nx
*/
struct question *
-build_fake_question(char *name, int namelen, u_int16_t type)
+build_fake_question(char *name, int namelen, u_int16_t type, char *tsigkey, int tsigkeylen)
{
struct question *q;
@@ -553,7 +553,34 @@ build_fake_question(char *name, int namelen, u_int16_t
q->hdr->qtype = type;
q->hdr->qclass = htons(DNS_CLASS_IN);
+ if (tsig) {
+ char *alg;
+ int alglen;
+
+ if (tsigkeylen > sizeof(q->tsig.tsigkey)) {
+ free(q->hdr->name);
+ free(q->hdr);
+ free(q);
+ return NULL;
+ }
+
+ memcpy(&q->tsig.tsigkey, tsigkey, tsigkeylen);
+ q->tsig.tsigkeylen = tsigkeylen;
+
+ alg = dns_label("hmac-sha256.", &alglen);
+
+ if (alg != NULL) {
+ memcpy (&q->tsig.tsigalg, alg, alglen);
+ q->tsig.tsigalglen = alglen;
+
+ free(alg);
+
+ q->tsig.tsigmaclen = 32;
+ }
+ }
+
return (q);
+
}
/*
@@ -625,7 +652,7 @@ memcasecmp(u_char *b1, u_char *b2, int len)
*/
struct question *
-build_question(char *buf, int len, int additional)
+build_question(char *buf, int len, int additional, char *mac)
{
char pseudo_packet[4096]; /* for tsig */
u_int rollback, i;
@@ -970,13 +997,6 @@ build_question(char *buf, int len, int additional)
q->tsig.tsig_timefudge = tsigrr->timefudge;
- now = time(NULL);
- /* outside our fudge window */
- if (tsigtime < (now - fudge) || tsigtime > (now + fudge)) {
- q->tsig.tsigerrorcode = DNS_BADTIME;
- break;
- }
-
i += (8 + 2); /* timefudge + macsize */
if (ntohs(tsigrr->macsize) != 32) {
@@ -1007,8 +1027,20 @@ build_question(char *buf, int len, int additional)
tsigotherlen = (u_int16_t *)&buf[i];
i += 2;
- memcpy(pseudo_packet, buf, pseudolen1);
- ppoffset = pseudolen1;
+ ppoffset = 0;
+
+ /* check if we have a request mac, this means it's an answer */
+ if (mac) {
+ val16 = (u_int16_t *)&pseudo_packet[ppoffset];
+ *val16 = htons(32); /* XXX magic number */
+ ppoffset += 2;
+
+ memcpy(&pseudo_packet[ppoffset], mac, 32);
+ ppoffset += 32;
+ }
+
+ memcpy(&pseudo_packet[ppoffset], buf, pseudolen1);
+ ppoffset += pseudolen1;
memcpy((char *)&pseudo_packet[ppoffset], &buf[pseudolen2], 6);
ppoffset += 6;
@@ -1029,12 +1061,17 @@ build_question(char *buf, int len, int additional)
memcpy(&pseudo_packet[ppoffset], &buf[i], len - i);
ppoffset += (len - i);
+
HMAC(EVP_sha256(), tsigkey, tsignamelen, (unsigned char *)pseudo_packet,
ppoffset, (unsigned char *)&sha256, &shasize);
+#if __OpenBSD__
+ if (timingsafe_memcmp(sha256, tsigrr->mac, sizeof(sha256)) != 0) {
+#else
if (memcmp(sha256, tsigrr->mac, sizeof(sha256)) != 0) {
+#endif
#if DEBUG
dolog(LOG_INFO, "HMAC did not verify\n");
#endif
@@ -1045,6 +1082,19 @@ build_question(char *buf, int len, int additional)
/* copy the mac for error coding */
memcpy(q->tsig.tsigmac, tsigrr->mac, sizeof(q->tsig.tsigmac));
q->tsig.tsigmaclen = 32;
+
+ /*
+ * here we have a delayed fudge check, we want to ensure
+ * that the signature checked out before we give out a
+ * BADTIME message, otherwise it is BADKEY or BADSIG
+ */
+
+ now = time(NULL);
+ /* outside our fudge window */
+ if (tsigtime < (now - fudge) || tsigtime > (now + fudge)) {
+ q->tsig.tsigerrorcode = DNS_BADTIME;
+ break;
+ }
/* we're now authenticated */
q->tsig.tsigerrorcode = 0;
repomaster@centroid.eu