Commit Graph

204 Commits

Author SHA1 Message Date
Simon Kelley
ef8e930e42 Generalise cached NXDOMAIN replies.
We can cache an NXDOMAIN reply to a query for any RRTYPE
and reply from a cached NXDOMAIN to any RRTYPE.
2023-03-08 12:47:45 +00:00
Taylor R Campbell
137ae2e9cf Avoid undefined behaviour with the ctype(3) functions.
As defined in the C standard:

	In all cases the argument is an int, the value of which shall
	be representable as an unsigned char or shall equal the value
	of the macro EOF.  If the argument has any other value, the
	behavior is undefined.

This is because they're designed to work with the int values returned
by getc or fgetc; they need extra work to handle a char value.

If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed
inputs to the ctype(3) functions are:

	{-1, 0, 1, 2, 3, ..., 255}.

However, on platforms where char is signed, such as x86 with the
usual ABI, code like

	char *arg = ...;
	... isspace(*arg) ...

may pass in values in the range:

	{-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}.

This has two problems:

1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden.

2. The non-EOF byte 0xff is conflated with the value EOF = -1, so
   even though the input is not forbidden, it may give the wrong
   answer.

Casting char to int first before passing the result to ctype(3)
doesn't help: inputs like -128 are unchanged by this cast.  It is
necessary to cast char inputs to unsigned char first; you can then
cast to int if you like but there's no need because the functions
will always convert the argument to int by definition.  So the above
fragment needs to be:

	char *arg = ...;
	... isspace((unsigned char)*arg) ...

This patch inserts unsigned char casts where necessary, and changes
int casts to unsigned char casts where the input is char.

I left alone int casts where the input is unsigned char already --
they're not immediately harmful, although they would have the effect
of suppressing some compiler warnings if the input is ever changed to
be char instead of unsigned char, so it might be better to remove
those casts too.

I also left alone calls where the input is int to begin with because
it came from getc; casting to unsigned char here would be wrong, of
course.
2023-02-27 14:56:25 +00:00
Simon Kelley
e939b45c9f Handle malformed DNS replies better.
If we detect that that reply from usptream is malformed,
transform it into a SERVFAIL reply before sending to the
original requestor.
2022-11-26 22:19:29 +00:00
Simon Kelley
d334e7c34f Add --use-stale-cache option. 2022-09-06 22:43:33 +01:00
Simon Kelley
f4c87b504b Fix missing reverse-records from --dynamic-host.
Thanks to Sten Spans for spotting the bug.
2022-02-18 20:53:56 +00:00
Simon Kelley
c6d4c33d61 Bump copyright to 2022. 2022-01-24 15:19:00 +00:00
Simon Kelley
47aefca5e4 Add --nftset option, like --ipset but for the newer nftables.
Thanks to Chen Zhenge for the original patch, which I've
reworked. Any bugs down to SRK.
2021-09-27 21:49:28 +01:00
Dominik DL6ER
e0ce3c12f2 Add all current RR types to the table of type names used for query logging.
This patch also changes the method of calling querystr() such that
it is only called when logging is enabled, to eliminate any
possible performance problems from searching the larger table.
2021-09-10 23:13:53 +01:00
Simon Kelley
1ce1c6beae Caching cleanup. Use cached NXDOMAIN to answer queries of any type. 2021-09-05 18:47:45 +01:00
Simon Kelley
860a9a57d6 Get logging of DNSSEC status right when Checking Disabled bit set. 2021-09-02 10:07:08 +01:00
Dominik DL6ER
c83e33d608 Final logging tweaks. 2021-09-01 21:19:47 +01:00
Simon Kelley
7b80c75d9d Rationalise query-reply logging.
Try and log exactly what was returned, rather than just what
got cached. Also give validation status of RRsets if extra logging specified.

This commit also fixes a long-standing bug in caching of CNAME chains
leading to a PTR record.

Based on and inspired by a patch from Dominik DL6ER <dl6er@dl6er.de>
2021-08-31 18:23:03 +01:00
Simon Kelley
5bcca1219a Support IPv6 in --bogus-nxdomian and --ignore-address 2021-07-04 22:27:00 +01:00
Simon Kelley
4558c26fcd Make --rebind-localhost-ok apply to :: and 0.0.0.0
Also make the definition of local IPv6 addresses
the same for --bogus-priv and rebind protection.
2021-07-04 21:09:10 +01:00
Etan Kissling
9d806c51c2 Fix ipset support.
This fixes a problem with ipset processing that got recently introduced
when `extract_request` filtering was tightened. During the recent change
an incorrect assumption was made that `extract_request` was only called
for requests but with ipset it is also called when processing responses.

