|
|
41fa067 |
Index: validator/validator.c
|
|
|
41fa067 |
===================================================================
|
|
|
41fa067 |
--- validator/validator.c (revision 1669)
|
|
|
41fa067 |
+++ validator/validator.c (revision 1670)
|
|
|
41fa067 |
@@ -479,6 +479,36 @@
|
|
|
41fa067 |
}
|
|
|
41fa067 |
|
|
|
41fa067 |
/**
|
|
|
41fa067 |
+ * Detect wrong truncated response, by a bad recursor out there.
|
|
|
41fa067 |
+ * The positive response has a mangled authority section.
|
|
|
41fa067 |
+ * Remove that authority section.
|
|
|
41fa067 |
+ * @param rep: reply
|
|
|
41fa067 |
+ * @return true if a wrongly truncated response.
|
|
|
41fa067 |
+ */
|
|
|
41fa067 |
+static int
|
|
|
41fa067 |
+detect_wrongly_truncated(struct reply_info* rep)
|
|
|
41fa067 |
+{
|
|
|
41fa067 |
+ size_t i;
|
|
|
41fa067 |
+ /* no additional, only NS in authority, and it is bogus */
|
|
|
41fa067 |
+ if(rep->ar_numrrsets != 0 || rep->ns_numrrsets != 1 ||
|
|
|
41fa067 |
+ rep->an_numrrsets == 0)
|
|
|
41fa067 |
+ return 0;
|
|
|
41fa067 |
+ if(ntohs(rep->rrsets[ rep->an_numrrsets ]->rk.type) != LDNS_RR_TYPE_NS)
|
|
|
41fa067 |
+ return 0;
|
|
|
41fa067 |
+ if(((struct packed_rrset_data*)rep->rrsets[ rep->an_numrrsets ]
|
|
|
41fa067 |
+ ->entry.data)->security != sec_status_bogus)
|
|
|
41fa067 |
+ return 0;
|
|
|
41fa067 |
+ /* answer section is present and secure */
|
|
|
41fa067 |
+ for(i=0; i<rep->an_numrrsets; i++) {
|
|
|
41fa067 |
+ if(((struct packed_rrset_data*)rep->rrsets[ i ]
|
|
|
41fa067 |
+ ->entry.data)->security != sec_status_secure)
|
|
|
41fa067 |
+ return 0;
|
|
|
41fa067 |
+ }
|
|
|
41fa067 |
+ return 1;
|
|
|
41fa067 |
+}
|
|
|
41fa067 |
+
|
|
|
41fa067 |
+
|
|
|
41fa067 |
+/**
|
|
|
41fa067 |
* Given a "positive" response -- a response that contains an answer to the
|
|
|
41fa067 |
* question, and no CNAME chain, validate this response.
|
|
|
41fa067 |
*
|
|
|
41fa067 |
@@ -1449,17 +1479,31 @@
|
|
|
41fa067 |
vq->chase_reply->security = sec_status_bogus;
|
|
|
41fa067 |
return 1;
|
|
|
41fa067 |
}
|
|
|
41fa067 |
+ subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
|
|
41fa067 |
+ &vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
|
|
|
41fa067 |
|
|
|
41fa067 |
/* check signatures in the message;
|
|
|
41fa067 |
* answer and authority must be valid, additional is only checked. */
|
|
|
41fa067 |
if(!validate_msg_signatures(qstate->env, ve, &vq->qchase,
|
|
|
41fa067 |
vq->chase_reply, vq->key_entry)) {
|
|
|
41fa067 |
- verbose(VERB_DETAIL, "Validate: message contains bad rrsets");
|
|
|
41fa067 |
- return 1;
|
|
|
41fa067 |
+ /* workaround bad recursor out there that truncates (even
|
|
|
41fa067 |
+ * with EDNS4k) to 512 by removing RRSIG from auth section
|
|
|
41fa067 |
+ * for positive replies*/
|
|
|
41fa067 |
+ if(subtype == VAL_CLASS_POSITIVE &&
|
|
|
41fa067 |
+ detect_wrongly_truncated(vq->orig_msg->rep)) {
|
|
|
41fa067 |
+ /* truncate the message some more */
|
|
|
41fa067 |
+ vq->orig_msg->rep->ns_numrrsets = 0;
|
|
|
41fa067 |
+ vq->orig_msg->rep->rrset_count--;
|
|
|
41fa067 |
+ vq->chase_reply->ns_numrrsets = 0;
|
|
|
41fa067 |
+ vq->chase_reply->rrset_count--;
|
|
|
41fa067 |
+ }
|
|
|
41fa067 |
+ else {
|
|
|
41fa067 |
+ verbose(VERB_DETAIL, "Validate: message contains "
|
|
|
41fa067 |
+ "bad rrsets");
|
|
|
41fa067 |
+ return 1;
|
|
|
41fa067 |
+ }
|
|
|
41fa067 |
}
|
|
|
41fa067 |
|
|
|
41fa067 |
- subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
|
|
41fa067 |
- &vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
|
|
|
41fa067 |
switch(subtype) {
|
|
|
41fa067 |
case VAL_CLASS_POSITIVE:
|
|
|
41fa067 |
verbose(VERB_ALGO, "Validating a positive response");
|