This file has routine(s) for cleaning up incoming DNS messages from possible useless or malicious junk in it. More...
#include "config.h"
#include "iterator/iter_scrub.h"
#include "iterator/iterator.h"
#include "iterator/iter_priv.h"
#include "services/cache/rrset.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/alloc.h"
#include "sldns/sbuffer.h"
Macros | |
#define | RRSET_SCRUB_OK 0x80 |
RRset flag used during scrubbing. More... | |
Functions | |
static void | remove_rrset (const char *str, sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *prev, struct rrset_parse **rrset) |
remove rrset, update loop variables | |
static int | has_additional (uint16_t t) |
return true if rr type has additional names in it | |
static int | get_additional_name (struct rrset_parse *rrset, struct rr_parse *rr, uint8_t **nm, size_t *nmlen, sldns_buffer *pkt) |
get additional name from rrset RR, return false if no name present | |
static void | mark_additional_rrset (sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *rrset) |
Place mark on rrsets in additional section they are OK. | |
static int | parse_get_cname_target (struct rrset_parse *rrset, uint8_t **sname, size_t *snamelen, sldns_buffer *pkt) |
Get target name of a CNAME. | |
static int | synth_cname (uint8_t *qname, size_t qnamelen, struct rrset_parse *dname_rrset, uint8_t *alias, size_t *aliaslen, sldns_buffer *pkt) |
Synthesize CNAME from DNAME, false if too long. | |
static struct rrset_parse * | synth_cname_rrset (uint8_t **sname, size_t *snamelen, uint8_t *alias, size_t aliaslen, struct regional *region, struct msg_parse *msg, struct rrset_parse *rrset, struct rrset_parse *prev, struct rrset_parse *nx, sldns_buffer *pkt) |
synthesize a CNAME rrset | |
static int | pkt_strict_sub (sldns_buffer *pkt, uint8_t *sname, uint8_t *dr) |
check if DNAME applies to a name | |
static int | pkt_sub (sldns_buffer *pkt, uint8_t *comprname, uint8_t *zone) |
check subdomain with decompression | |
static int | sub_of_pkt (sldns_buffer *pkt, uint8_t *zone, uint8_t *comprname) |
check subdomain with decompression, compressed is parent | |
static int | soa_in_auth (struct msg_parse *msg) |
Check if there are SOA records in the authority section (negative) | |
static int | type_allowed_in_authority_section (uint16_t tp) |
Check if type is allowed in the authority section. | |
static int | type_allowed_in_additional_section (uint16_t tp) |
Check if type is allowed in the additional section. | |
static void | shorten_rrset (sldns_buffer *pkt, struct rrset_parse *rrset, int count) |
Shorten RRset. | |
static int | scrub_normalize (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, struct regional *region, struct module_env *env) |
This routine normalizes a response. More... | |
static void | store_rrset (sldns_buffer *pkt, struct msg_parse *msg, struct module_env *env, struct rrset_parse *rrset) |
Store potential poison in the cache (only if hardening disabled). More... | |
static int | sanitize_nsec_is_overreach (sldns_buffer *pkt, struct rrset_parse *rrset, uint8_t *zonename) |
Check if right hand name in NSEC is within zone. More... | |
static int | scrub_sanitize_rr_length (sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *prev, struct rrset_parse **rrset, int *added_ede, struct module_qstate *qstate) |
Remove individual RRs, if the length is wrong. More... | |
static int | scrub_sanitize (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, uint8_t *zonename, struct module_env *env, struct iter_env *ie, struct module_qstate *qstate) |
Given a response event, remove suspect RRsets from the response. More... | |
int | scrub_message (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, uint8_t *zonename, struct regional *region, struct module_env *env, struct module_qstate *qstate, struct iter_env *ie) |
Cleanup the passed dns message. More... | |
This file has routine(s) for cleaning up incoming DNS messages from possible useless or malicious junk in it.
#define RRSET_SCRUB_OK 0x80 |
RRset flag used during scrubbing.
The RRset is OK.
|
static |
This routine normalizes a response.
This includes removing "irrelevant" records from the answer and additional sections and (re)synthesizing CNAMEs from DNAMEs, if present.
pkt | packet. |
msg | msg to normalize. |
qinfo | original query. |
region | where to allocate synthesized CNAMEs. |
env | module env with config options. |
References msg_parse::flags, FLAGS_GET_RCODE, query_info::qname, and query_info::qname_len.
|
static |
Store potential poison in the cache (only if hardening disabled).
The rrset is stored in the cache but removed from the message. So that it will be used for infrastructure purposes, but not be returned to the client.
pkt | packet |
msg | message parsed |
env | environment with cache |
rrset | to store. |
References module_env::alloc, alloc_special_obtain(), alloc_special_release(), lruhash_entry::data, ub_packed_rrset_key::entry, rrset_ref::id, ub_packed_rrset_key::id, rrset_ref::key, module_env::now, packed_rrset_ttl_add(), parse_copy_decompress_rrset(), module_env::rrset_cache, and rrset_cache_update().
|
static |
Check if right hand name in NSEC is within zone.
pkt | the packet buffer for decompression. |
rrset | the NSEC rrset |
zonename | the zone name. |
References log_assert, and rrset_parse::type.
|
static |
Remove individual RRs, if the length is wrong.
Returns true if the RRset has been removed.
References LDNS_RR_TYPE_A, rr_parse::next, and rr_parse::size.
|
static |
Given a response event, remove suspect RRsets from the response.
"Suspect" rrsets are potentially poison. Note that this routine expects the response to be in a "normalized" state – that is, all "irrelevant" RRsets have already been removed, CNAMEs are in order, etc.
pkt | packet. |
msg | msg to normalize. |
qinfo | the question originally asked. |
zonename | name of server zone. |
env | module environment with config and cache. |
ie | iterator environment with private address data. |
qstate | for setting errinf for EDE error messages. |
References LDNS_RR_TYPE_DNAME, msg_parse::rrset_first, rrset_parse::section, and rrset_parse::type.
int scrub_message | ( | struct sldns_buffer * | pkt, |
struct msg_parse * | msg, | ||
struct query_info * | qinfo, | ||
uint8_t * | zonename, | ||
struct regional * | regional, | ||
struct module_env * | env, | ||
struct module_qstate * | qstate, | ||
struct iter_env * | ie | ||
) |
Cleanup the passed dns message.
pkt | the packet itself, for resolving name compression pointers. the packet buffer is unaltered. |
msg | the parsed packet, this structure is cleaned up. |
qinfo | the query info that was sent to the server. Checked. |
zonename | the name of the last delegation point. Used to determine out of bailiwick information. |
regional | where to allocate (new) parts of the message. |
env | module environment with config settings and cache. |
qstate | for setting errinf for EDE error messages. |
ie | iterator module environment data. |
References BIT_AD, BIT_QR, BIT_Z, msg_parse::flags, FLAGS_GET_RCODE, LDNS_RR_TYPE_NS, log_nametypeclass(), query_info::qclass, msg_parse::qdcount, and VERB_ALGO.