Commit graph

13916 commits

Author SHA1 Message Date
Artem Boldariev
c2fa72027c TLS: do not ignore readpaused flag in certain circumstances
In some circumstances generic TLS code could have resumed data reading
unexpectedly on the TCP layer code. Due to this, the behaviour of
isc_nm_pauseread() and isc_nm_resumeread() might have been
unexpected. This commit fixes that.

The bug does not seems to have real consequences in the existing code
due to the way the code is used. However, the bug could have lead to
unexpected behaviour and, at any rate, makes the TLS code behave
differently from the TCP code, with which it attempts to be as
compatible as possible.

(cherry picked from commit ec0647d546204a0e09aeaf0e2aabb37f1fb67dd0)
2022-08-02 17:31:15 +03:00
Aram Sargsyan
47e4ef0696 Improve fetch limit logging
When initially hitting the `fetches-per-zone` value, a log message
is being generated for the event of dropping the first fetch, then
any further log events occur only when another fetch is being dropped
and 60 seconds have been passed since the last logged message.

That logic isn't ideal because when the counter of the outstanding
fetches reaches zero, the structure holding the counters' values will
get deleted, and the information about the dropped fetches accumulated
during the last minute will not be logged.

Improve the fcount_logspill() function to makie sure that the final
values are getting logged before the counter object gets destroyed.

(cherry picked from commit 039871ceb767088205563965f7aae622a3f77082)
2022-08-01 13:54:46 +00:00
Artem Boldariev
a957511734 TLS: fix double resumption in isc__nm_tls_resumeread()
This commit fixes an obvious error in isc__nm_tls_resumeread() so that
read cannot be resumed twice.
2022-07-26 15:27:40 +03:00
Artem Boldariev
a165b66fc7 TLS: clear 'errno' when handling SSL status
Sometimes tls_do_bio() might be called when there is no new data to
process (most notably, when resuming reads), in such a case internal
TLS session state will remain untouched and old value in 'errno' will
alter the result of SSL_get_error() call, possibly making it to return
SSL_ERROR_SYSCALL. This value will be treated as an error, and will
lead to closing the connection, which is not what expected.
2022-07-26 15:27:40 +03:00
Mark Andrews
f3a0dac057 Check that we can verify a signature at initialisation time
Fedora 33 doesn't support RSASHA1 in future mode.  There is no easy
check for this other than by attempting to perform a verification
using known good signatures.  We don't attempt to sign with RSASHA1
as that would not work in FIPS mode.  RSASHA1 is verify only.

The test vectors were generated using OpenSSL 3.0 and
util/gen-rsa-sha-vectors.c.  Rerunning will generate a new set of
test vectors as the private key is not preserved.

e.g.
	cc util/gen-rsa-sha-vectors.c -I /opt/local/include \
		-L /opt/local/lib -lcrypto

(cherry picked from commit cd3f00874f63a50954cebb78edac8f580a27c0de)
2022-07-25 10:59:38 -04:00
Matthijs Mekking
56f1bf250d Fix rndc dumpdb -expired for stuck cache contents
The command 'rndc dumpdb -expired' will include expired RRsets in the
output, but only for the RBTDB_VIRTUAL time (of 5 minutes). This means
that if there is a cache cleaning problem and contents are not cleaned
up, the rndc command has little diagnostic value. Fix this by including
all RRsets in the dumpdb output if the '-expired' flag is set.

(cherry picked from commit 930ba2c914a0abc07fd087d663a7bfb57850d4ca)
2022-07-25 16:28:18 +02:00
Evan Hunt
4720f13730 warn about zones with both dnssec-policy and max-zone-ttl
max-zone-ttl in zone/view/options is a no-op if dnssec-policy
is in use, so generate a warning.
2022-07-22 13:13:24 -07:00
Ondřej Surý
3c1d6e164e
Increase the BUFSIZ-long buffers
The BUFSIZ value varies between platforms, it could be 8K on Linux and
512 bytes on mingw.  Make sure the buffers are always big enough for the
output data to prevent truncation of the output by appropriately
enlarging or sizing the buffers.

