Commit Diff
Diff:
4b80da13c000be9d9f5816bf5c71ef608b3337aa
93677ea47d9bf77d05d3ef6561e59d357e8106f0
Commit:
93677ea47d9bf77d05d3ef6561e59d357e8106f0
Tree:
053bf1f0a4defbdbb1b2c9f9fc594278fa9ad0af
Author:
Peter J. Philipp <pjp@delphinusdns.org>
Committer:
Peter J. Philipp <pjp@delphinusdns.org>
Date:
Mon Jan 18 14:57:27 2021 UTC
Message:
There is a circumstance where reply_refused() is called without having done any build_question() prior. The filter "" {} would core to this, this fixes it. This will be backported to 1.5.1.
blob - 71f3e6a0408fc76e8af44f32f71abac50d507f22
blob + 29eb30cadca7294e31d67960e937727531924e5c
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -142,7 +142,7 @@ extern int reply_mx(struct sreply *, int *, ddDB *);
extern int reply_naptr(struct sreply *, int *, ddDB *);
extern int reply_ns(struct sreply *, int *, ddDB *);
extern int reply_ptr(struct sreply *, int *, ddDB *);
-extern int reply_refused(struct sreply *, int *, ddDB *);
+extern int reply_refused(struct sreply *, int *, ddDB *, int);
extern int reply_srv(struct sreply *, int *, ddDB *);
extern int reply_sshfp(struct sreply *, int *, ddDB *);
extern int reply_tlsa(struct sreply *, int *, ddDB *);
@@ -1612,7 +1612,7 @@ axfrentry:
if (filter && require_tsig == 0) {
build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 0);
dolog(LOG_INFO, "UDP connection refused on descriptor %u interface \"%s\" from %s (ttl=%d, region=%d) replying REFUSED, filter policy\n", so, cfg->ident[i], address, received_ttl, aregion);
goto drop;
@@ -1621,7 +1621,7 @@ axfrentry:
if (passlist && blocklist == 0) {
build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 0);
dolog(LOG_INFO, "UDP connection refused on descriptor %u interface \"%s\" from %s (ttl=%d, region=%d) replying REFUSED, passlist policy\n", so, cfg->ident[i], address, received_ttl, aregion);
goto drop;
@@ -1719,7 +1719,7 @@ axfrentry:
case PARSE_RETURN_NOTAUTH:
if (filter && pq.tsig.have_tsig == 0) {
build_reply(&sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 0);
dolog(LOG_INFO, "UDP connection refused on descriptor %u interface \"%s\" from %s (ttl=%d, region=%d) replying REFUSED, not a tsig\n", so, cfg->ident[i], address, received_ttl, aregion);
imsg_free(&imsg);
goto drop;
@@ -1786,7 +1786,7 @@ axfrentry:
dolog(LOG_INFO, "on descriptor %u interface \"%s\" dns NOTIFY packet from %s, NOT in our list of MASTER servers replying REFUSED\n", so, cfg->ident[i], address);
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, buf, len, question, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 1);
goto udpout;
}
@@ -1843,7 +1843,7 @@ axfrentry:
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, buf, len, question, from, fromlen, rbt0, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 1);
goto udpout;
break;
case ERR_NXDOMAIN:
@@ -1881,7 +1881,7 @@ axfrentry:
if (forward)
goto forwardudp;
build_reply(&sreply, so, buf, len, question, from, fromlen, rbt1, rbt0, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, cfg->db);
+ slen = reply_refused(&sreply, &sretlen, cfg->db, 1);
snprintf(replystring, DNS_MAXNAME, "REFUSED");
}
goto udpout;
@@ -1905,7 +1905,7 @@ forwardudp:
} else {
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, buf, len, question, from, fromlen, rbt1, rbt0, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, cfg->db);
+ slen = reply_refused(&sreply, &sretlen, cfg->db, 1);
goto udpout;
}
}
@@ -2624,7 +2624,7 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf, struct
dolog(LOG_INFO, "TCP connection refused on descriptor %u interface \"%s\" from %s, filter policy, drop\n", so, cfg->ident[i], address);
#if 0
build_reply(&sreply, so, pbuf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 0);
#endif
close(so);
continue;
@@ -2818,7 +2818,7 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf, struct
case PARSE_RETURN_NOTAUTH:
if (filter && pq.tsig.have_tsig == 0) {
build_reply(&sreply, so, pbuf, len, NULL, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 0);
dolog(LOG_INFO, "TCP connection refused on descriptor %u interface \"%s\" from %s (ttl=TCP, region=%d) replying REFUSED, not a tsig\n", so, cfg->ident[tcpnp->intidx], tcpnp->address, aregion);
imsg_free(&imsg);
goto drop;
@@ -2880,7 +2880,7 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf, struct
dolog(LOG_INFO, "on TCP descriptor %u interface \"%s\" dns NOTIFY packet from %s, NOT in our list of MASTER servers replying REFUSED\n", so, cfg->ident[tcpnp->intidx], tcpnp->address);
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, pbuf, len, question, from, fromlen, NULL, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 1);
goto tcpout;
}
@@ -2946,7 +2946,7 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf, struct
case ERR_REFUSED:
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, pbuf, len, question, from, fromlen, rbt0, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, NULL);
+ slen = reply_refused(&sreply, &sretlen, NULL, 1);
goto tcpout;
break;
case ERR_NODATA:
@@ -2965,7 +2965,7 @@ tcploop(struct cfg *cfg, struct imsgbuf *ibuf, struct
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, pbuf, len, question, from, fromlen, rbt0, NULL, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, cfg->db);
+ slen = reply_refused(&sreply, &sretlen, cfg->db, 1);
}
goto tcpout;
@@ -3005,7 +3005,7 @@ forwardtcp:
} else {
snprintf(replystring, DNS_MAXNAME, "REFUSED");
build_reply(&sreply, so, pbuf, len, question, from, fromlen, rbt1, rbt0, aregion, istcp, 0, replybuf);
- slen = reply_refused(&sreply, &sretlen, cfg->db);
+ slen = reply_refused(&sreply, &sretlen, cfg->db, 1);
goto tcpout;
}
}
blob - 7bdb8079d000a2eaa9e5f648433b8f209fbbab0b
blob + 70e04e1a3e485b3c30069174fb6c510d33b4e2e5
--- regress/delphinusdnsd/Makefile
+++ regress/delphinusdnsd/Makefile
@@ -1,3 +1,3 @@
-SUBDIR= rr
+SUBDIR= rr filter
.include <bsd.subdir.mk>
blob - /dev/null
blob + 2c5353cde8bb8d31f9dc49b402ba873e053c2026 (mode 644)
--- /dev/null
+++ regress/delphinusdnsd/filter/Makefile
@@ -0,0 +1,23 @@
+DELPHINUSDNSDSRC = ${.CURDIR}/../../../delphinusdnsd
+
+.PATH: ${DELPHINUSDNSDSRC}
+
+CONFIG= filter
+
+REGRESS_TARGETS= tmpfiles
+
+CLEANFILES += tmpfiles
+
+regress: depend
+
+.for i in ${CONFIG}
+ @echo "--> testing config file $i"
+ @./run.sh $i
+.endfor
+
+tmpfiles:
+ @echo rm -f output output.2
+
+clean: tmpfiles
+
+.include <bsd.regress.mk>
blob - /dev/null
blob + 267183dcdee1c617a4bff54333384e4e9caa23af (mode 644)
--- /dev/null
+++ regress/delphinusdnsd/filter/filter
@@ -0,0 +1,21 @@
+version "1";
+options "cool stuff" {
+ versionstring "DELPHINUSDNSD - http://delphinusdns.centroid.eu";
+ interface "lo0";
+ port 9999;
+}
+
+filter "check this" {
+ 127.0.0.1;
+}
+
+zone "centroid.eu" {
+ centroid.eu,soa,3600,uranus.centroid.eu.,hostmaster.centroid.eu.,2019062701,3600,1800,7200,3600
+ centroid.eu,ns,3600,kite.centroid.eu.
+ centroid.eu,ns,3600,rhombus.centroid.eu.
+ centroid.eu,ns,3600,trapezoid.centroid.eu.
+ ;
+ centroid.eu,a,3600,200.46.208.61
+ centroid.eu,a,3600,62.75.160.180
+ ;
+}
blob - /dev/null
blob + e8a160ad1c25f9563145a1775afc26bbc9abe198 (mode 755)
--- /dev/null
+++ regress/delphinusdnsd/filter/run.sh
@@ -0,0 +1,44 @@
+#!/bin/ksh
+
+#set -x
+
+i=$1
+
+dddctl configtest $i > /dev/null
+if [ $? -eq 1 ]; then
+ echo dddctl configtest failed! 1>&2
+ exit 1
+fi
+
+dddctl start -I QWERAFSDFATETWQR -f `pwd`/$i
+#delphinusdnsd -l -f `pwd`/$i -s `pwd`/control.sock
+
+sleep 3
+
+case $1 in
+
+"filter")
+ dig -p 9999 @127.0.0.1 checkrefused.tld a | grep REFUSED
+ if [ $? -ne 0 ]; then
+ RETCODE=1
+ else
+ RETCODE=0
+ fi
+ ;;
+
+esac
+
+sleep 2
+
+dddctl stop -I QWERAFSDFATETWQR > /dev/null 2>&1
+sleep 3
+
+if [ $RETCODE -eq 0 ]; then
+ echo OK
+else
+ #cat output.2
+ echo "--> FAILURE retcode $RETCODE"
+ exit $RETCODE
+fi
+
+exit 0
blob - 7a79a2fa7bf1ecc21357a609dc67c4ef45656bd3
blob + 1d49bc93532b1b40aa3436615b6c5291513f3de2
--- reply.c
+++ reply.c
@@ -138,7 +138,7 @@ int reply_sshfp(struct sreply *, int *, ddDB *);
int reply_tlsa(struct sreply *, int *, ddDB *);
int reply_cname(struct sreply *, int *, ddDB *);
int reply_any(struct sreply *, int *, ddDB *);
-int reply_refused(struct sreply *, int *, ddDB *);
+int reply_refused(struct sreply *, int *, ddDB *, int);
int reply_fmterror(struct sreply *, int *, ddDB *);
int reply_notauth(struct sreply *, int *, ddDB *);
int reply_notify(struct sreply *, int *, ddDB *);
@@ -5791,7 +5791,7 @@ out:
*/
int
-reply_refused(struct sreply *sreply, int *sretlen, ddDB *db)
+reply_refused(struct sreply *sreply, int *sretlen, ddDB *db, int haveq)
{
char *reply = sreply->replybuf;
struct dns_header *odh;
@@ -5821,8 +5821,13 @@ reply_refused(struct sreply *sreply, int *sretlen, ddD
}
- memcpy(&reply[0], buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
- outlen += (sizeof(struct dns_header) + q->hdr->namelen + 4);
+ if (haveq) {
+ memcpy(&reply[0], buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
+ outlen += (sizeof(struct dns_header) + q->hdr->namelen + 4);
+ } else {
+ memcpy(&reply[0], buf, len);
+ outlen += len;
+ }
memset((char *)&odh->query, 0, sizeof(u_int16_t));
SET_DNS_RCODE_REFUSED(odh);
@@ -5832,9 +5837,12 @@ reply_refused(struct sreply *sreply, int *sretlen, ddD
odh->nsrr = 0; /* reset any authoritave */
odh->additional = 0; /* reset any additionals */
- set_reply_flags(NULL, odh, q);
+ if (haveq)
+ set_reply_flags(NULL, odh, q);
+ else
+ odh->question = htons(1);
- if (q->edns0len) {
+ if (haveq && q->edns0len) {
/* tag on edns0 opt record */
odh->additional = htons(1);
@@ -5859,7 +5867,7 @@ reply_refused(struct sreply *sreply, int *sretlen, ddD
}
free(tmpbuf);
} else {
- if (q->rawsocket) {
+ if (haveq && q->rawsocket) {
*sretlen = retlen = outlen;
} else {
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
repomaster@centroid.eu