The fix ensures that the new filters only apply to requests (QR=0 @ hdr)

Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-06-30 12:31:51 +01:00
Simon Kelley
b908f4334b Merge branch 'extended-error' 2021-06-26 00:38:55 +01:00
Simon Kelley
6261aba026 Initial implementation of RFC-8914 extended DNS errors. 2021-06-26 00:38:01 +01:00
Simon Kelley
85bc7534da Rationalise --server parsing and datastructure building.
Use add_update_server for everything.
2021-06-25 22:09:08 +01:00
Simon Kelley
25ff956c7d Tidy up name buffer use in report_addresses().
Buffer may need to be twice MAXDNAME is escaping is
enabled in extract_name. The name may include weird characters.
2021-06-21 15:05:28 +01:00
Etan Kissling
627056febb Connection track mark based DNS query filtering.
This extends query filtering support beyond what is currently possible
with the `--ipset` configuration option, by adding support for:
1) Specifying allowlists on a per-client basis, based on their
   associated Linux connection track mark.
2) Dynamic configuration of allowlists via Ubus.
3) Reporting when a DNS query resolves or is rejected via Ubus.
4) DNS name patterns containing wildcards.

Disallowed queries are not forwarded; they are rejected
with a REFUSED error code.

Signed-off-by: Etan Kissling <etan_kissling@apple.com>
(addressed reviewer feedback)
Signed-off-by: Etan Kissling <etan.kissling@gmail.com>
2021-06-21 14:14:55 +01:00
Simon Kelley
12a9aa7c62 Major rewrite of the DNS server and domain handling code.
This should be largely transparent, but it drastically
improves performance and reduces memory foot-print when
configuring large numbers domains of the form
local=/adserver.com/
or
local=/adserver.com/#

Lookup times now grow as log-to-base-2 of the number of domains,
rather than greater than linearly, as before.
The change makes multiple addresses associated with a domain work
address=/example.com/1.2.3.4
address=/example.com/5.6.7.8
It also handles multiple upstream servers for a domain better; using
the same try/retry alogrithms as non domain-specific servers. This
also applies to DNSSEC-generated queries.

Finally, some of the oldest and gnarliest code in dnsmasq has had
a significant clean-up. It's far from perfect, but it _is_ better.
2021-06-08 22:10:55 +01:00
Simon Kelley
9eaa91bfc3 Teach --bogus-nxdomain and --ignore-address to take a subnet argument. 2021-03-17 20:31:06 +00:00
Simon Kelley
c8e8f5c204 Bump copyright notices for 2021. Happy New Year! 2021-01-24 21:59:37 +00:00
Simon Kelley
1eb6cedb03 Fix DNS reply when asking for DNSSEC and a validated CNAME is already cached. 2020-12-16 15:49:02 +00:00
Simon Kelley
2d765867c5 Use SHA-256 to provide security against DNS cache poisoning.
Use the SHA-256 hash function to verify that DNS answers
received are for the questions originally asked. This replaces
the slightly insecure SHA-1 (when compiled with DNSSEC) or
the very insecure CRC32 (otherwise). Refer: CERT VU#434904.
2020-12-16 15:49:02 +00:00
Dominik DL6ER
e7ee1aa093 Extend stop-dns-rebind to reject IPv6 LL and ULA addresses.
We also reject the loopback address if rebind-localhost-ok is NOT set.

Signed-off-by: DL6ER <dl6er@dl6er.de>
2020-03-17 22:59:17 +00:00
Petr Menšík
29ae308398 Restore ability to answer non-recursive requests
Instead, check only local configured entries are answered without
rdbit set. All cached replies are still denied, but locally configured
names are available with both recursion and without it.

Fixes commit 4139298d28 unintended
behaviour.
2020-02-11 21:01:28 +00:00
Simon Kelley
2a8710ac2f Update copyrights to 2020. 2020-01-05 16:40:06 +00:00
Simon Kelley
1aef66bb34 New CNAME code shouldn't spin on CNAME loops. 2019-11-30 21:07:15 +00:00
Simon Kelley
4a1c21d62c Fix spin-crash in new CNAME code (b59a5c2567)
Thanks to Tore Anderson for finding this.
2019-11-30 20:59:44 +00:00
Simon Kelley
1fd56c0e33 Tidy up CNAME representaion.
Use an explicit discriminator for the target union.
2019-10-30 12:58:28 +00:00
Simon Kelley
84449bf41c Generalise locally-configured CNAME handling.
It's now possible for the target of a CNAME to be any locally
configured RR or even point to a non-existent RR.
2019-10-29 22:24:19 +00:00
Simon Kelley
122997da54 Fix bugs in caching CNAMEs with target to SRV records. 2019-10-25 17:23:56 +01:00
Simon Kelley
b59a5c2567 Generalise CNAME handling.
Cope with cached and configured CNAMES for all record types we
support, including local-config but not cached types such as TXT.

