action = respip_always_nxdomain;
else if(strcmp(actnstr, "always_nodata") == 0)
action = respip_always_nodata;
+ else if(strcmp(actnstr, "always_deny") == 0)
+ action = respip_always_deny;
else {
log_err("unknown response-ip action %s", actnstr);
return 0;
&& action != respip_always_transparent
&& action != respip_always_nxdomain
&& action != respip_always_nodata
+ && action != respip_always_deny
&& (result = respip_data_answer(action,
(data) ? data : raddr->data, qinfo->qtype, rep,
rrset_id, new_repp, tag, tag_datas, tag_datas_size,
} else {
qstate->respip_action_info = NULL;
}
- if (new_rep == qstate->return_msg->rep &&
+ if (actinfo.action == respip_always_deny ||
+ (new_rep == qstate->return_msg->rep &&
(actinfo.action == respip_deny ||
- actinfo.action == respip_inform_deny)) {
+ actinfo.action == respip_deny ||
+ actinfo.action == respip_inform_deny))) {
/* for deny-variant actions (unless response-ip
* data is applied), mark the query state so
* the response will be dropped for all
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
"[%s] ", respip_actinfo->log_name);
}
- txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
+ snprintf(txt+txtlen, sizeof(txt)-txtlen,
"%s/%d %s %s@%u", respip, respip_addr->net,
(actionstr) ? actionstr : "inform", srcip, port);
if(actionstr)
return 1;
}
+/** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be
+ * free'd (regionally alloc'd) */
+int
+local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index)
+{
+ if(index >= pd->count) {
+ log_warn("Trying to remove RR with out of bound index");
+ return 0;
+ }
+ if(index - 1 < pd->count) {
+ /* not removing last element */
+ size_t nexti = index + 1;
+ size_t num = pd->count - nexti;
+ memcpy(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num);
+ memcpy(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num);
+ memcpy(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num);
+ }
+ pd->count--;
+ return 1;
+}
+
struct local_data*
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
{
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
struct local_data* ld, enum localzone_type lz_type)
{
- if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
+ if(lz_type == local_zone_deny ||
+ lz_type == local_zone_always_deny ||
+ lz_type == local_zone_inform_deny) {
/** no reply at all, signal caller by clearing buffer. */
sldns_buffer_clear(buf);
sldns_buffer_flip(buf);
&& lzt != local_zone_always_transparent
&& lzt != local_zone_always_nxdomain
&& lzt != local_zone_always_nodata
+ && lzt != local_zone_always_deny
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
lock_rw_unlock(&z->lock);
case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain";
case local_zone_always_nodata: return "always_nodata";
+ case local_zone_always_deny: return "always_deny";
case local_zone_noview: return "noview";
case local_zone_invalid: return "invalid";
}
*t = local_zone_always_nxdomain;
else if(strcmp(type, "always_nodata") == 0)
*t = local_zone_always_nodata;
+ else if(strcmp(type, "always_deny") == 0)
+ *t = local_zone_always_deny;
else if(strcmp(type, "noview") == 0)
*t = local_zone_noview;
else if(strcmp(type, "nodefault") == 0)
local_zone_always_nxdomain,
/** answer with noerror/nodata, even when there is local data */
local_zone_always_nodata,
+ /** drop query, even when there is local data */
+ local_zone_always_deny,
/** answer not from the view, but global or no-answer */
local_zone_noview,
/** Invalid type, cannot be used to generate answer */
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
+/**
+ * Remove RR from rrset that is created using localzone's rrset_insert_rr.
+ * @param pd: the RRset containing the RR to remove
+ * @param index: index of RR to remove
+ * @return: 1 on success; 0 otherwise.
+ */
+int
+local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index);
+
/**
* Valid response ip actions for the IP-response-driven-action feature;
* defined here instead of in the respip module to enable sharing of enum
respip_always_nxdomain = local_zone_always_nxdomain,
/** answer with nodata response */
respip_always_nodata = local_zone_always_nodata,
+ /** answer with nodata response */
+ respip_always_deny = local_zone_always_deny,
/* The rest of the values are only possible as
* access-control-tag-action */
switch(a) {
case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain;
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
- case RPZ_DROP_ACTION: return local_zone_deny;
+ case RPZ_DROP_ACTION: return local_zone_always_deny;
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
case RPZ_CNAME_OVERRIDE_ACTION:
switch(a) {
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
case RPZ_NODATA_ACTION: return respip_always_nodata;
- case RPZ_DROP_ACTION: return respip_deny;
+ case RPZ_DROP_ACTION: return respip_always_deny;
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
case RPZ_CNAME_OVERRIDE_ACTION:
switch(lzt) {
case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
case local_zone_always_nodata: return RPZ_NODATA_ACTION;
- case local_zone_deny: return RPZ_DROP_ACTION;
+ case local_zone_always_deny: return RPZ_DROP_ACTION;
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
case local_zone_invalid:
switch(a) {
case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
case respip_always_nodata: return RPZ_NODATA_ACTION;
- case respip_deny: return RPZ_DROP_ACTION;
+ case respip_always_deny: return RPZ_DROP_ACTION;
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
case respip_invalid:
}
if(d->count > 1) {
- struct packed_rrset_data* new;
- new = packed_rrset_remove_rr(d, index, z->region);
- if(!new)
+ if(!local_rrset_remove_rr(d, index))
return 0;
- p->rrset->entry.data = new;
}
}
}
return 1;
}
if(d->count > 1) {
- struct packed_rrset_data* new;
- new = packed_rrset_remove_rr(d, index, region);
- if(!new)
+ if(!local_rrset_remove_rr(d, index))
return 0;
- raddr->data->entry.data = new;
}
}
return 0;
#include "services/localzone.h"
#include "util/locks.h"
+#include "util/log.h"
#include "util/config_file.h"
#include "services/authzone.h"
#include "sldns/sbuffer.h"
--- /dev/null
+; config options
+server:
+ module-config: "respip validator iterator"
+ target-fetch-policy: "0 0 0 0 0"
+ qname-minimisation: no
+
+rpz:
+ name: "rpz.example.com."
+ master: 10.20.30.40
+ 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.rpz.example.com. IN CNAME *.
+c.rpz.example.com. IN TXT "hello from initial RPZ"
+c.rpz.example.com. IN TXT "another hello from initial RPZ"
+c.rpz.example.com. IN TXT "yet another hello from initial RPZ"
+d.rpz.example.com. IN CNAME .
+32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
+32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
+TEMPFILE_END
+
+stub-zone:
+ name: "."
+ stub-addr: 10.20.30.40
+
+CONFIG_END
+
+SCENARIO_BEGIN Test RPZ QNAME trigger, loaded using IXFR
+
+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. IN TXT
+SECTION ANSWER
+b. TXT "hello from upstream"
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+d. IN TXT
+SECTION ANSWER
+d. TXT "hello from upstream"
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+a.rpz-ip. IN A
+SECTION ANSWER
+a.rpz-ip. IN A 10.0.123.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+c.rpz-ip. IN A
+SECTION ANSWER
+c.rpz-ip. IN A 10.0.123.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR NOERROR AA
+SECTION QUESTION
+d.rpz-ip. IN A
+SECTION ANSWER
+d.rpz-ip. IN A 10.0.123.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+rpz.example.com. IN SOA
+SECTION ANSWER
+rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+rpz.example.com. IN IXFR
+SECTION ANSWER
+rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
+rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
+a.rpz.example.com. IN CNAME *.
+c.rpz.example.com. IN TXT "hello from initial RPZ"
+c.rpz.example.com. IN TXT "another hello from initial RPZ"
+d.rpz.example.com. IN CNAME .
+32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
+32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
+rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
+b.rpz.example.com. TXT "hello from RPZ"
+c.rpz.example.com. TXT "hello from RPZ"
+a.rpz.example.com. CNAME .
+32.1.123.0.10.rpz-ip.rpz.example.com. CNAME .
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.5
+32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.6
+rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
+ENTRY_END
+
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b. IN TXT
+ENTRY_END
+
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+b. IN TXT
+SECTION ANSWER
+b. IN TXT "hello from upstream"
+ENTRY_END
+
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a. IN TXT
+ENTRY_END
+
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+a. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.rpz-ip. IN A
+ENTRY_END
+
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.rpz-ip. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 7 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+c. IN TXT
+ENTRY_END
+
+STEP 8 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+c. IN TXT
+SECTION ANSWER
+c. IN TXT "yet another hello from initial RPZ"
+c. IN TXT "another hello from initial RPZ"
+c. IN TXT "hello from initial RPZ"
+ENTRY_END
+
+STEP 9 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+c.rpz-ip. IN A
+ENTRY_END
+
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+c.rpz-ip. IN A
+SECTION ANSWER
+c.rpz-ip. IN A 10.66.0.4
+c.rpz-ip. IN A 10.66.0.3
+ENTRY_END
+
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+d. IN TXT
+ENTRY_END
+
+STEP 12 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+d. IN TXT
+ENTRY_END
+
+STEP 13 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+d.rpz-ip. IN A
+ENTRY_END
+
+
+STEP 15 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+d.rpz-ip. IN A
+ENTRY_END
+
+STEP 16 TIME_PASSES ELAPSE 1
+STEP 30 TIME_PASSES ELAPSE 3600
+STEP 40 TRAFFIC
+
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b. IN TXT
+ENTRY_END
+
+STEP 51 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+b. IN TXT
+SECTION ANSWER
+b. IN TXT "hello from RPZ"
+ENTRY_END
+
+STEP 52 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a. IN TXT
+ENTRY_END
+
+STEP 53 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NXDOMAIN
+SECTION QUESTION
+a. IN TXT
+SECTION ANSWER
+ENTRY_END
+
+STEP 54 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.rpz-ip. IN A
+ENTRY_END
+
+STEP 55 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NXDOMAIN
+SECTION QUESTION
+a.rpz-ip. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 56 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+c. IN TXT
+ENTRY_END
+
+STEP 57 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AA NOERROR
+SECTION QUESTION
+c. IN TXT
+SECTION ANSWER
+c. IN TXT "hello from RPZ"
+c. IN TXT "yet another hello from initial RPZ"
+ENTRY_END
+
+STEP 58 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+c.rpz-ip. IN A
+ENTRY_END
+
+STEP 59 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+c.rpz-ip. IN A
+SECTION ANSWER
+c.rpz-ip. IN A 10.66.0.6
+c.rpz-ip. IN A 10.66.0.5
+ENTRY_END
+
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+d. IN TXT
+ENTRY_END
+
+STEP 61 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+d. IN TXT
+SECTION ANSWER
+d. IN TXT "hello from upstream"
+ENTRY_END
+
+STEP 62 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+d.rpz-ip. IN A
+ENTRY_END
+
+STEP 63 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+d.rpz-ip. IN A
+SECTION ANSWER
+d.rpz-ip. IN A 10.0.123.4
+ENTRY_END
+
+SCENARIO_END
e TXT "should be override by cname"
TEMPFILE_END
+rpz:
+ name: "rpz7.example.com."
+ rpz-action-override: drop
+ zonefile:
+TEMPFILE_NAME rpz7.example.com
+TEMPFILE_CONTENTS rpz7.example.com
+$ORIGIN rpz7.example.com.
+f TXT "should be override by drop policy"
+TEMPFILE_END
+
stub-zone:
name: "d."
stub-addr: 10.20.30.40
d. IN TXT "answer from upstream ns"
ENTRY_END
+; check drop override, would be localdata without override
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+f. IN TXT
+ENTRY_END
+; no answer is checked at exit of testbound.
+
SCENARIO_END
32.6.113.0.203.rpz-ip A 192.0.2.6
TEMPFILE_END
+rpz:
+ name: "rpz7.example.com."
+ rpz-action-override: drop
+ zonefile:
+TEMPFILE_NAME rpz7.example.com
+TEMPFILE_CONTENTS rpz7.example.com
+$ORIGIN rpz7.example.com.
+32.7.113.0.203.rpz-ip A 192.0.2.7
+TEMPFILE_END
+
stub-zone:
name: "."
stub-addr: 10.20.30.40
e. IN A 203.0.113.6
ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+f. IN A
+SECTION ANSWER
+f. IN A 203.0.113.7
+ENTRY_END
+
RANGE_END
STEP 1 QUERY
ns. IN A 10.20.30.40
ENTRY_END
+STEP 11 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+f. IN A
+ENTRY_END
+; no answer is checked at exit of testbound.
+
+STEP 12 TIME_PASSES ELAPSE 10
+
SCENARIO_END