mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'devel/spki_pinset_via_tlsa_checking' into release/1.4.0
This commit is contained in:
commit
ca7c2fe00e
|
@ -9,3 +9,6 @@
|
|||
path = stubby
|
||||
url = https://github.com/getdnsapi/stubby.git
|
||||
branch = develop
|
||||
[submodule "src/ssl_dane"]
|
||||
path = src/ssl_dane
|
||||
url = https://github.com/getdnsapi/ssl_dane
|
||||
|
|
24
configure.ac
24
configure.ac
|
@ -408,7 +408,7 @@ fi
|
|||
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/bn.h openssl/rsa.h openssl/dsa.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_min_proto_version OpenSSL_version_num OpenSSL_version])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_min_proto_version OpenSSL_version_num OpenSSL_version SSL_CTX_dane_enable SSL_dane_enable SSL_dane_tlsa_add])
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
|
@ -431,6 +431,28 @@ AC_INCLUDES_DEFAULT
|
|||
])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether we need to compile/link DANE support])
|
||||
DANESSL_XTRA_OBJS=""
|
||||
AC_LANG_PUSH(C)
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
[#include <openssl/opensslv.h>]
|
||||
[#if OPENSSL_VERSION_NUMBER < 0x1000000fL]
|
||||
[#error "OpenSSL 1.0.0 or higher required for DANE library"]
|
||||
[#elif defined(HAVE_SSL_DANE_ENABLE)]
|
||||
[#error "OpenSSL has native DANE support"]
|
||||
[#elif defined(LIBRESSL_VERSION_NUMBER)]
|
||||
[#error "dane_ssl library does not work with LibreSSL"]
|
||||
[#endif]
|
||||
],[[]])],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([USE_DANESSL], [1], [Define this to use DANE functions from the ssl_dane/danessl library.])
|
||||
DANESSL_XTRA_OBJS="danessl.lo"
|
||||
],
|
||||
[AC_MSG_RESULT([no])])
|
||||
AC_LANG_POP(C)
|
||||
AC_SUBST(DANESSL_XTRA_OBJS)
|
||||
|
||||
AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
|
||||
case "$enable_sha1" in
|
||||
|
|
|
@ -96,7 +96,9 @@ JSMN_OBJ=jsmn.lo
|
|||
YXML_OBJ=yxml.lo
|
||||
|
||||
YAML_OBJ=convert_yaml_to_json.lo
|
||||
GETDNS_XTRA_OBJS=@GETDNS_XTRA_OBJS@
|
||||
DANESSL_OBJ=danessl.lo
|
||||
|
||||
GETDNS_XTRA_OBJS=@GETDNS_XTRA_OBJS@ @DANESSL_XTRA_OBJS@
|
||||
STUBBY_XTRA_OBJS=@STUBBY_XTRA_OBJS@
|
||||
|
||||
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
|
||||
|
@ -133,6 +135,9 @@ $(JSMN_OBJ):
|
|||
$(YAML_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(stubbysrcdir)/src/yaml/$(@:.lo=.c) -o $@
|
||||
|
||||
$(DANESSL_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WNOERRORFLAG) -c $(srcdir)/ssl_dane/$(@:.lo=.c) -o $@
|
||||
|
||||
$(YXML_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -I$(srcdir)/yxml -DYXML_GETDNS -Wno-unused-parameter -c $(srcdir)/yxml/$(@:.lo=.c) -o $@
|
||||
|
||||
|
@ -255,7 +260,7 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
|||
depend:
|
||||
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
||||
|
||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iyxml -Iutil/auxiliary -I../stubby/src *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yxml/*.c extension/*.c ../stubby/src/*.c | \
|
||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iyxml -Iutil/auxiliary -I../stubby/src *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yxml/*.c ssl_dane/danessl.c extension/*.c ../stubby/src/*.c | \
|
||||
sed -e "s? $$blddir/? ?g" \
|
||||
-e 's? gldns/? $$(srcdir)/gldns/?g' \
|
||||
-e 's? compat/? $$(srcdir)/compat/?g' \
|
||||
|
@ -263,6 +268,7 @@ depend:
|
|||
-e 's? util/? $$(srcdir)/util/?g' \
|
||||
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
|
||||
-e 's? yxml/? $$(srcdir)/yxml/?g' \
|
||||
-e 's? ssl_dane/? $$(srcdir)/ssl_dane/?g' \
|
||||
-e 's? extension/? $$(srcdir)/extension/?g' \
|
||||
-e 's? \.\./stubby/? $$(stubbysrcdir)/?g' \
|
||||
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
|
||||
|
@ -311,7 +317,7 @@ context.lo context.o: $(srcdir)/context.c \
|
|||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/dnssec.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h $(srcdir)/ssl_dane/danessl.h
|
||||
convert.lo convert.o: $(srcdir)/convert.c \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
|
@ -450,7 +456,7 @@ stub.lo stub.o: $(srcdir)/stub.c \
|
|||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/anchor.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/util-internal.h $(srcdir)/platform.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h $(srcdir)/ssl_dane/danessl.h
|
||||
sync.lo sync.o: $(srcdir)/sync.c \
|
||||
getdns/getdns.h \
|
||||
config.h \
|
||||
|
@ -557,6 +563,7 @@ val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
|
|||
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
|
||||
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
|
||||
yxml.lo yxml.o: $(srcdir)/yxml/yxml.c $(srcdir)/yxml/yxml.h
|
||||
danessl.lo danessl.o: $(srcdir)/ssl_dane/danessl.c $(srcdir)/ssl_dane/danessl.h
|
||||
libev.lo libev.o: $(srcdir)/extension/libev.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef unsigned short in_port_t;
|
|||
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
|
@ -89,6 +90,9 @@ typedef unsigned short in_port_t;
|
|||
#include "list.h"
|
||||
#include "dict.h"
|
||||
#include "pubkey-pinning.h"
|
||||
#ifdef USE_DANESSL
|
||||
# include "ssl_dane/danessl.h"
|
||||
#endif
|
||||
|
||||
#define GETDNS_PORT_ZERO 0
|
||||
#define GETDNS_PORT_DNS 53
|
||||
|
@ -681,6 +685,27 @@ upstreams_create(getdns_context *context, size_t size)
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_DANESSL) && defined(STUB_DEBUG) && STUB_DEBUG
|
||||
static void _stub_debug_print_openssl_errors(void)
|
||||
{
|
||||
unsigned long err;
|
||||
char buffer[1024];
|
||||
const char *file;
|
||||
const char *data;
|
||||
int line;
|
||||
int flags;
|
||||
|
||||
while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
|
||||
ERR_error_string_n(err, buffer, sizeof(buffer));
|
||||
if (flags & ERR_TXT_STRING)
|
||||
DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d:%s\n", buffer, file, line, data);
|
||||
else
|
||||
DEBUG_STUB("DEBUG OpenSSL Error: %s:%s:%d\n", buffer, file, line);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
||||
{
|
||||
|
@ -722,6 +747,12 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
|||
|
||||
if (upstream->tls_obj != NULL) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
#ifdef USE_DANESSL
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
_stub_debug_print_openssl_errors();
|
||||
# endif
|
||||
DANESSL_cleanup(upstream->tls_obj);
|
||||
#endif
|
||||
SSL_free(upstream->tls_obj);
|
||||
}
|
||||
if (upstream->fd != -1)
|
||||
|
@ -832,6 +863,12 @@ _getdns_upstream_reset(getdns_upstream *upstream)
|
|||
}
|
||||
if (upstream->tls_obj != NULL) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
#ifdef USE_DANESSL
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
_stub_debug_print_openssl_errors();
|
||||
# endif
|
||||
DANESSL_cleanup(upstream->tls_obj);
|
||||
#endif
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
|
@ -1636,6 +1673,9 @@ getdns_context_create_with_extended_memory_functions(
|
|||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_library_init();
|
||||
# ifdef USE_DANESSL
|
||||
(void) DANESSL_library_init();
|
||||
# endif
|
||||
#else
|
||||
OPENSSL_init_crypto( OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
|
@ -3622,6 +3662,25 @@ _getdns_context_prepare_for_resolution(getdns_context *context)
|
|||
if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
# if defined(HAVE_SSL_CTX_DANE_ENABLE)
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
int osr =
|
||||
# else
|
||||
(void)
|
||||
# endif
|
||||
SSL_CTX_dane_enable(context->tls_ctx);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: SSL_CTX_dane_enable() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
# elif defined(USE_DANESSL)
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
int osr =
|
||||
# else
|
||||
(void)
|
||||
# endif
|
||||
DANESSL_CTX_init(context->tls_ctx);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_CTX_init() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
# endif
|
||||
#else /* HAVE_TLS_v1_2 */
|
||||
if (tls_only_is_in_transports_list(context) == 1)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit dd093e585a237e0321d303ec35e84c393ef739f4
|
257
src/stub.c
257
src/stub.c
|
@ -55,6 +55,9 @@
|
|||
#include "platform.h"
|
||||
#include "general.h"
|
||||
#include "pubkey-pinning.h"
|
||||
#ifdef USE_DANESSL
|
||||
# include "ssl_dane/danessl.h"
|
||||
#endif
|
||||
|
||||
/* WSA TODO:
|
||||
* STUB_TCP_RETRY added to deal with edge triggered event loops (versus
|
||||
|
@ -827,7 +830,37 @@ tls_requested(getdns_network_req *netreq)
|
|||
1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
#if defined(HAVE_SSL_DANE_ENABLE) || defined(USE_DANESSL)
|
||||
|
||||
static int
|
||||
_getdns_tls_verify_always_ok(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
char buf[8192];
|
||||
X509 *cert;
|
||||
int err;
|
||||
int depth;
|
||||
|
||||
cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
err = X509_STORE_CTX_get_error(ctx);
|
||||
depth = X509_STORE_CTX_get_error_depth(ctx);
|
||||
|
||||
if (cert)
|
||||
X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
|
||||
else
|
||||
strcpy(buf, "<unknown>");
|
||||
DEBUG_STUB("DEBUG Cert verify: depth=%d verify=%d err=%d subject=%s errorstr=%s\n", depth, ok, err, buf, X509_verify_cert_error_string(err));
|
||||
# else /* defined(STUB_DEBUG) && STUB_DEBUG */
|
||||
(void)ok;
|
||||
(void)ctx;
|
||||
# endif /* #else defined(STUB_DEBUG) && STUB_DEBUG */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* defined(HAVE_SSL_DANE_ENABLE) || defined(USE_DANESSL) */
|
||||
|
||||
static int
|
||||
tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
getdns_upstream *upstream;
|
||||
|
@ -837,36 +870,22 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
return 0;
|
||||
|
||||
int err = X509_STORE_CTX_get_error(ctx);
|
||||
#if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
DEBUG_STUB("%s %-35s: FD: %d Verify result: (%d) \"%s\"\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err,
|
||||
X509_verify_cert_error_string(err));
|
||||
#endif
|
||||
# endif
|
||||
if (!preverify_ok && !upstream->tls_fallback_ok)
|
||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||
"%-40s : Verify failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
|
||||
upstream->addr_str, err,
|
||||
X509_verify_cert_error_string(err));
|
||||
|
||||
/* First deal with the hostname authentication done by OpenSSL. */
|
||||
#ifdef X509_V_ERR_HOSTNAME_MISMATCH
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
/*Report if error is hostname mismatch*/
|
||||
if (err == X509_V_ERR_HOSTNAME_MISMATCH && upstream->tls_fallback_ok)
|
||||
DEBUG_STUB("%s %-35s: FD: %d WARNING: Proceeding even though hostname validation failed!\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
|
||||
# endif
|
||||
#else
|
||||
/* if we weren't built against OpenSSL with hostname matching we
|
||||
* could not have matched the hostname, so this would be an automatic
|
||||
* tls_auth_fail if there is a hostname provided*/
|
||||
if (upstream->tls_auth_name[0]) {
|
||||
upstream->tls_auth_state = GETDNS_AUTH_FAILED;
|
||||
preverify_ok = 0;
|
||||
}
|
||||
#endif
|
||||
/* No need to deal with hostname authentication, since this will be
|
||||
* dealt with in the DANE preprocessor paths.
|
||||
*/
|
||||
|
||||
/* Now deal with the pinset validation*/
|
||||
/* Deal with the pinset validation */
|
||||
if (upstream->tls_pubkey_pinset)
|
||||
pinset_ret = _getdns_verify_pinset_match(upstream->tls_pubkey_pinset, ctx);
|
||||
|
||||
|
@ -882,22 +901,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_ERR,
|
||||
"%-40s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
|
||||
upstream->addr_str);
|
||||
} else {
|
||||
/* If we _only_ had a pinset and it is good then force succesful
|
||||
authentication when the cert self-signed
|
||||
TODO: We need to check for other error cases here, not blindly accept the cert!! */
|
||||
if ((upstream->tls_pubkey_pinset && upstream->tls_auth_name[0] == '\0') &&
|
||||
(err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
|
||||
err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) {
|
||||
preverify_ok = 1;
|
||||
DEBUG_STUB("%s %-35s: FD: %d, Allowing self-signed (%d) cert since pins match\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err);
|
||||
_getdns_upstream_log(upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
||||
"%-40s : Verify passed : Transport=TLS - Allowing self-signed cert since pins match\n",
|
||||
upstream->addr_str);
|
||||
}
|
||||
}
|
||||
|
||||
/* If nothing has failed yet and we had credentials, we have succesfully authenticated*/
|
||||
if (preverify_ok == 0)
|
||||
upstream->tls_auth_state = GETDNS_AUTH_FAILED;
|
||||
|
@ -910,6 +914,8 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
|||
return (upstream->tls_fallback_ok) ? 1 : preverify_ok;
|
||||
}
|
||||
|
||||
#endif /* #else defined(HAVE_SSL_DANE_ENABLE) || defined(USE_DANESSL) */
|
||||
|
||||
static SSL*
|
||||
tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
||||
{
|
||||
|
@ -943,7 +949,10 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
|||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->tls_auth_name);
|
||||
SSL_set_tlsext_host_name(ssl, upstream->tls_auth_name);
|
||||
#ifdef HAVE_SSL_HN_AUTH
|
||||
/* Set up native OpenSSL hostname verification*/
|
||||
/* Set up native OpenSSL hostname verification
|
||||
* ( doesn't work with USE_DANESSL, but we verify the
|
||||
* name afterwards in such cases )
|
||||
*/
|
||||
X509_VERIFY_PARAM *param;
|
||||
param = SSL_get0_param(ssl);
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
|
@ -994,7 +1003,71 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
|||
DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS,
|
||||
__FUNC__);
|
||||
}
|
||||
#if defined(HAVE_SSL_DANE_ENABLE)
|
||||
int osr;
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
osr =
|
||||
# else
|
||||
(void)
|
||||
# endif
|
||||
SSL_dane_enable(ssl, *upstream->tls_auth_name ? upstream->tls_auth_name : NULL);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_enable(\"%s\") -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->tls_auth_name, osr);
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
|
||||
sha256_pin_t *pin_p;
|
||||
size_t n_pins = 0;
|
||||
for (pin_p = upstream->tls_pubkey_pinset; pin_p; pin_p = pin_p->next) {
|
||||
osr = SSL_dane_tlsa_add(ssl, 2, 1, 1,
|
||||
(unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_tlsa_add() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
if (osr > 0)
|
||||
++n_pins;
|
||||
osr = SSL_dane_tlsa_add(ssl, 3, 1, 1,
|
||||
(unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: SSL_dane_tlsa_add() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
if (osr > 0)
|
||||
++n_pins;
|
||||
}
|
||||
#elif defined(USE_DANESSL)
|
||||
if (upstream->tls_pubkey_pinset) {
|
||||
const char *auth_names[2] = { upstream->tls_auth_name, NULL };
|
||||
int osr;
|
||||
# if defined(STUB_DEBUG) && STUB_DEBUG
|
||||
osr =
|
||||
# else
|
||||
(void)
|
||||
# endif
|
||||
DANESSL_init(ssl,
|
||||
*upstream->tls_auth_name ? upstream->tls_auth_name : NULL,
|
||||
*upstream->tls_auth_name ? auth_names : NULL
|
||||
);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_init(\"%s\") -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->tls_auth_name, osr);
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
|
||||
sha256_pin_t *pin_p;
|
||||
size_t n_pins = 0;
|
||||
for (pin_p = upstream->tls_pubkey_pinset; pin_p; pin_p = pin_p->next) {
|
||||
osr = DANESSL_add_tlsa(ssl, 3, 1, "sha256",
|
||||
(unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_add_tlsa() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
if (osr > 0)
|
||||
++n_pins;
|
||||
osr = DANESSL_add_tlsa(ssl, 2, 1, "sha256",
|
||||
(unsigned char *)pin_p->pin, SHA256_DIGEST_LENGTH);
|
||||
DEBUG_STUB("%s %-35s: DEBUG: DANESSL_add_tlsa() -> %d\n"
|
||||
, STUB_DEBUG_SETUP_TLS, __FUNC__, osr);
|
||||
if (osr > 0)
|
||||
++n_pins;
|
||||
}
|
||||
} else {
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER, _getdns_tls_verify_always_ok);
|
||||
}
|
||||
#else
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_callback);
|
||||
#endif
|
||||
|
||||
SSL_set_connect_state(ssl);
|
||||
(void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
|
@ -1011,7 +1084,6 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
|
|||
__FUNC__);
|
||||
}
|
||||
}
|
||||
|
||||
return ssl;
|
||||
}
|
||||
|
||||
|
@ -1050,16 +1122,119 @@ tls_do_handshake(getdns_upstream *upstream)
|
|||
return STUB_SETUP_ERROR;
|
||||
}
|
||||
}
|
||||
upstream->tls_hs_state = GETDNS_HS_DONE;
|
||||
upstream->conn_state = GETDNS_CONN_OPEN;
|
||||
upstream->conn_completed++;
|
||||
/* A re-used session is not verified so need to fix up state in that case */
|
||||
if (SSL_session_reused(upstream->tls_obj))
|
||||
upstream->tls_auth_state = upstream->last_tls_auth_state;
|
||||
|
||||
#if defined(USE_DANESSL) || defined(HAVE_SSL_HN_AUTH)
|
||||
else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) {
|
||||
X509 *peer_cert = SSL_get_peer_certificate(upstream->tls_obj);
|
||||
long verify_result = SSL_get_verify_result(upstream->tls_obj);
|
||||
|
||||
/* In case of DANESSL use, and a tls_auth_name was given alongside a pinset,
|
||||
* we need to verify auth_name explicitely (otherwise it will not be checked,
|
||||
* because this is not required with DANE with an EE match).
|
||||
* This is not needed with native OpenSSL DANE, because EE name checks have
|
||||
* to be disabled explicitely.
|
||||
*/
|
||||
# if defined(USE_DANESSL) && defined(HAVE_SSL_HN_AUTH)
|
||||
if (peer_cert && verify_result == X509_V_OK
|
||||
&& upstream->tls_auth_name[0]
|
||||
&& upstream->tls_pubkey_pinset
|
||||
&& X509_check_host(peer_cert, upstream->tls_auth_name, 0,
|
||||
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL) <= 0)
|
||||
verify_result = X509_V_ERR_HOSTNAME_MISMATCH;
|
||||
# endif
|
||||
upstream->tls_auth_state = peer_cert && verify_result == X509_V_OK
|
||||
? GETDNS_AUTH_OK : GETDNS_AUTH_FAILED;
|
||||
if (!peer_cert)
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS,
|
||||
( upstream->tls_fallback_ok
|
||||
? GETDNS_LOG_INFO : GETDNS_LOG_ERR),
|
||||
"%-40s : Verify failed : Transport=TLS - %s - "
|
||||
"Remote did not offer certificate\n",
|
||||
upstream->addr_str,
|
||||
( upstream->tls_fallback_ok
|
||||
? "Tolerated because of Opportunistic profile"
|
||||
: "*Failure*" ));
|
||||
|
||||
/* Since we don't have DANE validation yet, DANE validation
|
||||
* failures are always pinset validation failures
|
||||
*/
|
||||
# if defined(HAVE_SSL_DANE_ENABLE)
|
||||
else if (verify_result == X509_V_ERR_DANE_NO_MATCH)
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS,
|
||||
( upstream->tls_fallback_ok
|
||||
? GETDNS_LOG_INFO : GETDNS_LOG_ERR),
|
||||
"%-40s : Verify failed : Transport=TLS - %s - "
|
||||
"Pinset validation failure\n", upstream->addr_str,
|
||||
( upstream->tls_fallback_ok
|
||||
? "Tolerated because of Opportunistic profile"
|
||||
: "*Failure*" ));
|
||||
# elif defined(USE_DANESSL)
|
||||
else if (verify_result == X509_V_ERR_CERT_UNTRUSTED
|
||||
&& upstream->tls_pubkey_pinset
|
||||
&& !DANESSL_get_match_cert(
|
||||
upstream->tls_obj, NULL, NULL, NULL))
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS,
|
||||
( upstream->tls_fallback_ok
|
||||
? GETDNS_LOG_INFO : GETDNS_LOG_ERR),
|
||||
"%-40s : Verify failed : Transport=TLS - %s - "
|
||||
"Pinset validation failure\n", upstream->addr_str,
|
||||
( upstream->tls_fallback_ok
|
||||
? "Tolerated because of Opportunistic profile"
|
||||
: "*Failure*" ));
|
||||
# endif
|
||||
else if (verify_result != X509_V_OK)
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS,
|
||||
( upstream->tls_fallback_ok
|
||||
? GETDNS_LOG_INFO : GETDNS_LOG_ERR),
|
||||
"%-40s : Verify failed : Transport=TLS - %s - "
|
||||
"(%d) \"%s\"\n", upstream->addr_str,
|
||||
( upstream->tls_fallback_ok
|
||||
? "Tolerated because of Opportunistic profile"
|
||||
: "*Failure*" ), verify_result,
|
||||
X509_verify_cert_error_string(verify_result));
|
||||
# ifndef HAVE_SSL_HN_AUTH
|
||||
else if (*upstream->tls_auth_name) {
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS,
|
||||
( upstream->tls_fallback_ok
|
||||
? GETDNS_LOG_INFO : GETDNS_LOG_ERR),
|
||||
"%-40s : Verify failed : Transport=TLS - %s - "
|
||||
"Hostname Authentication not available from TLS "
|
||||
"library (check library version)\n",
|
||||
upstream->addr_str,
|
||||
( upstream->tls_fallback_ok
|
||||
? "Tolerated because of Opportunistic profile"
|
||||
: "*Failure*" ));
|
||||
|
||||
upstream->tls_auth_state = GETDNS_AUTH_FAILED;
|
||||
}
|
||||
# endif
|
||||
else
|
||||
_getdns_upstream_log(upstream,
|
||||
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG,
|
||||
"%-40s : Verify passed : Transport=TLS\n",
|
||||
upstream->addr_str);
|
||||
|
||||
X509_free(peer_cert);
|
||||
if (upstream->tls_auth_state == GETDNS_AUTH_FAILED
|
||||
&& !upstream->tls_fallback_ok)
|
||||
return STUB_SETUP_ERROR;
|
||||
}
|
||||
#endif /* defined(USE_DANESSL) || defined(HAVE_SSL_HN_AUTH) */
|
||||
DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %s. Session is %s.\n",
|
||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd,
|
||||
_getdns_auth_str(upstream->tls_auth_state),
|
||||
SSL_session_reused(upstream->tls_obj) ?"re-used":"new");
|
||||
upstream->tls_hs_state = GETDNS_HS_DONE;
|
||||
upstream->conn_state = GETDNS_CONN_OPEN;
|
||||
upstream->conn_completed++;
|
||||
if (upstream->tls_session != NULL)
|
||||
SSL_SESSION_free(upstream->tls_session);
|
||||
upstream->tls_session = SSL_get1_session(upstream->tls_obj);
|
||||
|
|
|
@ -57,19 +57,7 @@ getdns_return_t getdns_yaml2dict(const char *, getdns_dict **dict);
|
|||
#define EXAMPLE_PIN "pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""
|
||||
|
||||
static int verbosity = 0;
|
||||
static int i_am_stubby = 0;
|
||||
static const char *default_stubby_config =
|
||||
"{ resolution_type: GETDNS_RESOLUTION_STUB"
|
||||
", dns_transport_list: [ GETDNS_TRANSPORT_TLS, GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP ]"
|
||||
", idle_timeout: 10000"
|
||||
", listen_addresses: [ 127.0.0.1@53, 0::1@53 ]"
|
||||
", tls_query_padding_blocksize: 1"
|
||||
", edns_client_subnet_private : 1"
|
||||
"}";
|
||||
static int clear_listen_list_on_arg = 0;
|
||||
#ifndef GETDNS_ON_WINDOWS
|
||||
static int run_in_foreground = 1;
|
||||
#endif
|
||||
static int quiet = 0;
|
||||
static int batch_mode = 0;
|
||||
static char *query_file = NULL;
|
||||
|
@ -95,6 +83,8 @@ static int check_dnssec = 0;
|
|||
static char *resolvconf = NULL;
|
||||
#endif
|
||||
static int print_api_info = 0, print_trust_anchors = 0;
|
||||
static int log_level = 0;
|
||||
static uint64_t log_systems = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
static int get_rrtype(const char *t)
|
||||
{
|
||||
|
@ -179,19 +169,14 @@ print_usage(FILE *out, const char *progname)
|
|||
{
|
||||
fprintf(out, "usage: %s [<option> ...] \\\n"
|
||||
"\t[@<upstream> ...] [+<extension> ...] [\'{ <settings> }\'] [<name>] [<type>]\n", progname);
|
||||
if (!i_am_stubby) {
|
||||
fprintf(out, "\ndefault mode: "
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
"recursive"
|
||||
# define DEFAULT_RESOLUTION_TYPE "recursive"
|
||||
#else
|
||||
"stub"
|
||||
# define DEFAULT_RESOLUTION_TYPE "stub"
|
||||
#endif
|
||||
", synchronous resolution of NS record\n\t\tusing UDP with TCP fallback\n");
|
||||
}
|
||||
else {
|
||||
fprintf(out, "\ndefault mode: "
|
||||
"stub, asynchronous resolution \n\t\tusing TLS with UDP then TCP fallback\n");
|
||||
}
|
||||
fprintf(out, "\ndefault mode: " DEFAULT_RESOLUTION_TYPE
|
||||
", synchronous resolution of NS record\n\t\tusing UDP with TCP fallback\n");
|
||||
fprintf(out, "\nupstreams: @<ip>[%%<scope_id>][@<port>][#<tls port>][~<tls name>][^<tsig spec>]");
|
||||
fprintf(out, "\n <ip>@<port> may be given as <IPv4>:<port>");
|
||||
fprintf(out, "\n or \'[\'<IPv6>[%%<scope_id>]\']\':<port> too\n");
|
||||
|
@ -216,12 +201,9 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t+0\t\t\tClear all extensions\n");
|
||||
fprintf(out, "\nsettings in json dict format (like outputted by -i option).\n");
|
||||
fprintf(out, "\noptions:\n");
|
||||
if (!i_am_stubby) {
|
||||
fprintf(out, "\t-a\tPerform asynchronous resolution "
|
||||
"(default = synchronous)\n");
|
||||
fprintf(out, "\t-A\taddress lookup (<type> is ignored)\n");
|
||||
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
||||
}
|
||||
fprintf(out, "\t-a\tPerform asynchronous resolution (default = synchronous)\n");
|
||||
fprintf(out, "\t-A\taddress lookup (<type> is ignored)\n");
|
||||
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
||||
fprintf(out, "\t-b <bufsize>\tSet edns0 max_udp_payload size\n");
|
||||
fprintf(out, "\t-c\tSend Client Subnet privacy request\n");
|
||||
fprintf(out, "\t-C\t<filename>\n");
|
||||
|
@ -229,28 +211,16 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t\tThe getdns context will be configured with these settings\n");
|
||||
fprintf(out, "\t\tThe file must be in YAML format (with extension of '.yml')\n");
|
||||
fprintf(out, "\t\tor JSON dict format (with extension '.conf')\n");
|
||||
if (i_am_stubby) {
|
||||
fprintf(out, "\t\tBy default, configuration is first read from");
|
||||
fprintf(out, "\n\t\t\"/etc/stubby.conf\" and then from \"$HOME/.stubby.conf\"\n");
|
||||
}
|
||||
fprintf(out, "\t-D\tSet edns0 do bit\n");
|
||||
fprintf(out, "\t-d\tclear edns0 do bit\n");
|
||||
fprintf(out, "\t-e <idle_timeout>\tSet idle timeout in milliseconds\n");
|
||||
if (!i_am_stubby)
|
||||
fprintf(out, "\t-F <filename>\tread the queries from the specified file\n");
|
||||
fprintf(out, "\t-F <filename>\tread the queries from the specified file\n");
|
||||
fprintf(out, "\t-f <filename>\tRead DNSSEC trust anchors from <filename>\n");
|
||||
#ifndef GETDNS_ON_WINDOWS
|
||||
if (i_am_stubby)
|
||||
fprintf(out, "\t-g\tRun stubby in background (default is foreground)\n");
|
||||
#endif
|
||||
if (!i_am_stubby) {
|
||||
fprintf(out, "\t-G\tgeneral lookup\n");
|
||||
fprintf(out, "\t-H\thostname lookup. (<name> must be an IP address; <type> is ignored)\n");
|
||||
}
|
||||
fprintf(out, "\t-G\tgeneral lookup\n");
|
||||
fprintf(out, "\t-H\thostname lookup. (<name> must be an IP address; <type> is ignored)\n");
|
||||
fprintf(out, "\t-h\tPrint this help\n");
|
||||
fprintf(out, "\t-i\tPrint api information\n");
|
||||
if (!i_am_stubby)
|
||||
fprintf(out, "\t-I\tInteractive mode (> 1 queries on same context)\n");
|
||||
fprintf(out, "\t-I\tInteractive mode (> 1 queries on same context)\n");
|
||||
fprintf(out, "\t-j\tOutput json response dict\n");
|
||||
fprintf(out, "\t-J\tPretty print json response dict\n");
|
||||
fprintf(out, "\t-k\tPrint root trust anchors\n");
|
||||
|
@ -266,19 +236,21 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n"
|
||||
"\t\t(special values: 0: no padding, 1: sensible default policy)\n");
|
||||
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
||||
fprintf( out, "\t-r\tSet recursing resolution type%s\n"
|
||||
, i_am_stubby ? "(default = stub)" : "");
|
||||
fprintf( out, "\t-r\tSet recursing resolution type (default = "
|
||||
DEFAULT_RESOLUTION_TYPE ")\n");
|
||||
fprintf(out, "\t-R <filename>\tRead root hints from <filename>\n");
|
||||
fprintf(out, "\t-s\tSet stub resolution type%s\n"
|
||||
, i_am_stubby ? "" : "(default = recursing)" );
|
||||
if (!i_am_stubby)
|
||||
fprintf(out, "\t-S\tservice lookup (<type> is ignored)\n");
|
||||
fprintf(out, "\t-s\tSet stub resolution type (default = "
|
||||
DEFAULT_RESOLUTION_TYPE ")\n");
|
||||
fprintf(out, "\t-S\tservice lookup (<type> is ignored)\n");
|
||||
fprintf(out, "\t-t <timeout>\tSet timeout in milliseconds\n");
|
||||
fprintf(out, "\t-v\tPrint getdns release version\n");
|
||||
fprintf(out, "\t-V\tIncrease verbosity (may be used more than once)\n");
|
||||
fprintf(out, "\t-x\tDo not follow redirects\n");
|
||||
fprintf(out, "\t-X\tFollow redirects (default)\n");
|
||||
|
||||
fprintf(out, "\t-y <log level>\tPrint log messages with"
|
||||
"severity <= <log level> (default = 0)\n");
|
||||
fprintf(out, "\t-Y <log systems>\tBitwise or'ed set of systems for "
|
||||
" which to print log messages (default == -1 (= all))\n");
|
||||
fprintf(out, "\t-0\tAppend suffix to single label first (default)\n");
|
||||
fprintf(out, "\t-W\tAppend suffix always\n");
|
||||
fprintf(out, "\t-1\tAppend suffix only to single label after failure\n");
|
||||
|
@ -298,8 +270,6 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t\tListen for DNS requests on the given IP address\n");
|
||||
fprintf(out, "\t\t<listen address> is in the same format as upstreams.\n");
|
||||
fprintf(out, "\t\tThis option can be given more than once.\n");
|
||||
if (i_am_stubby)
|
||||
fprintf(out, "\t\t(default is to listen on 127.0.0.1:53)\n");
|
||||
}
|
||||
|
||||
static getdns_return_t validate_chain(getdns_dict *response)
|
||||
|
@ -609,6 +579,7 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
getdns_bindata bindata;
|
||||
size_t upstream_count = 0;
|
||||
FILE *fh;
|
||||
int int_value;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = argv[i];
|
||||
|
@ -927,17 +898,49 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
getdns_context_set_follow_redirects(
|
||||
context, GETDNS_REDIRECTS_FOLLOW);
|
||||
break;
|
||||
case 'y':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
fprintf(stderr, "log level expected "
|
||||
"after -y\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
int_value = strtol(argv[i], &endptr, 10);
|
||||
if (*endptr || int_value < 0) {
|
||||
fprintf(stderr, "positive "
|
||||
"numeric log level expected "
|
||||
"after -y\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
} else
|
||||
log_level = int_value;
|
||||
goto next;
|
||||
|
||||
case 'Y':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
fprintf(stderr, "log systems expected "
|
||||
"after -y\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
int_value = strtol(argv[i], &endptr, 10);
|
||||
if (*endptr || int_value < 0) {
|
||||
fprintf(stderr, "positive "
|
||||
"numeric log systems expected "
|
||||
"after -Y\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
} else
|
||||
log_systems = (uint64_t)int_value;
|
||||
goto next;
|
||||
|
||||
case 'e':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
fprintf(stderr, "idle timeout expected "
|
||||
"after -t\n");
|
||||
"after -e\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
timeout = strtol(argv[i], &endptr, 10);
|
||||
if (*endptr || timeout < 0) {
|
||||
fprintf(stderr, "positive "
|
||||
"numeric idle timeout expected "
|
||||
"after -t\n");
|
||||
"after -e\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
getdns_context_set_idle_timeout(
|
||||
|
@ -1081,12 +1084,6 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
#ifndef GETDNS_ON_WINDOWS
|
||||
if (i_am_stubby && *c == 'g') {
|
||||
run_in_foreground = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
fprintf(stderr, "Unknown option "
|
||||
"\"%c\"\n", *c);
|
||||
for (i = 0; i < argc; i++)
|
||||
|
@ -1694,7 +1691,7 @@ answer_request:
|
|||
}
|
||||
}
|
||||
|
||||
static void stubby_log(void *userarg, uint64_t system,
|
||||
static void _getdns_query_log(void *userarg, uint64_t system,
|
||||
getdns_loglevel_type level, const char *fmt, va_list ap)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
@ -1703,16 +1700,10 @@ static void stubby_log(void *userarg, uint64_t system,
|
|||
#ifdef GETDNS_ON_WINDOWS
|
||||
time_t tsec;
|
||||
|
||||
if (!verbosity)
|
||||
return;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
tsec = (time_t) tv.tv_sec;
|
||||
gmtime_s(&tm, (const time_t *) &tsec);
|
||||
#else
|
||||
if (!verbosity)
|
||||
return;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
gmtime_r(&tv.tv_sec, &tm);
|
||||
#endif
|
||||
|
@ -1734,18 +1725,7 @@ static void stubby_log(void *userarg, uint64_t system,
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char home_stubby_conf_fn[1024];
|
||||
getdns_return_t r;
|
||||
#ifndef USE_WINSOCK
|
||||
char *prg_name = strrchr(argv[0], '/');
|
||||
#else
|
||||
char *prg_name = strrchr(argv[0], '\\');
|
||||
#endif
|
||||
prg_name = prg_name ? prg_name + 1 : argv[0];
|
||||
|
||||
i_am_stubby = strcasecmp(prg_name, "stubby") == 0
|
||||
|| strcasecmp(prg_name, "lt-stubby") == 0
|
||||
|| strcasecmp(prg_name, "stubby.exe") == 0;
|
||||
|
||||
name = the_root;
|
||||
if ((r = getdns_context_create(&context, 1))) {
|
||||
|
@ -1760,22 +1740,6 @@ main(int argc, char **argv)
|
|||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
goto done_destroy_context;
|
||||
}
|
||||
if (i_am_stubby) {
|
||||
int n_chars = snprintf( home_stubby_conf_fn
|
||||
, sizeof(home_stubby_conf_fn)
|
||||
, "%s/.stubby.conf"
|
||||
, getenv("HOME")
|
||||
);
|
||||
(void) parse_config(default_stubby_config, 0);
|
||||
(void) parse_config_file("/etc/stubby.conf", 0);
|
||||
if (n_chars > 0 && n_chars < (int)sizeof(home_stubby_conf_fn)){
|
||||
(void) parse_config_file(home_stubby_conf_fn, 0);
|
||||
}
|
||||
clear_listen_list_on_arg = 1;
|
||||
}
|
||||
(void) getdns_context_set_logfunc(context, NULL,
|
||||
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, stubby_log);
|
||||
|
||||
if ((r = parse_args(argc, argv)) && r != CONTINUE)
|
||||
goto done_destroy_context;
|
||||
#ifndef USE_WINSOCK
|
||||
|
@ -1788,6 +1752,9 @@ main(int argc, char **argv)
|
|||
goto done_destroy_context;
|
||||
}
|
||||
#endif
|
||||
(void) getdns_context_set_logfunc(context, NULL,
|
||||
log_systems, log_level, _getdns_query_log);
|
||||
|
||||
if (print_api_info) {
|
||||
getdns_dict *api_information =
|
||||
getdns_context_get_api_information(context);
|
||||
|
@ -1902,7 +1869,7 @@ done_destroy_context:
|
|||
else if (r == CONTINUE_ERROR)
|
||||
return 1;
|
||||
|
||||
if (!i_am_stubby && verbosity)
|
||||
if (verbosity)
|
||||
fprintf(stdout, "\nAll done.\n");
|
||||
|
||||
return r ? r
|
||||
|
|
Loading…
Reference in New Issue