mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-11 06:43:40 -05:00
extremely lenient for truncated positive replies
git-svn-id: file:///svn/unbound/trunk@1670 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
efcb61fb22
commit
e0bc4f2c97
3 changed files with 199 additions and 4 deletions
|
|
@ -2,6 +2,9 @@
|
|||
- Fix of message parse bug where (specifically) an NSEC and RRSIG
|
||||
in the wrong order would be parsed, but put wrongly into internal
|
||||
structures so that later validation would fail.
|
||||
- Extreme lenience for wrongly truncated replies where a positive
|
||||
reply has an NS in the authority but no signatures. They are
|
||||
turned into minimal responses with only the (secure) answer.
|
||||
|
||||
17 June 2009: Wouter
|
||||
- CREDITS entry for cz.nic, sponsoring a 'summer of code' that was
|
||||
|
|
|
|||
148
testdata/val_pos_truncns.rpl
vendored
Normal file
148
testdata/val_pos_truncns.rpl
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with badly truncated positive response
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
|
||||
; Truncated, no signature for NS record.
|
||||
;;;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
;;;SECTION ADDITIONAL
|
||||
;;;ns.example.com. IN A 1.2.3.4
|
||||
;;;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
@ -478,6 +478,36 @@ validate_msg_signatures(struct module_env* env, struct val_env* ve,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect wrong truncated response, by a bad recursor out there.
|
||||
* The positive response has a mangled authority section.
|
||||
* Remove that authority section.
|
||||
* @param rep: reply
|
||||
* @return true if a wrongly truncated response.
|
||||
*/
|
||||
static int
|
||||
detect_wrongly_truncated(struct reply_info* rep)
|
||||
{
|
||||
size_t i;
|
||||
/* no additional, only NS in authority, and it is bogus */
|
||||
if(rep->ar_numrrsets != 0 || rep->ns_numrrsets != 1 ||
|
||||
rep->an_numrrsets == 0)
|
||||
return 0;
|
||||
if(ntohs(rep->rrsets[ rep->an_numrrsets ]->rk.type) != LDNS_RR_TYPE_NS)
|
||||
return 0;
|
||||
if(((struct packed_rrset_data*)rep->rrsets[ rep->an_numrrsets ]
|
||||
->entry.data)->security != sec_status_bogus)
|
||||
return 0;
|
||||
/* answer section is present and secure */
|
||||
for(i=0; i<rep->an_numrrsets; i++) {
|
||||
if(((struct packed_rrset_data*)rep->rrsets[ i ]
|
||||
->entry.data)->security != sec_status_secure)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a "positive" response -- a response that contains an answer to the
|
||||
* question, and no CNAME chain, validate this response.
|
||||
|
|
@ -1449,17 +1479,31 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
vq->chase_reply->security = sec_status_bogus;
|
||||
return 1;
|
||||
}
|
||||
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
||||
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
|
||||
|
||||
/* check signatures in the message;
|
||||
* answer and authority must be valid, additional is only checked. */
|
||||
if(!validate_msg_signatures(qstate->env, ve, &vq->qchase,
|
||||
vq->chase_reply, vq->key_entry)) {
|
||||
verbose(VERB_DETAIL, "Validate: message contains bad rrsets");
|
||||
return 1;
|
||||
/* workaround bad recursor out there that truncates (even
|
||||
* with EDNS4k) to 512 by removing RRSIG from auth section
|
||||
* for positive replies*/
|
||||
if(subtype == VAL_CLASS_POSITIVE &&
|
||||
detect_wrongly_truncated(vq->orig_msg->rep)) {
|
||||
/* truncate the message some more */
|
||||
vq->orig_msg->rep->ns_numrrsets = 0;
|
||||
vq->orig_msg->rep->rrset_count--;
|
||||
vq->chase_reply->ns_numrrsets = 0;
|
||||
vq->chase_reply->rrset_count--;
|
||||
}
|
||||
else {
|
||||
verbose(VERB_DETAIL, "Validate: message contains "
|
||||
"bad rrsets");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
||||
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
|
||||
switch(subtype) {
|
||||
case VAL_CLASS_POSITIVE:
|
||||
verbose(VERB_ALGO, "Validating a positive response");
|
||||
|
|
|
|||
Loading…
Reference in a new issue