resolved: load libcrypto/libssl lazily on first use and make them optional
Currently they are marked as required, as resolved aborts on startup if dns-over-tls is built in, even if it is not enabled in the config. Change initialization to be done lazily on first use, so that if the config is not enabled, it never runs, and the libraries are never dlopened, so they can be downgraded to recommends.
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
#include "memory-util.h"
|
||||
#include "memstream-util.h"
|
||||
#include "resolved-dns-dnssec.h"
|
||||
#include "resolved-util.h"
|
||||
#include "sort-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@@ -717,7 +716,7 @@ int dnssec_verify_rrset(
|
||||
assert(dnskey);
|
||||
assert(result);
|
||||
|
||||
r = DLOPEN_LIBCRYPTO(LOG_DEBUG, DLOPEN_LIBCRYPTO_PRIORITY);
|
||||
r = DLOPEN_LIBCRYPTO(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1074,7 +1073,7 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
|
||||
assert(dnskey);
|
||||
assert(ds);
|
||||
|
||||
r = DLOPEN_LIBCRYPTO(LOG_DEBUG, DLOPEN_LIBCRYPTO_PRIORITY);
|
||||
r = DLOPEN_LIBCRYPTO(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1214,7 +1213,7 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
r = DLOPEN_LIBCRYPTO(LOG_DEBUG, DLOPEN_LIBCRYPTO_PRIORITY);
|
||||
r = DLOPEN_LIBCRYPTO(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -786,8 +786,20 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) {
|
||||
|
||||
assert(t->server);
|
||||
r = dnstls_stream_connect_tls(s, t->server);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
/* If libcrypto is not available treat this like a TLS connection loss, so
|
||||
* that opportunistic DNS-over-TLS downgrades to plaintext instead of
|
||||
* re-selecting a TLS feature level and failing on every attempt. */
|
||||
if (r == -EOPNOTSUPP) {
|
||||
log_struct_once(LOG_WARNING,
|
||||
LOG_MESSAGE_ID(SD_MESSAGE_MISSING_DEPENDENCY_STR),
|
||||
LOG_ITEM("FEATURE=DNS-over-TLS"),
|
||||
LOG_MESSAGE("DNS-over-TLS has been requested but the required TLS libraries (libssl/libcrypto) are not installed."));
|
||||
dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level);
|
||||
return -ECONNREFUSED;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -71,6 +71,10 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
|
||||
assert(stream->manager);
|
||||
assert(server);
|
||||
|
||||
r = dnstls_manager_init(stream->manager);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rb = sym_BIO_new_socket(stream->fd, 0);
|
||||
if (!rb)
|
||||
return -ENOMEM;
|
||||
@@ -398,31 +402,39 @@ void dnstls_server_free(DnsServer *server) {
|
||||
}
|
||||
|
||||
int dnstls_manager_init(Manager *manager) {
|
||||
_cleanup_(SSL_CTX_freep) SSL_CTX *ctx = NULL;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
r = DLOPEN_LIBCRYPTO(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED);
|
||||
/* Load libcrypto/libssl on first use, so that the dependencies can be optional. */
|
||||
|
||||
if (manager->dnstls_data.ctx)
|
||||
return 0;
|
||||
|
||||
r = DLOPEN_LIBCRYPTO(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = DLOPEN_LIBSSL(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED);
|
||||
r = DLOPEN_LIBSSL(LOG_WARNING, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
manager->dnstls_data.ctx = sym_SSL_CTX_new(sym_TLS_client_method());
|
||||
if (!manager->dnstls_data.ctx)
|
||||
ctx = sym_SSL_CTX_new(sym_TLS_client_method());
|
||||
if (!ctx)
|
||||
return log_openssl_errors(LOG_WARNING, "Failed to create SSL context");
|
||||
|
||||
r = sym_SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
|
||||
r = sym_SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
|
||||
if (r == 0)
|
||||
return log_openssl_errors(LOG_WARNING, "Failed to set protocol version on SSL context");
|
||||
|
||||
(void) sym_SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
|
||||
(void) sym_SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
|
||||
|
||||
r = sym_SSL_CTX_set_default_verify_paths(manager->dnstls_data.ctx);
|
||||
r = sym_SSL_CTX_set_default_verify_paths(ctx);
|
||||
if (r == 0)
|
||||
return log_openssl_errors(LOG_WARNING, "Failed to load system trust store");
|
||||
|
||||
manager->dnstls_data.ctx = TAKE_PTR(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -754,12 +754,6 @@ int manager_new(Manager **ret) {
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse configuration file, ignoring: %m");
|
||||
|
||||
#if ENABLE_DNS_OVER_TLS
|
||||
r = dnstls_manager_init(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
#endif
|
||||
|
||||
r = sd_event_default(&m->event);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-dlopen.h"
|
||||
|
||||
#if ENABLE_DNS_OVER_TLS
|
||||
# define DLOPEN_LIBCRYPTO_PRIORITY SD_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED
|
||||
#else
|
||||
# define DLOPEN_LIBCRYPTO_PRIORITY SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED
|
||||
#endif
|
||||
|
||||
int resolve_system_hostname(char **full_hostname, char **first_label);
|
||||
|
||||
Reference in New Issue
Block a user