1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #ifndef DNS_RPZ_H
13 #define DNS_RPZ_H 1
14 
15 #include <inttypes.h>
16 #include <stdbool.h>
17 
18 #include <isc/deprecated.h>
19 #include <isc/event.h>
20 #include <isc/ht.h>
21 #include <isc/lang.h>
22 #include <isc/refcount.h>
23 #include <isc/rwlock.h>
24 #include <isc/time.h>
25 #include <isc/timer.h>
26 
27 #include <dns/fixedname.h>
28 #include <dns/rdata.h>
29 #include <dns/types.h>
30 
31 ISC_LANG_BEGINDECLS
32 
33 #define DNS_RPZ_PREFIX "rpz-"
34 /*
35  * Sub-zones of various trigger types.
36  */
37 #define DNS_RPZ_CLIENT_IP_ZONE DNS_RPZ_PREFIX "client-ip"
38 #define DNS_RPZ_IP_ZONE	       DNS_RPZ_PREFIX "ip"
39 #define DNS_RPZ_NSIP_ZONE      DNS_RPZ_PREFIX "nsip"
40 #define DNS_RPZ_NSDNAME_ZONE   DNS_RPZ_PREFIX "nsdname"
41 /*
42  * Special policies.
43  */
44 #define DNS_RPZ_PASSTHRU_NAME DNS_RPZ_PREFIX "passthru"
45 #define DNS_RPZ_DROP_NAME     DNS_RPZ_PREFIX "drop"
46 #define DNS_RPZ_TCP_ONLY_NAME DNS_RPZ_PREFIX "tcp-only"
47 
48 typedef uint8_t dns_rpz_prefix_t;
49 
50 typedef enum {
51 	DNS_RPZ_TYPE_BAD,
52 	DNS_RPZ_TYPE_CLIENT_IP,
53 	DNS_RPZ_TYPE_QNAME,
54 	DNS_RPZ_TYPE_IP,
55 	DNS_RPZ_TYPE_NSDNAME,
56 	DNS_RPZ_TYPE_NSIP
57 } dns_rpz_type_t;
58 
59 /*
60  * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_DROP
61  * < DNS_RPZ_POLICY_TCP_ONLY DNS_RPZ_POLICY_NXDOMAIN < DNS_RPZ_POLICY_NODATA
62  * < DNS_RPZ_POLICY_CNAME to choose among competing policies.
63  */
64 typedef enum {
65 	DNS_RPZ_POLICY_GIVEN = 0,    /* 'given': what policy record says */
66 	DNS_RPZ_POLICY_DISABLED = 1, /* log what would have happened */
67 	DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
68 	DNS_RPZ_POLICY_DROP = 3,     /* 'drop': do not respond */
69 	DNS_RPZ_POLICY_TCP_ONLY = 4, /* 'tcp-only': answer UDP with TC=1 */
70 	DNS_RPZ_POLICY_NXDOMAIN = 5, /* 'nxdomain': answer with NXDOMAIN */
71 	DNS_RPZ_POLICY_NODATA = 6,   /* 'nodata': answer with ANCOUNT=0 */
72 	DNS_RPZ_POLICY_CNAME = 7,    /* 'cname x': answer with x's rrsets */
73 	DNS_RPZ_POLICY_DNS64,	     /* Apply DN64 to the A rewrite */
74 	DNS_RPZ_POLICY_RECORD,
75 	DNS_RPZ_POLICY_WILDCNAME,
76 	DNS_RPZ_POLICY_MISS,
77 	DNS_RPZ_POLICY_ERROR
78 } dns_rpz_policy_t;
79 
80 typedef uint8_t dns_rpz_num_t;
81 
82 #define DNS_RPZ_MAX_ZONES 64
83 /*
84  * Type dns_rpz_zbits_t must be an unsigned int wide enough to contain
85  * at least DNS_RPZ_MAX_ZONES bits.
86  */
87 typedef uint64_t dns_rpz_zbits_t;
88 
89 #define DNS_RPZ_ALL_ZBITS ((dns_rpz_zbits_t)-1)
90 
91 #define DNS_RPZ_INVALID_NUM DNS_RPZ_MAX_ZONES
92 
93 #define DNS_RPZ_ZBIT(n) (((dns_rpz_zbits_t)1) << (dns_rpz_num_t)(n))
94 
95 /*
96  * Mask of the specified and higher numbered policy zones
97  * Avoid hassles with (1<<33) or (1<<65)
98  */
99 #define DNS_RPZ_ZMASK(n)                                                     \
100 	((dns_rpz_zbits_t)(                                                  \
101 		(((n) >= DNS_RPZ_MAX_ZONES - 1) ? 0 : (1ULL << ((n) + 1))) - \
102 		1))
103 
104 /*
105  * The trigger counter type.
106  */
107 typedef size_t dns_rpz_trigger_counter_t;
108 
109 /*
110  * The number of triggers of each type in a response policy zone.
111  */
112 typedef struct dns_rpz_triggers dns_rpz_triggers_t;
113 struct dns_rpz_triggers {
114 	dns_rpz_trigger_counter_t client_ipv4;
115 	dns_rpz_trigger_counter_t client_ipv6;
116 	dns_rpz_trigger_counter_t qname;
117 	dns_rpz_trigger_counter_t ipv4;
118 	dns_rpz_trigger_counter_t ipv6;
119 	dns_rpz_trigger_counter_t nsdname;
120 	dns_rpz_trigger_counter_t nsipv4;
121 	dns_rpz_trigger_counter_t nsipv6;
122 };
123 
124 /*
125  * A single response policy zone.
126  */
127 typedef struct dns_rpz_zone  dns_rpz_zone_t;
128 typedef struct dns_rpz_zones dns_rpz_zones_t;
129 
130 struct dns_rpz_zone {
131 	isc_refcount_t	 refs;
132 	dns_rpz_num_t	 num;	    /* ordinal in list of policy zones */
133 	dns_name_t	 origin;    /* Policy zone name */
134 	dns_name_t	 client_ip; /* DNS_RPZ_CLIENT_IP_ZONE.origin. */
135 	dns_name_t	 ip;	    /* DNS_RPZ_IP_ZONE.origin. */
136 	dns_name_t	 nsdname;   /* DNS_RPZ_NSDNAME_ZONE.origin */
137 	dns_name_t	 nsip;	    /* DNS_RPZ_NSIP_ZONE.origin. */
138 	dns_name_t	 passthru;  /* DNS_RPZ_PASSTHRU_NAME. */
139 	dns_name_t	 drop;	    /* DNS_RPZ_DROP_NAME. */
140 	dns_name_t	 tcp_only;  /* DNS_RPZ_TCP_ONLY_NAME. */
141 	dns_name_t	 cname;	    /* override value for ..._CNAME */
142 	dns_ttl_t	 max_policy_ttl;
143 	dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
144 
145 	uint32_t min_update_interval;	 /* minimal interval between
146 					  * updates */
147 	isc_ht_t *	 nodes;		 /* entries in zone */
148 	dns_rpz_zones_t *rpzs;		 /* owner */
149 	isc_time_t	 lastupdated;	 /* last time the zone was processed
150 					  * */
151 	bool updatepending;		 /* there is an update
152 					  * pending/waiting */
153 	bool		 updaterunning;	 /* there is an update running */
154 	dns_db_t *	 db;		 /* zones database */
155 	dns_dbversion_t *dbversion;	 /* version we will be updating to */
156 	dns_db_t *	 updb;		 /* zones database we're working on */
157 	dns_dbversion_t *updbversion;	 /* version we're currently working
158 					  * on */
159 	dns_dbiterator_t *updbit;	 /* iterator to use when updating */
160 	isc_ht_t *	  newnodes;	 /* entries in zone being updated */
161 	bool		  db_registered; /* is the notify event
162 					  * registered? */
163 	bool	     addsoa;		 /* add soa to the additional section */
164 	isc_timer_t *updatetimer;
165 	isc_event_t  updateevent;
166 };
167 
168 /*
169  * Radix tree node for response policy IP addresses
170  */
171 typedef struct dns_rpz_cidr_node dns_rpz_cidr_node_t;
172 
173 /*
174  * Bitfields indicating which policy zones have policies of
175  * which type.
176  */
177 typedef struct dns_rpz_have dns_rpz_have_t;
178 struct dns_rpz_have {
179 	dns_rpz_zbits_t client_ipv4;
180 	dns_rpz_zbits_t client_ipv6;
181 	dns_rpz_zbits_t client_ip;
182 	dns_rpz_zbits_t qname;
183 	dns_rpz_zbits_t ipv4;
184 	dns_rpz_zbits_t ipv6;
185 	dns_rpz_zbits_t ip;
186 	dns_rpz_zbits_t nsdname;
187 	dns_rpz_zbits_t nsipv4;
188 	dns_rpz_zbits_t nsipv6;
189 	dns_rpz_zbits_t nsip;
190 	dns_rpz_zbits_t qname_skip_recurse;
191 };
192 
193 /*
194  * Policy options
195  */
196 typedef struct dns_rpz_popt dns_rpz_popt_t;
197 struct dns_rpz_popt {
198 	dns_rpz_zbits_t no_rd_ok;
199 	dns_rpz_zbits_t no_log;
200 	dns_rpz_zbits_t nsip_on;
201 	dns_rpz_zbits_t nsdname_on;
202 	bool		dnsrps_enabled;
203 	bool		break_dnssec;
204 	bool		qname_wait_recurse;
205 	bool		nsip_wait_recurse;
206 	unsigned int	min_ns_labels;
207 	dns_rpz_num_t	num_zones;
208 };
209 
210 /*
211  * Response policy zones known to a view.
212  */
213 struct dns_rpz_zones {
214 	dns_rpz_popt_t	   p;
215 	dns_rpz_zone_t *   zones[DNS_RPZ_MAX_ZONES];
216 	dns_rpz_triggers_t triggers[DNS_RPZ_MAX_ZONES];
217 
218 	/*
219 	 * RPZ policy version number.
220 	 * It is initially 0 and it increases whenever the server is
221 	 * reconfigured with new zones or policy.
222 	 */
223 	int rpz_ver;
224 
225 	dns_rpz_zbits_t defined;
226 
227 	/*
228 	 * The set of records for a policy zone are in one of these states:
229 	 *	never loaded		    load_begun=0  have=0
230 	 *	during initial loading	    load_begun=1  have=0
231 	 *				and rbtdb->rpzsp == rbtdb->load_rpzsp
232 	 *	after good load		    load_begun=1  have!=0
233 	 *	after failed initial load   load_begun=1  have=0
234 	 *				and rbtdb->load_rpzsp == NULL
235 	 *	reloading after failure	    load_begun=1  have=0
236 	 *	reloading after success
237 	 *		main rpzs	    load_begun=1  have!=0
238 	 *		load rpzs	    load_begun=1  have=0
239 	 */
240 	dns_rpz_zbits_t load_begun;
241 	dns_rpz_have_t	have;
242 
243 	/*
244 	 * total_triggers maintains the total number of triggers in all
245 	 * policy zones in the view. It is only used to print summary
246 	 * statistics after a zone load of how the trigger counts
247 	 * changed.
248 	 */
249 	dns_rpz_triggers_t total_triggers;
250 
251 	isc_mem_t *	mctx;
252 	isc_taskmgr_t * taskmgr;
253 	isc_timermgr_t *timermgr;
254 	isc_task_t *	updater;
255 	isc_refcount_t	refs;
256 	isc_refcount_t	irefs;
257 	/*
258 	 * One lock for short term read-only search that guarantees the
259 	 * consistency of the pointers.
260 	 * A second lock for maintenance that guarantees no other thread
261 	 * is adding or deleting nodes.
262 	 */
263 	isc_rwlock_t search_lock;
264 	isc_mutex_t  maint_lock;
265 
266 	dns_rpz_cidr_node_t *cidr;
267 	dns_rbt_t *	     rbt;
268 
269 	/*
270 	 * DNSRPZ librpz configuration string and handle on librpz connection
271 	 */
272 	char *		      rps_cstr;
273 	size_t		      rps_cstr_size;
274 	struct librpz_client *rps_client;
275 };
276 
277 /*
278  * context for finding the best policy
279  */
280 typedef struct {
281 	unsigned int state;
282 #define DNS_RPZ_REWRITTEN      0x0001
283 #define DNS_RPZ_DONE_CLIENT_IP 0x0002 /* client IP address checked */
284 #define DNS_RPZ_DONE_QNAME     0x0004 /* qname checked */
285 #define DNS_RPZ_DONE_QNAME_IP  0x0008 /* IP addresses of qname checked */
286 #define DNS_RPZ_DONE_NSDNAME   0x0010 /* NS name missed; checking addresses */
287 #define DNS_RPZ_DONE_IPv4      0x0020
288 #define DNS_RPZ_RECURSING      0x0040
289 #define DNS_RPZ_ACTIVE	       0x0080
290 	/*
291 	 * Best match so far.
292 	 */
293 	struct {
294 		dns_rpz_type_t	 type;
295 		dns_rpz_zone_t * rpz;
296 		dns_rpz_prefix_t prefix;
297 		dns_rpz_policy_t policy;
298 		dns_ttl_t	 ttl;
299 		isc_result_t	 result;
300 		dns_zone_t *	 zone;
301 		dns_db_t *	 db;
302 		dns_dbversion_t *version;
303 		dns_dbnode_t *	 node;
304 		dns_rdataset_t * rdataset;
305 	} m;
306 	/*
307 	 * State for chasing IP addresses and NS names including recursion.
308 	 */
309 	struct {
310 		unsigned int	label;
311 		dns_db_t *	db;
312 		dns_rdataset_t *ns_rdataset;
313 		dns_rdatatype_t r_type;
314 		isc_result_t	r_result;
315 		dns_rdataset_t *r_rdataset;
316 	} r;
317 
318 	/*
319 	 * State of real query while recursing for NSIP or NSDNAME.
320 	 */
321 	struct {
322 		isc_result_t	result;
323 		bool		is_zone;
324 		bool		authoritative;
325 		dns_zone_t *	zone;
326 		dns_db_t *	db;
327 		dns_dbnode_t *	node;
328 		dns_rdataset_t *rdataset;
329 		dns_rdataset_t *sigrdataset;
330 		dns_rdatatype_t qtype;
331 	} q;
332 
333 	/*
334 	 * A copy of the 'have' and 'p' structures and the RPZ
335 	 * policy version as of the beginning of RPZ processing,
336 	 * used to avoid problems when policy is updated while
337 	 * RPZ recursion is ongoing.
338 	 */
339 	dns_rpz_have_t have;
340 	dns_rpz_popt_t popt;
341 	int	       rpz_ver;
342 
343 	/*
344 	 * Shim db between BIND and DNRPS librpz.
345 	 */
346 	dns_db_t *rpsdb;
347 
348 	/*
349 	 * p_name: current policy owner name
350 	 * r_name: recursing for this name to possible policy triggers
351 	 * f_name: saved found name from before recursion
352 	 */
353 	dns_name_t *	p_name;
354 	dns_name_t *	r_name;
355 	dns_name_t *	fname;
356 	dns_fixedname_t _p_namef;
357 	dns_fixedname_t _r_namef;
358 	dns_fixedname_t _fnamef;
359 } dns_rpz_st_t;
360 
361 #define DNS_RPZ_TTL_DEFAULT		  5
362 #define DNS_RPZ_MAX_TTL_DEFAULT		  DNS_RPZ_TTL_DEFAULT
363 #define DNS_RPZ_MINUPDATEINTERVAL_DEFAULT 60
364 
365 /*
366  * So various response policy zone messages can be turned up or down.
367  */
368 #define DNS_RPZ_ERROR_LEVEL  ISC_LOG_WARNING
369 #define DNS_RPZ_INFO_LEVEL   ISC_LOG_INFO
370 #define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
371 #define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
372 #define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
373 #define DNS_RPZ_DEBUG_QUIET  (DNS_RPZ_DEBUG_LEVEL3 + 1)
374 
375 const char *
376 dns_rpz_type2str(dns_rpz_type_t type);
377 
378 dns_rpz_policy_t
379 dns_rpz_str2policy(const char *str);
380 
381 const char *
382 dns_rpz_policy2str(dns_rpz_policy_t policy);
383 
384 dns_rpz_policy_t
385 dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
386 		     dns_name_t *selfname);
387 
388 isc_result_t
389 dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
390 		  isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
391 		  isc_timermgr_t *timermgr);
392 
393 isc_result_t
394 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp);
395 
396 isc_result_t
397 dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg);
398 
399 void
400 dns_rpz_attach_rpzs(dns_rpz_zones_t *source, dns_rpz_zones_t **target);
401 
402 void
403 dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp);
404 
405 isc_result_t
406 dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs,
407 		  dns_rpz_num_t rpz_num) ISC_DEPRECATED;
408 
409 isc_result_t
410 dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp,
411 	      dns_rpz_num_t rpz_num) ISC_DEPRECATED;
412 
413 isc_result_t
414 dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
415 	    const dns_name_t *name);
416 
417 void
418 dns_rpz_delete(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
419 	       const dns_name_t *name);
420 
421 dns_rpz_num_t
422 dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
423 		dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr,
424 		dns_name_t *ip_name, dns_rpz_prefix_t *prefixp);
425 
426 dns_rpz_zbits_t
427 dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
428 		  dns_rpz_zbits_t zbits, dns_name_t *trig_name);
429 
430 ISC_LANG_ENDDECLS
431 
432 #endif /* DNS_RPZ_H */
433