(cherry picked from commit b19d932262e84608174cb89eeed32ae0212f8a87)
2022-07-15 21:16:51 +02:00
Evan Hunt
7903bffbc4 remove unnecessary assertion in dns_dispatch_connect()
When a thread calls dns_dispatch_connect() on an unconnected TCP socket
it sets `tcpstate` from `DNS_DISPATCHSTATE_NONE` to `_CONNECTING`.
Previously, it then INSISTed that there were no pending connections
before calling isc_nm_tcpdnsconnect().

If a second thread called dns_dispatch_connect() during that window
of time, it could add a pending connection to the list, and trigger
an assertion failure.

This commit removes the INSIST since the condition is actually
harmless.

(cherry picked from commit 25ddec8a0a8e0549b69f4e601028f3323d3c1886)
2022-07-14 19:27:24 -07:00
Ondřej Surý
d242ced18f
Cleanup the STATID_CONNECT and STATID_CONNECTFAIL stat counters
The STATID_CONNECT and STATID_CONNECTFAIL statistics were used
incorrectly. The STATID_CONNECT was incremented twice (once in
the *_connect_direct() and once in the callback) and STATID_CONNECTFAIL
would not be incremented at all if the failure happened in the callback.

Closes: #3452
(cherry picked from commit 59e1703b50dc4a5c52e3d6ae13bdd873a677b03f)
2022-07-14 21:48:44 +02:00
Ondřej Surý
259f4481bd
Handle the transient TCP connect() failures on FreeBSD
On FreeBSD (and perhaps other *BSD) systems, the TCP connect() call (via
uv_tcp_connect()) can fail with transient UV_EADDRINUSE error.  The UDP
code already handles this by trying three times (is a charm) before
giving up.  Add a code for the TCP, TCPDNS and TLSDNS layers to also try
three times before giving up by calling uv_tcp_connect() from the
callback two more time on UV_EADDRINUSE error.

Additionally, stop the timer only if we succeed or on hard error via
isc__nm_failed_connect_cb().

(cherry picked from commit b21f507c0ac5b5d2d2c27fd2d71e27e8605dd5fc)
2022-07-14 21:47:47 +02:00
Mark Andrews
937794c2da disassociate rdatasets when cleaning up
free_namelist could be passed names with associated rdatasets
when handling errors.  These need to be disassociated before
calling dns_message_puttemprdataset.

(cherry picked from commit 745d5edc3a8ca6f232b2d700ae076c2caee2bfc5)
2022-07-14 10:21:38 +10:00
Michał Kępień
b855c6b6c9 Stop resolving invalid names in resume_dslookup()
Commit 7b2ea97e46 introduced a logic bug
in resume_dslookup(): that function now only conditionally checks
whether DS chasing can still make progress.  Specifically, that check is
only performed when the previous resume_dslookup() call invokes
dns_resolver_createfetch() with the 'nameservers' argument set to
something else than NULL, which may not always be the case.  Failing to
perform that check may trigger assertion failures as a result of
dns_resolver_createfetch() attempting to resolve an invalid name.

Example scenario that leads to such outcome:

 1. A validating resolver is configured to forward all queries to
    another resolver.  The latter returns broken DS responses that
    trigger DS chasing.

 2. rctx_chaseds() calls dns_resolver_createfetch() with the
    'nameservers' argument set to NULL.

 3. The fetch fails, so resume_dslookup() is called.  Due to
    fevent->result being set to e.g. DNS_R_SERVFAIL, the default branch
    is taken in the switch statement.

 4. Since 'nameservers' was set to NULL for the fetch which caused the
    resume_dslookup() callback to be invoked
    (fctx->nsfetch->private->nameservers), resume_dslookup() chops off
    one label off fctx->nsname and calls dns_resolver_createfetch()
    again, for a name containing one label less than before.

 5. Steps 3-4 are repeated (i.e. all attempts to find the name servers
    authoritative for the DS RRset being chased fail) until fctx->nsname
    becomes stripped down the the root name.

 6. Since resume_dslookup() does not check whether DS chasing can still
    make progress, it strips off a label off the root name and continues
    its attempts at finding the name servers authoritative for the DS
    RRset being chased, passing an invalid name to
    dns_resolver_createfetch().

