]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #954: Inconsistent RPZ handling for A record returned along with
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 17 Oct 2023 14:47:04 +0000 (16:47 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 17 Oct 2023 14:47:04 +0000 (16:47 +0200)
  CNAME.

doc/Changelog
iterator/iterator.c
services/rpz.c
testdata/rpz_cached_cname.rpl [new file with mode: 0644]

index ff12a6b462c8e4e5df8cae93d8309470c8f932d1..bdd8ea2f1500fcb55cb39921a77678f8e7d61010 100644 (file)
@@ -1,3 +1,7 @@
+17 October 2023: Wouter
+       - Fix #954: Inconsistent RPZ handling for A record returned along with
+         CNAME.
+
 16 October 2023: George
        - Expose the script filename in the Python module environment 'mod_env'
          instead of the config_file structure which includes the linked list
index 053c0faec00e124c4d0953646ae6f3f9c9cd52df..6ff811a27d06cb3da64aa2f886741e099d1a244d 100644 (file)
@@ -1449,6 +1449,39 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
                        }
                        iq->qchase.qname = sname;
                        iq->qchase.qname_len = slen;
+                       if(qstate->env->auth_zones) {
+                               /* apply rpz qname triggers after cname */
+                               struct dns_msg* forged_response =
+                                       rpz_callback_from_iterator_cname(qstate, iq);
+                               while(forged_response && reply_find_rrset_section_an(
+                                       forged_response->rep, iq->qchase.qname,
+                                       iq->qchase.qname_len, LDNS_RR_TYPE_CNAME,
+                                       iq->qchase.qclass)) {
+                                       /* another cname to follow */
+                                       if(!handle_cname_response(qstate, iq, forged_response,
+                                               &sname, &slen)) {
+                                               errinf(qstate, "malloc failure, CNAME info");
+                                               return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+                                       }
+                                       iq->qchase.qname = sname;
+                                       iq->qchase.qname_len = slen;
+                                       forged_response =
+                                               rpz_callback_from_iterator_cname(qstate, iq);
+                               }
+                               if(forged_response != NULL) {
+                                       qstate->ext_state[id] = module_finished;
+                                       qstate->return_rcode = LDNS_RCODE_NOERROR;
+                                       qstate->return_msg = forged_response;
+                                       iq->response = forged_response;
+                                       next_state(iq, FINISHED_STATE);
+                                       if(!iter_prepend(iq, qstate->return_msg, qstate->region)) {
+                                               log_err("rpz: after cached cname, prepend rrsets: out of memory");
+                                               return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+                                       }
+                                       qstate->return_msg->qinfo = qstate->qinfo;
+                                       return 0;
+                               }
+                       }
                        /* This *is* a query restart, even if it is a cheap 
                         * one. */
                        iq->dp = NULL;
index 7f7a2fa9b11163380482288f9d9f5ef3655d749d..18d76c07bff3d77c226f4efffd4f6e582c54d375 100644 (file)
@@ -2448,6 +2448,10 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
                        rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
                ret = NULL;
        }
+       if(r->log)
+               log_rpz_apply("qname", (z?z->name:NULL), NULL,
+                       localzone_type_to_rpz_action(lzt),
+                       &is->qchase, NULL, ms, r->log_name);
        lock_rw_unlock(&z->lock);
        lock_rw_unlock(&a->lock);
        return ret;
diff --git a/testdata/rpz_cached_cname.rpl b/testdata/rpz_cached_cname.rpl
new file mode 100644 (file)
index 0000000..198b946
--- /dev/null
@@ -0,0 +1,122 @@
+; config options
+server:
+       module-config: "respip validator iterator"
+       target-fetch-policy: "0 0 0 0 0"
+       qname-minimisation: no
+       rrset-roundrobin: no
+       access-control: 192.0.0.0/8 allow
+
+rpz:
+       name: "rpz.example.com"
+       rpz-log: yes
+       rpz-log-name: "rpz.example.com"
+       zonefile:
+TEMPFILE_NAME rpz.example.com
+TEMPFILE_CONTENTS rpz.example.com
+rpz.example.com. 3600 IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
+rpz.example.com.       3600    IN      NS      ns.rpz.example.net.
+a.foo.rpz.example.com. 120 IN A 10.99.99.99
+TEMPFILE_END
+
+stub-zone:
+       name: "."
+       stub-addr: 10.20.30.40
+
+CONFIG_END
+
+SCENARIO_BEGIN Test RPZ with cached CNAME to A record
+
+RANGE_BEGIN 0 100
+       ADDRESS 10.20.30.40
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+.      IN      NS
+SECTION ANSWER
+.      IN      NS      ns.
+SECTION ADDITIONAL
+ns.    IN      NS      10.20.30.40
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+b.foo. IN      A
+SECTION ANSWER
+b.foo. 30 CNAME        a.foo.
+a.foo.  30 A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+a.foo. IN      A
+SECTION ANSWER
+a.foo.  A 1.2.3.4
+ENTRY_END
+
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.foo. IN      A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+a.foo. IN      A
+SECTION ANSWER
+a.foo.  120 A 10.99.99.99
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b.foo. IN      A
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+b.foo. IN      A
+SECTION ANSWER
+b.foo. 30 CNAME        a.foo.
+a.foo.  120 A 10.99.99.99
+ENTRY_END
+
+STEP 50 TIME_PASSES ELAPSE 3
+
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b.foo. IN      A
+ENTRY_END
+
+STEP 70 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+b.foo. IN      A
+SECTION ANSWER
+b.foo. 30 CNAME        a.foo.
+a.foo.  120 A 10.99.99.99
+ENTRY_END
+
+SCENARIO_END