Implement DoT support for nsupdate

Implement DNS-over-TLS support for nsupdate. Use DiG's DoT
implementation as a model for the newly added features.
This commit is contained in:
Aram Sargsyan
2022-09-21 08:20:22 +00:00
parent 73cc9a3232
commit 13000c28c2
3 changed files with 210 additions and 29 deletions

View File

@@ -62,9 +62,13 @@ dns_transport_get_tls_versions(const dns_transport_t *transport);
bool
dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport,
bool *preferp);
bool
dns_transport_get_always_verify_remote(dns_transport_t *transport);
/*%<
* Getter functions: return the type, cert file, key file, CA file,
* hostname, HTTP endpoint, or HTTP mode (GET or POST) for 'transport'.
* hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, TLS name,
* TLS version, server ciphers preference mode, and always enabling
* authentication mode for 'transport'.
*
* dns_transport_get_prefer_server_ciphers() returns 'true' is value
* was set, 'false' otherwise. The actual value is returned via
@@ -80,6 +84,13 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer,
* Get the transport's TLS Context and the TLS Client Session Cache associated
* with it.
*
* When neither the TLS hostname, nor the TLS certificates authorities (CA)
* file are set for the 'transport', then Opportunistic TLS (no authentication
* of the remote peer) will be used, unless the 'always_verify_remote' mode is
* enabled on the 'transport', in which case the remote peer will be
* authenticated by its IP address using the system's default certificates
* authorities store.
*
* Requires:
*\li 'transport' is a valid, 'DNS_TRANSPORT_TLS' type transport.
*\li 'peer' is not NULL.
@@ -113,9 +124,14 @@ dns_transport_set_tls_versions(dns_transport_t *transport,
void
dns_transport_set_prefer_server_ciphers(dns_transport_t *transport,
const bool prefer);
void
dns_transport_set_always_verify_remote(dns_transport_t *transport,
const bool always_verify_remote);
/*%<
* Setter functions: set the type, cert file, key file, CA file,
* hostname, HTTP endpoint, or HTTP mode (GET or POST) for 'transport'.
* hostname, HTTP endpoint, HTTP mode (GET or POST), ciphers, TLS name,
* TLS version, server ciphers preference mode, and always enabling
* authentication mode for 'transport'.
*
* Requires:
*\li 'transport' is valid.

View File

@@ -56,6 +56,7 @@ struct dns_transport {
char *ciphers;
uint32_t protocol_versions;
ternary_t prefer_server_ciphers;
bool always_verify_remote;
} tls;
struct {
char *endpoint;
@@ -334,6 +335,25 @@ dns_transport_get_prefer_server_ciphers(const dns_transport_t *transport,
return false;
}
void
dns_transport_set_always_verify_remote(dns_transport_t *transport,
const bool always_verify_remote) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_HTTP);
transport->tls.always_verify_remote = always_verify_remote;
}
bool
dns_transport_get_always_verify_remote(dns_transport_t *transport) {
REQUIRE(VALID_TRANSPORT(transport));
REQUIRE(transport->type == DNS_TRANSPORT_TLS ||
transport->type == DNS_TRANSPORT_HTTP);
return transport->tls.always_verify_remote;
}
isc_result_t
dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer,
isc_tlsctx_cache_t *tlsctx_cache, isc_mem_t *mctx,
@@ -378,6 +398,8 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer,
const char *ca_file = dns_transport_get_cafile(transport);
const char *cert_file = dns_transport_get_certfile(transport);
const char *key_file = dns_transport_get_keyfile(transport);
const bool always_verify_remote =
dns_transport_get_always_verify_remote(transport);
char peer_addr_str[INET6_ADDRSTRLEN] = { 0 };
isc_netaddr_t peer_netaddr = { 0 };
bool hostname_ignore_subject;
@@ -406,7 +428,8 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer,
prefer_server_ciphers);
}
if (hostname != NULL || ca_file != NULL) {
if (always_verify_remote || hostname != NULL || ca_file != NULL)
{
/*
* The situation when 'found_store != NULL' while
* 'found == NULL' may occur as there is a one-to-many
@@ -433,12 +456,9 @@ dns_transport_get_tlsctx(dns_transport_t *transport, const isc_sockaddr_t *peer,
INSIST(store != NULL);
if (hostname == NULL) {
/*
* If CA bundle file is specified, but
* hostname is not, then use the peer
* IP address for validation, just like
* dig does.
* If hostname is not specified, then use the
* peer IP address for validation.
*/
INSIST(ca_file != NULL);
isc_netaddr_fromsockaddr(&peer_netaddr, peer);
isc_netaddr_format(&peer_netaddr, peer_addr_str,
sizeof(peer_addr_str));