Fix by ensuring resume_dslookup() always checks whether DS chasing can
still make progress when a name server fetch fails.  Update code
comments to ensure the purpose of the relevant dns_name_equal() check is
clear.

(cherry picked from commit 1a79aeab44)
2022-07-13 11:00:32 +02:00
Evan Hunt
b66cd7b2fc clear fctx->magic and fetch->magic when destroying
fctx_destroy() and dns_resolver_destroyfetch() did not clear the
'magic' field during destruction.

(cherry picked from commit 5ec077e6aa)
2022-07-13 02:12:35 +00:00
Mark Andrews
7f101aeb53 Update libdns_la_LIBADD rather than libdns_la_LDFLAGS
the wrong macro was being update with MAXMINDDB_LIBS making
it difficult to adjust link order.

(cherry picked from commit 5b51610174)
2022-07-13 10:46:37 +10:00
Evan Hunt
cc3070a0b3 log the reason for falling back to AXFR from IXFR at level info
messages indicating the reason for a fallback to AXFR (i.e, because
the requested serial number is not present in the journal, or because
the size of the IXFR response would exceeed "max-ixfr-ratio") are now
logged at level info instead of debug(4).

(cherry picked from commit df1d81cf96)
2022-07-12 16:26:13 -07:00
Artem Boldariev
814baa3e6b TLS: do not ignore accept callback result
Before this change the TLS code would ignore the accept callback result,
and would not try to gracefully close the connection. This had not been
noticed, as it is not really required for DoH. Now the code tries to
shut down the TLS connection gracefully when accepting it is not
successful.

(cherry picked from commit ffcb54211e)
2022-07-12 15:32:45 +03:00
Artem Boldariev
c85949fbe1 TLSDNS: try pass incoming data to OpenSSL if there are any
Otherwise the code path will lead to a call to SSL_get_error()
returning SSL_ERROR_SSL, which in turn might lead to closing
connection to early in an unexpected way, as it is clearly not what is
intended.

The issue was found when working on loppmgr branch and appears to
be timing related as well. Might be responsible for some unexpected
transmission failures e.g. on zone transfers.

(cherry picked from commit 8585b92f98)
2022-07-12 15:29:36 +03:00
Artem Boldariev
ba7fabde01 TLS: bail out earlier when NM is stopping
In some operations - most prominently when establishing connection -
it might be beneficial to bail out earlier when the network manager
is stopping.

The issue is backported from loopmgr branch, where such a change is
not only beneficial, but required.

(cherry picked from commit fc74b15e67)
2022-07-12 15:28:15 +03:00
Artem Boldariev
0754def85d TLS: sometimes TCP conn. handle might be NULL on when connecting
In some cases - in particular, in case of errors, NULL might be passed
to a connection callback instead of a handle that could have led to
an abort. This commit ensures that such a situation will not occur.

The issue was found when working on the loopmgr branch.

(cherry picked from commit ac4fb34f18)
2022-07-12 15:26:50 +03:00
Artem Boldariev
c44633feb2 TLS: try to close sockets whenever there are no pending operations
This commit ensures that the underlying TCP socket of a TLS connection
gets closed earlier whenever there are no pending operations on it.

In the loop-manager branch, in some circumstances the connection
could have remained opened for far too long for no reason. This
commit ensures that will not happen.

(cherry picked from commit 88524e26ec)
2022-07-12 15:25:30 +03:00
Artem Boldariev
3e69cc35b8 TLS: Implement isc_nmhandle_setwritetimeout()
This commit adds a proper implementation of
isc_nmhandle_setwritetimeout() for TLS connections. Now it passes the
value to the underlying TCP handle.

