]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/validate: validation of NXDOMAIN answers for DS queries was fixed
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 5 Jun 2017 11:03:50 +0000 (13:03 +0200)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Mon, 5 Jun 2017 11:03:50 +0000 (13:03 +0200)
lib/layer/validate.c

index 2726d858235777b89457c788e86bea53fba722b4..bd6ef5581c4ac0449e356ee733ebcde81ad80114 100644 (file)
@@ -345,11 +345,19 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_
         * otherwise referral is bogus (or an attempted downgrade attack).
         */
 
+
        unsigned section = KNOT_ANSWER;
-       if (!knot_wire_get_aa(answer->wire)) { /* Referral */
+       const bool referral = !knot_wire_get_aa(answer->wire);
+       if (referral) {
                section = KNOT_AUTHORITY;
-       } else if (knot_pkt_qtype(answer) == KNOT_RRTYPE_DS &&
-                  !(qry->flags & QUERY_CNAME)) {
+       } /* else if  {
+                Not referral, but RCODE is NXDOMAIN.
+                * Since we are here NXDOMAIN is proved above,
+                * so do nothing and exit.
+               return kr_ok();
+       } */ else if (knot_pkt_qtype(answer) == KNOT_RRTYPE_DS &&
+                  !(qry->flags & QUERY_CNAME) &&
+                  (knot_wire_get_rcode(answer->wire) != KNOT_RCODE_NXDOMAIN)) {
                section = KNOT_ANSWER;
        } else { /* N/A */
                return kr_ok();
@@ -362,16 +370,16 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_
        if (!new_ds) {
                /* No DS provided, check for proof of non-existence. */
                if (!has_nsec3) {
-                       if (!knot_wire_get_aa(answer->wire)) {
-                               /* Referral, check if it is referral to unsigned, rfc4035 5.2 */
+                       if (referral) {
+                               /* Check if it is referral to unsigned, rfc4035 5.2 */
                                ret = kr_nsec_ref_to_unsigned(answer);
                        } else {
                                /* No-data answer */
                                ret = kr_nsec_existence_denial(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
                        }
                } else {
-                       if (!knot_wire_get_aa(answer->wire)) {
-                               /* Referral, check if it is referral to unsigned, rfc5155 8.9 */
+                       if (referral) {
+                               /* Check if it is referral to unsigned, rfc5155 8.9 */
                                ret = kr_nsec3_ref_to_unsigned(answer);
                        } else {
                                /* No-data answer, QTYPE is DS, rfc5155 8.6 */
@@ -383,8 +391,7 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_
                        }
                }
 
-               if (!knot_wire_get_aa(answer->wire) &&
-                   qry->stype != KNOT_RRTYPE_DS &&
+               if (referral && qry->stype != KNOT_RRTYPE_DS &&
                    ret == DNSSEC_NOT_FOUND) {
                        /* referral,
                         * qtype is not KNOT_RRTYPE_DS, NSEC\NSEC3 were not found.