Also, if we have a locally configured CNAME but no target for the
requested type, don't forward the query.
2019-10-25 16:13:38 +01:00
Simon Kelley
ae7a3b9d2e DNSSEC: implement RFC-4036 para 5.3.3. rules on TTL values. 2019-09-03 14:40:47 +01:00
Simon Kelley
5b99eae59d Cache SRV records.
Inpsired by a patch from Jeremy Allison, but completely re-rolled
by srk. All bugs are mine.
2019-01-06 23:09:50 +00:00
Simon Kelley
cc921df9ce Remove nested struct/union in cache records and all_addr. 2019-01-02 22:48:59 +00:00
Simon Kelley
65a01b71bb Tidy address-union handling: move class into explicit argument.
This moves the class argument to cache-insert into an argument,
rather then overloading a union in the address argument. Note that
tha class is NOT stored in the cache other than for DS/DNSKEY entries,
so must always be C_IN except for these. The data-extraction code
ensures this as it only attempts to cache C_IN class records.
2018-12-31 23:56:33 +00:00
Simon Kelley
bde46476ee Tidy all_addr union, merge log and rcode fields. 2018-12-31 23:28:24 +00:00
Simon Kelley
07e25da5bf Treat DS and DNSKEY queries being forwarded the same as those locally originated.
The queries will not be forwarded to a server for a domain, unless
there's a trust anchor provided for that domain. This allows, especially,
suitable proof of non-existance for DS records to come from
the parent domain for domains which are not signed.
2018-12-16 18:21:58 +00:00
Simon Kelley
6f7812d97b Fix spurious AD flags in some DNS replies from local config. 2018-10-23 23:54:44 +01:00
Simon Kelley
cbb5b17ad8 Fix logging in cf5984367b 2018-10-23 23:45:57 +01:00
Vladislav Grishenko
cf5984367b Don't forward *.bind/*.server queries upstream
Chaos .bind and .server (RFC4892) zones are local, therefore
don't forward queries upstream to avoid mixing with supported
locally and false replies with NO_ID enabled.
2018-10-23 23:08:15 +01:00
Simon Kelley
ee8750451b Remove ability to compile without IPv6 support.
This was the source of a large number of #ifdefs, originally
included for use with old embedded libc versions. I'm
sure no-one wants or needs IPv6-free code these days, so this
is a move towards more maintainable code.
2018-10-23 22:10:17 +01:00
Simon Kelley
a220545c42 Ensure that AD bit is reset on answers from --address=/<domain>/<address>. 2018-10-22 18:21:48 +01:00
Simon Kelley
4139298d28 Change behavior when RD bit unset in queries.
Change anti cache-snooping behaviour with queries with the
recursion-desired bit unset. Instead to returning SERVFAIL, we
now always forward, and never answer from the cache. This
allows "dig +trace" command to work.
2018-09-19 22:27:11 +01:00
Simon Kelley
c346f61535 Handle ANY queries in context of da8b6517de 2018-09-04 21:14:18 +01:00
Simon Kelley
b758b67c37 Improve logging of RRs from --dns-rr. 2018-08-23 21:41:23 +01:00
Simon Kelley
97f876b64c Properly deal with unaligned addresses in DHCPv6 packets.
Thanks to Vladislav Grishenko for spotting this.
2018-08-21 22:06:36 +01:00
Simon Kelley
b6f926fbef Don't return NXDOMAIN to empty non-terminals.
When a record is defined locally, eg an A record for one.two.example then
we already know that if we forward, eg an AAAA query for one.two.example,
and get back NXDOMAIN, then we need to alter that to NODATA. This is handled
by  check_for_local_domain(). But, if we forward two.example, because
one.two.example exists, then the answer to two.example should also be
a NODATA.

For most local records this is easy, just to substring matching.
for A, AAAA and CNAME records that are in the cache, it's more difficult.
The cache has no efficient way to find such records. The fix is to
insert empty (none of F_IPV4, F_IPV6 F_CNAME set) records for each
non-terminal.

The same considerations apply in auth mode, and the same basic mechanism
is used there too.
2018-08-21 17:46:52 +01:00