(cherry picked from commit 237ce05b89)
2022-07-12 15:22:57 +03:00
Mark Andrews
44bfc8a9b2 Clone the message buffer before forwarding UPDATE messages
this prevents named forwarding a buffer that may have been over
written.

(cherry picked from commit 7a42417d61)
2022-07-12 19:00:38 +10:00
Evan Hunt
30534b125e try other servers when receiving FORMERR
previously, when an iterative query returned FORMERR, resolution
would be stopped under the assumption that other servers for
the same domain would likely have the same capabilities. this
assumption is not correct; some domains have been reported for
which some but not all servers will return FORMERR to a given
query; retrying allows recursion to succeed.

(cherry picked from commit f6abb80746)
2022-07-06 22:19:20 +00:00
Mark Andrews
30d4e3ee89 Add synth-from-dnssec namespaces for keytable entries
We do this by adding callbacks for when a node is added or deleted
from the keytable.  dns_keytable_add and dns_keytable_delete where
extended to take a callback.  dns_keytable_deletekey does not remove
the node so it was not extended.

(cherry picked from commit a5b57ed293)
2022-07-07 07:47:45 +10:00
Mark Andrews
107c3a452a Add entries to the synth-from-dnssec namespace tree for zones
When a zone is attached or detached from the view (zone->view is
updated) update the synth-from-dnssec namespace tree.

(cherry picked from commit f716bd68d4)
2022-07-07 07:47:45 +10:00
Mark Andrews
4d9287dca5 Check the synth-form-dnssec namespace when synthesising responses
Call dns_view_sfd_find to find the namespace to be used to verify
the covering NSEC records returned for the given QNAME.  Check that
the NSEC owner names are within that namespace.

(cherry picked from commit 228dadb026)
2022-07-07 07:47:45 +10:00
Mark Andrews
b979b6be40 Add a mechanism to record namespaces for synth-from-dnssec
When namespace is grafted on, the DNSSEC proofs for non existance
need to come from that namespace and not a higher namespace.  We
add 3 function dns_view_sfd_add, dns_view_sfd_del and dns_view_sfd_find
to add, remove and find the namespace that should be used when
checking NSEC records.

dns_view_sfd_add adds a name to a tree, creating the tree if needed.
If the name already existed in the tree the reference count is
increased otherwise it is initalised to 1.

dns_view_sfd_del removes a reference to a name in the tree, if the
count goes to 0 the node is removed.

dns_view_sfd_find returns the namespace to be used to entered name.
If there isn't an enclosing name in the tree, or the tree does not
yet exist, the root name is returned.

Access to the tree is controlled by a read/write lock.

(cherry picked from commit 3619cad141)
2022-07-07 07:47:45 +10:00
Mark Andrews
656e33ce18 Tighten $GENERATE directive parsing
The original sscanf processing allowed for a number of syntax errors
to be accepted.  This included missing the closing brace in
${modifiers}

Look for both comma and right brace as intermediate seperators as
well as consuming the final right brace in the sscanf processing
for ${modifiers}.  Check when we got right brace to determine if
the sscanf consumed more input than expected and if so behave as
if it had stopped at the first right brace.

(cherry picked from commit 7be64c0e94)
2022-07-06 11:25:20 +10:00
Mark Andrews
72999440bd Check for overflow in $GENERATE computations
$GENERATE uses 'int' for its computations and some constructions
can overflow values that can be represented by an 'int' resulting
in undefined behaviour.  Detect these conditions and return a
range error.

(cherry picked from commit 5327b9708f)
2022-07-06 11:25:20 +10:00
Evan Hunt
b061e86d17 REQUIRE should not have side effects
it's a style violation to have REQUIRE or INSIST contain code that
must run for the server to work. this was being done with some
atomic_compare_exchange calls. these have been cleaned up.  uses
of atomic_compare_exchange in assertions have been replaced with
a new macro atomic_compare_exchange_enforced, which uses RUNTIME_CHECK
to ensure that the exchange was successful.

(cherry picked from commit a499794984)
2022-07-05 13:04:17 -07:00
Artem Boldariev
b6b07c5646 Update the set of HTTP endpoints on reconfiguration
This commit ensures that on reconfiguration the set of HTTP
endpoints (=paths) is being updated within HTTP listeners.

(cherry picked from commit d2e13ddf22)
2022-06-28 16:37:31 +03:00
Artem Boldariev
bb8ba2c027 Update max concurrent streams limit in HTTP listeners on reconfig
This commit ensures that HTTP listeners concurrent streams limit gets
updated properly on reconfiguration.

(cherry picked from commit e72962d5f1)
2022-06-28 16:37:31 +03:00
Artem Boldariev
1ccbb24078 Update HTTP listeners quotas on reconfiguration
This commit ensures that on reconfiguration a proper value for HTTP
connections limit is picked up.

The commit also refactors how listeners settings are updated so that
there is less code duplication.

(cherry picked from commit a2379135fa)
2022-06-28 16:37:31 +03:00
Artem Boldariev
63a4c12227 Store HTTP quota size inside a listenlist instead of the quota
This way only quota size is passed to the interface/listener
management code instead of a quota object. Thus, we can implement
updating the quota object size instead of recreating the object.

(cherry picked from commit 3f0b310772)
2022-06-28 16:37:31 +03:00
Matthijs Mekking
35f6cabab4 Add isccfg duration utility functions
Add function isccfg_duration_toseconds and isccfg_parse_duration to get
rid of code duplication.

(cherry picked from commit d8dae61832)
2022-06-28 14:37:26 +02:00
Matthijs Mekking
feaf3950fd Fix a bug in the duration_fromtext function
The function actually did not enforce that the duration string starts
with a P (or p), just that there is a P (or p) in the string.

(cherry picked from commit 8e18fa5874)
2022-06-28 14:37:19 +02:00
Matthijs Mekking
8af88d4111 Also inherit from "default" for "insecure" policy
Remove the duplication from the defaultconf and inherit the values
not set in the "insecure" policy from the "default" policy. Therefore,
we must insist that the first read built-in policy is the default one.

(cherry picked from commit c2a7950417)
2022-06-28 14:37:10 +02:00
Matthijs Mekking
fd34ea8523 Nit changes in keymgr and kasp
Use the ISC_MAX define instead of "x = a > b ? a : b" paradigm.

Remove an unneeded include.

(cherry picked from commit 5d6f0de84b)
2022-06-28 14:36:53 +02:00
Matthijs Mekking
e16cfce91d When loading dnssec-policies, inherit from default
Most of the settings (durations) are already inheriting from the default
because they use the constants from lib/dns/kasp.h. We need them as
constants so we can use them in named-checkconf to verify the policy
parameters.

The NSEC(3) parameters and keys should come from the actual default
policy. Change the call to cfg_kasp_fromconfig() to include the default
kasp. We also no longer need to corner case where config is NULL we load
the built-in policy: the built-in policies are now loaded when config is
set to named_g_config.

Finally, add a debug log (it is useful to see which policies are being
loaded).

(cherry picked from commit 20acb8d3a3)
2022-06-28 14:36:45 +02:00
Matthijs Mekking
03c0c72aeb Store built-in dnssec-policies in defaultconf
Update the defaultconf with the built-in policies. These will now be
printed with "named -C".

Change the defines in kasp.h to be strings, so they can be concatenated
in the defaultconf. This means when creating a kasp structure, we no
longer initialize the defaults (this is fine because only kaspconf.c
uses dns_kasp_create() and it inherits from the default policy).

In kaspconf.c, the default values now need to be parsed from string.

Introduce some variables so we don't need to do get_duration multiple
times on the same configuration option.

Finally, clang-format-14 decided to do some random formatting changes.

(cherry picked from commit 5ff414e986)
2022-06-28 14:36:38 +02:00
Matthijs Mekking
4fb2ecd444 Move duration structure to libisccfg/duration
Having the duration structure and parsing code here, it becomes
more accessible to be used in other places.

(cherry picked from commit a28d919503)
2022-06-28 14:36:31 +02:00
Michał Kępień
457b666c6f Fix destination port extraction for client queries
The current logic for determining the address of the socket to which a
client sent its query is:

 1. Get the address:port tuple from the netmgr handle using
    isc_nmhandle_localaddr().

 2. Convert the address:port tuple from step 1 into an isc_netaddr_t
    using isc_netaddr_fromsockaddr().

 3. Convert the address from step 2 back into a socket address with the
    port set to 0 using isc_sockaddr_fromnetaddr().

Note that the port number (readily available in the netmgr handle) is
needlessly lost in the process, preventing it from being recorded in
dnstap captures of client traffic produced by named.

Fix by first storing the address:port tuple returned by
isc_nmhandle_localaddr() in client->destsockaddr and then creating an
isc_netaddr_t from that structure.  This allows the port number to be
retained in client->destsockaddr, which is what subsequently gets passed
to dns_dt_send().

(cherry picked from commit 2f945703f2)
2022-06-22 13:46:42 +02:00
Michal Nowak
d3eb307e3c
Update clang to version 14
(cherry picked from commit 1c45a9885a)
2022-06-16 18:09:33 +02:00
Artem Boldariev
b3490213eb CID 352848: split xfrin_start() and remove dead code
This commit separates TLS context creation code from xfrin_start() as
it has become too large and hard to follow into a new
function (similarly how it is done in dighost.c)

The dead code has been removed from the cleanup section of the TLS
creation code:

* there is no way 'tlsctx' can equal 'found';
* there is no way 'sess_cache' can be non-NULL in the cleanup section.

Also, it fixes a bug in the older version of the code, where TLS
client session context fetched from the cache would not get passed to
isc_nm_tlsdnsconnect().

(cherry picked from commit 98f758ed4f)
2022-06-15 17:02:45 +03:00
Artem Boldariev
334eeef5a1 Do not provide a shim for SSL_SESSION_is_resumable()
The recently added TLS client session cache used
SSL_SESSION_is_resumable() to avoid polluting the cache with
non-resumable sessions. However, it turned out that we cannot provide
a shim for this function across the whole range of OpenSSL versions
due to the fact that OpenSSL 1.1.0 does uses opaque pointers for
SSL_SESSION objects.

The commit replaces the shim for SSL_SESSION_is_resumable() with a non
public approximation of it on systems shipped with OpenSSL 1.1.0. It
is not turned into a proper shim because it does not fully emulate the
behaviour of SSL_SESSION_is_resumable(), but in our case it is good
enough, as it still helps to protect the cache from pollution.

For systems shipped with OpenSSL 1.0.X and derivatives (e.g. older
versions of LibreSSL), the provided replacement perfectly mimics the
function it is intended to replace.

(cherry picked from commit 40be3c9263)
2022-06-15 17:02:45 +03:00
Artem Boldariev
0cec9cca37 Fix an abort in DoH (client-side) when writing on closing sock
The commit fixes a corner case in client-side DoH code, when a write
attempt is done on a closing socket (session).

The change ensures that the write call-back will be called with a
proper error code (see failed_send_cb() call in client_httpsend()).

(cherry picked from commit 9abb00bb5f)
2022-06-15 17:02:45 +03:00
Artem Boldariev
cb6591f277 Avoid aborting when uv_timer_start() is used on a closing socket
In such a case it will return UV_EINVAL (-EINVAL), leading to
aborting, as the code expects the function to succeed.

(cherry picked from commit 245f7cec2e)
2022-06-15 17:02:45 +03:00
Artem Boldariev
5154bac7c5 Add SSL_SESSION_is_resumable() implementation shim
This commit adds SSL_SESSION_is_resumable() implementation if it is
missing.

(cherry picked from commit 35338b4105)
2022-06-15 17:02:45 +03:00
Artem Boldariev
e02284354a DoT: implement TLS client session resumption
This commit extends DoT code with TLS client session resumption
support implemented on top of the TLS client session cache.

(cherry picked from commit 86465c1dac)
2022-06-15 17:02:45 +03:00