dirmngr: Add option --standard-resolver.

* dirmngr/dirmngr.c (oStandardResolver): New constant.
(opts): New option --standard-resolver.
(parse_rereadable_options): Set option.
* dirmngr/dns-stuff.c: Refactor all code to support the new option.
(standard_resolver): New var.
(enable_standard_resolver, standard_resolver_p): New func.
* dirmngr/http.c (connect_server): Remove USE_DNS_SRV build
conditional.
* dirmngr/ks-engine-hkp.c (map_host): Ditto.
* dirmngr/server.c (cmd_getinfo) <dnsinfo>: Take care of new option
* configure.ac (HAVE_ADNS_IF_TORMODE): Remove var ADNSLIB.  ac_define
USE_ADNS in the adns checking code.  Remove options --disable-dns-srv
and --disable-dns-cert.  Always look for the system resolver.  Print
warning if no system resolver was found.
(USE_DNS_CERT, USE_DNS_SRV): Remove ac_defines.
(HAVE_SYSTEM_RESOLVER): New ac_define.
(USE_DNS_SRV): Remove am_conditional; not used anyway.
--

This option allows for runtime switching to the system's standard
resolver.  This is mainly useful to work around possible bugs in the
optional resolver libraries (as of now ADNS).  Note that on Windows
there is no code to use systems's resolver and thus for full
functionality dirmngr must be build with a separate resolver.

This patch also does way with configure options to disable the use of
CERT and SRV records.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-12-01 15:45:51 +01:00
parent 86efc3ee53
commit 304566d332
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
9 changed files with 483 additions and 391 deletions

View File

@ -103,6 +103,7 @@ have_sqlite=no
have_npth=no have_npth=no
have_libusb=no have_libusb=no
have_adns=no have_adns=no
have_system_resolver=no
gnupg_have_ldap="n/a" gnupg_have_ldap="n/a"
use_zip=yes use_zip=yes
@ -1025,41 +1026,22 @@ fi
CPPFLAGS=${_cppflags} CPPFLAGS=${_cppflags}
LDFLAGS=${_ldflags} LDFLAGS=${_ldflags}
if test "$have_adns" = "yes"; then if test "$have_adns" = "yes"; then
ADNSLIBS="-ladns" DNSLIBS="-ladns"
AC_DEFINE(USE_ADNS,1,[Use ADNS as resolver library.])
else
DNSLIBS=""
fi fi
# #
# Now try for the resolver functions so we can use DNS for SRV, PA and CERT. # Check standard resolver functions.
# #
AC_ARG_ENABLE(dns-srv, if test "$build_dirmngr" = "yes"; then
AC_HELP_STRING([--disable-dns-srv],
[disable the use of DNS SRV in HKP and HTTP]),
use_dns_srv=$enableval,use_dns_srv=yes)
AC_ARG_ENABLE(dns-cert,
AC_HELP_STRING([--disable-dns-cert],
[disable the use of CERT records in DNS]),
use_dns_cert=$enableval,use_dns_cert=yes)
if test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then
_dns_save_libs=$LIBS _dns_save_libs=$LIBS
LIBS="" LIBS=""
if test x"$have_adns" = xyes ; then # Find the system resolver which can always be enabled with
# We prefer ADNS. # the dirmngr option --standard-resolver.
DNSLIBS="$ADNSLIBS"
AC_DEFINE(USE_ADNS,1,[Use ADNS as resolver library.])
if test x"$use_dns_srv" = xyes ; then
AC_DEFINE(USE_DNS_SRV,1)
fi
if test x"$use_dns_cert" = xyes ; then
AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT])
fi
else
# With no ADNS find the system resolver.
# the double underscore thing is a glibc-ism? # the double underscore thing is a glibc-ism?
AC_SEARCH_LIBS(res_query,resolv bind,, AC_SEARCH_LIBS(res_query,resolv bind,,
@ -1116,23 +1098,18 @@ if test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then
fi fi
if test x"$have_resolver" = xyes ; then if test x"$have_resolver" = xyes ; then
DNSLIBS=$LIBS AC_DEFINE(HAVE_SYSTEM_RESOLVER,1,[The system's resolver is usable.])
DNSLIBS="$DNSLIBS $LIBS"
if test x"$use_dns_srv" = xyes ; then
AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV])
fi
if test x"$use_dns_cert" = xyes ; then
AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT])
fi
if test x"$need_compat" = xyes ; then if test x"$need_compat" = xyes ; then
AC_DEFINE(BIND_8_COMPAT,1,[an Apple OSXism]) AC_DEFINE(BIND_8_COMPAT,1,[an Apple OSXism])
fi fi
else else
use_dns_srv=no AC_MSG_WARN([[
use_dns_cert=no ***
fi *** The system's DNS resolver is not usable.
*** Dirmngr functionality is limited.
***]])
show_tor_support="${show_tor_support} (no system resolver)"
fi fi
LIBS=$_dns_save_libs LIBS=$_dns_save_libs
@ -1140,8 +1117,6 @@ fi
AC_SUBST(DNSLIBS) AC_SUBST(DNSLIBS)
AM_CONDITIONAL(USE_DNS_SRV, test x"$use_dns_srv" = xyes)
# #
# Check for LDAP # Check for LDAP
@ -1963,7 +1938,6 @@ echo "
Dirmngr auto start: $dirmngr_auto_start Dirmngr auto start: $dirmngr_auto_start
Readline support: $gnupg_cv_have_readline Readline support: $gnupg_cv_have_readline
LDAP support: $gnupg_have_ldap LDAP support: $gnupg_have_ldap
DNS SRV support: $use_dns_srv
TLS support: $use_tls_library TLS support: $use_tls_library
TOFU support: $use_tofu TOFU support: $use_tofu
Tor support: $show_tor_support Tor support: $show_tor_support

View File

@ -140,6 +140,7 @@ enum cmd_and_opt_values {
oKeyServer, oKeyServer,
oNameServer, oNameServer,
oDisableCheckOwnSocket, oDisableCheckOwnSocket,
oStandardResolver,
aTest aTest
}; };
@ -236,6 +237,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"), ARGPARSE_s_s (oHTTPWrapperProgram, "http-wrapper-program", "@"),
ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"), ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", "@"),
ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"), ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
ARGPARSE_s_n (oStandardResolver, "standard-resolver", "@"),
ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing " ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
"of all commands and options)\n")), "of all commands and options)\n")),
@ -543,6 +545,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
FREE_STRLIST (opt.keyserver); FREE_STRLIST (opt.keyserver);
/* Note: We do not allow resetting of opt.use_tor at runtime. */ /* Note: We do not allow resetting of opt.use_tor at runtime. */
disable_check_own_socket = 0; disable_check_own_socket = 0;
enable_standard_resolver (0);
return 1; return 1;
} }
@ -617,6 +620,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oUseTor: opt.use_tor = 1; break; case oUseTor: opt.use_tor = 1; break;
case oStandardResolver: enable_standard_resolver (1); break;
case oKeyServer: case oKeyServer:
if (*pargs->r.ret_str) if (*pargs->r.ret_str)
add_to_strlist (&opt.keyserver, pargs->r.ret_str); add_to_strlist (&opt.keyserver, pargs->r.ret_str);

View File

@ -1,6 +1,6 @@
/* dns-stuff.c - DNS related code including CERT RR (rfc-4398) /* dns-stuff.c - DNS related code including CERT RR (rfc-4398)
* Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc. * Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
* Copyright (C) 2005, 2006, 2009, 2015 Werner Koch * Copyright (C) 2005, 2006, 2009, 2015. 2016 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -36,9 +36,11 @@
# endif # endif
# include <windows.h> # include <windows.h>
#else #else
# if HAVE_SYSTEM_RESOLVER
# include <netinet/in.h> # include <netinet/in.h>
# include <arpa/nameser.h> # include <arpa/nameser.h>
# include <resolv.h> # include <resolv.h>
# endif
# include <netdb.h> # include <netdb.h>
#endif #endif
#include <string.h> #include <string.h>
@ -101,6 +103,8 @@
/* The default nameserver used with ADNS in Tor mode. */ /* The default nameserver used with ADNS in Tor mode. */
#define DEFAULT_NAMESERVER "8.8.8.8" #define DEFAULT_NAMESERVER "8.8.8.8"
/* If set force the use of the standard resolver. */
static int standard_resolver;
/* If set Tor mode shall be used. */ /* If set Tor mode shall be used. */
static int tor_mode; static int tor_mode;
@ -114,6 +118,25 @@ static char tor_nameserver[40+20];
static char tor_credentials[50]; static char tor_credentials[50];
#endif #endif
/* Calling this function with YES set to True forces the use of the
* standard resolver even if dirmngr has been built with support for
* an alternative resolver. */
void
enable_standard_resolver (int yes)
{
standard_resolver = yes;
}
/* Return true if the standard resolver is used. */
int
standard_resolver_p (void)
{
return standard_resolver;
}
/* Sets the module in Tor mode. Returns 0 is this is possible or an /* Sets the module in Tor mode. Returns 0 is this is possible or an
error code. */ error code. */
gpg_error_t gpg_error_t
@ -121,7 +144,7 @@ enable_dns_tormode (int new_circuit)
{ {
(void) new_circuit; (void) new_circuit;
#if defined(USE_DNS_CERT) && defined(USE_ADNS) #ifdef USE_ADNS
# if HAVE_ADNS_IF_TORMODE # if HAVE_ADNS_IF_TORMODE
if (!*tor_credentials || new_circuit) if (!*tor_credentials || new_circuit)
{ {
@ -367,7 +390,6 @@ resolve_name_adns (const char *name, unsigned short port,
#endif /*USE_ADNS*/ #endif /*USE_ADNS*/
#ifndef USE_ADNS
/* Resolve a name using the standard system function. */ /* Resolve a name using the standard system function. */
static gpg_error_t static gpg_error_t
resolve_name_standard (const char *name, unsigned short port, resolve_name_standard (const char *name, unsigned short port,
@ -472,7 +494,6 @@ resolve_name_standard (const char *name, unsigned short port,
*r_dai = daihead; *r_dai = daihead;
return err; return err;
} }
#endif /*!USE_ADNS*/
/* Resolve an address using the standard system function. */ /* Resolve an address using the standard system function. */
@ -552,12 +573,12 @@ resolve_dns_name (const char *name, unsigned short port,
dns_addrinfo_t *r_ai, char **r_canonname) dns_addrinfo_t *r_ai, char **r_canonname)
{ {
#ifdef USE_ADNS #ifdef USE_ADNS
if (!standard_resolver)
return resolve_name_adns (name, port, want_family, want_socktype, return resolve_name_adns (name, port, want_family, want_socktype,
r_ai, r_canonname); r_ai, r_canonname);
#else #endif
return resolve_name_standard (name, port, want_family, want_socktype, return resolve_name_standard (name, port, want_family, want_socktype,
r_ai, r_canonname); r_ai, r_canonname);
#endif
} }
@ -565,11 +586,7 @@ gpg_error_t
resolve_dns_addr (const struct sockaddr *addr, int addrlen, resolve_dns_addr (const struct sockaddr *addr, int addrlen,
unsigned int flags, char **r_name) unsigned int flags, char **r_name)
{ {
#ifdef USE_ADNS_disabled_for_now
return resolve_addr_adns (addr, addrlen, flags, r_name);
#else
return resolve_addr_standard (addr, addrlen, flags, r_name); return resolve_addr_standard (addr, addrlen, flags, r_name);
#endif
} }
@ -654,23 +671,13 @@ is_onion_address (const char *name)
} }
/* Returns 0 on success or an error code. If a PGP CERT record was #ifdef USE_ADNS
found, the malloced data is returned at (R_KEY, R_KEYLEN) and /* ADNS version of get_dns_cert. */
the other return parameters are set to NULL/0. If an IPGP CERT static gpg_error_t
record was found the fingerprint is stored as an allocated block at get_dns_cert_adns (const char *name, int want_certtype,
R_FPR and its length at R_FPRLEN; an URL is is allocated as a
string and returned at R_URL. If WANT_CERTTYPE is 0 this function
returns the first CERT found with a supported type; it is expected
that only one CERT record is used. If WANT_CERTTYPE is one of the
supported certtypes only records with this certtype are considered
and the first found is returned. (R_KEY,R_KEYLEN) are optional. */
gpg_error_t
get_dns_cert (const char *name, int want_certtype,
void **r_key, size_t *r_keylen, void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen, char **r_url) unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
{ {
#ifdef USE_DNS_CERT
#ifdef USE_ADNS
gpg_error_t err; gpg_error_t err;
int ret; int ret;
adns_state state; adns_state state;
@ -678,14 +685,6 @@ get_dns_cert (const char *name, int want_certtype,
unsigned int ctype; unsigned int ctype;
int count; int count;
if (r_key)
*r_key = NULL;
if (r_keylen)
*r_keylen = 0;
*r_fpr = NULL;
*r_fprlen = 0;
*r_url = NULL;
err = my_adns_init (&state); err = my_adns_init (&state);
if (err) if (err)
return err; return err;
@ -812,22 +811,22 @@ get_dns_cert (const char *name, int want_certtype,
adns_free (answer); adns_free (answer);
adns_finish (state); adns_finish (state);
return err; return err;
}
#endif /*!USE_ADNS */
#else /*!USE_ADNS*/
/* Standard resolver version of get_dns_cert. */
static gpg_error_t
get_dns_cert_standard (const char *name, int want_certtype,
void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
{
#ifdef HAVE_SYSTEM_RESOLVER
gpg_error_t err; gpg_error_t err;
unsigned char *answer; unsigned char *answer;
int r; int r;
u16 count; u16 count;
if (r_key)
*r_key = NULL;
if (r_keylen)
*r_keylen = 0;
*r_fpr = NULL;
*r_fprlen = 0;
*r_url = NULL;
/* Allocate a 64k buffer which is the limit for an DNS response. */ /* Allocate a 64k buffer which is the limit for an DNS response. */
answer = xtrymalloc (65536); answer = xtrymalloc (65536);
if (!answer) if (!answer)
@ -1004,9 +1003,36 @@ get_dns_cert (const char *name, int want_certtype,
xfree (answer); xfree (answer);
return err; return err;
#endif /*!USE_ADNS */ #else /*!HAVE_SYSTEM_RESOLVER*/
#else /* !USE_DNS_CERT */
(void)name; (void)name;
(void)want_certtype;
(void)r_key;
(void)r_keylen;
(void)r_fpr;
(void)r_fprlen;
(void)r_url;
return gpg_error (GPG_ERR_NOT_SUPPORTED);
#endif /*!HAVE_SYSTEM_RESOLVER*/
}
/* Returns 0 on success or an error code. If a PGP CERT record was
found, the malloced data is returned at (R_KEY, R_KEYLEN) and
the other return parameters are set to NULL/0. If an IPGP CERT
record was found the fingerprint is stored as an allocated block at
R_FPR and its length at R_FPRLEN; an URL is is allocated as a
string and returned at R_URL. If WANT_CERTTYPE is 0 this function
returns the first CERT found with a supported type; it is expected
that only one CERT record is used. If WANT_CERTTYPE is one of the
supported certtypes only records with this certtype are considered
and the first found is returned. (R_KEY,R_KEYLEN) are optional. */
gpg_error_t
get_dns_cert (const char *name, int want_certtype,
void **r_key, size_t *r_keylen,
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
{
if (r_key) if (r_key)
*r_key = NULL; *r_key = NULL;
if (r_keylen) if (r_keylen)
@ -1015,11 +1041,16 @@ get_dns_cert (const char *name, int want_certtype,
*r_fprlen = 0; *r_fprlen = 0;
*r_url = NULL; *r_url = NULL;
return gpg_error (GPG_ERR_NOT_SUPPORTED); #ifdef USE_ADNS
#endif if (!standard_resolver)
return get_dns_cert_adns (name, want_certtype, r_key, r_keylen,
r_fpr, r_fprlen, r_url);
#endif /*!USE_ADNS */
return get_dns_cert_standard (name, want_certtype, r_key, r_keylen,
r_fpr, r_fprlen, r_url);
} }
#ifdef USE_DNS_SRV
static int static int
priosort(const void *a,const void *b) priosort(const void *a,const void *b)
{ {
@ -1033,17 +1064,14 @@ priosort(const void *a,const void *b)
} }
int
getsrv (const char *name,struct srventry **list)
{
int srvcount=0;
u16 count;
int i, rc;
*list = NULL;
#ifdef USE_ADNS #ifdef USE_ADNS
{ /* ADNS based helper for getsrv. */
static int
getsrv_adns (const char *name, struct srventry **list)
{
int srvcount = 0;
u16 count;
int rc;
adns_state state; adns_state state;
adns_answer *answer = NULL; adns_answer *answer = NULL;
@ -1084,7 +1112,11 @@ getsrv (const char *name,struct srventry **list)
newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry)); newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
if (!newlist) if (!newlist)
goto fail; {
xfree (*list);
*list = NULL;
return -1;
}
*list = newlist; *list = newlist;
memset (&(*list)[srvcount], 0, sizeof(struct srventry)); memset (&(*list)[srvcount], 0, sizeof(struct srventry));
srv = &(*list)[srvcount]; srv = &(*list)[srvcount];
@ -1098,9 +1130,17 @@ getsrv (const char *name,struct srventry **list)
adns_free (answer); adns_free (answer);
adns_finish (state); adns_finish (state);
}
#else /*!USE_ADNS*/ return srvcount;
{ }
#endif /*USE_ADNS*/
/* Standard resolver based helper for getsrv. */
static int
getsrv_standard (const char *name, struct srventry **list)
{
#ifdef HAVE_SYSTEM_RESOLVER
union { union {
unsigned char ans[2048]; unsigned char ans[2048];
HEADER header[1]; HEADER header[1];
@ -1108,8 +1148,10 @@ getsrv (const char *name,struct srventry **list)
unsigned char *answer = res.ans; unsigned char *answer = res.ans;
HEADER *header = res.header; HEADER *header = res.header;
unsigned char *pt, *emsg; unsigned char *pt, *emsg;
int r; int r, rc;
u16 dlen; u16 dlen;
int srvcount=0;
u16 count;
/* Do not allow a query using the standard resolver in Tor mode. */ /* Do not allow a query using the standard resolver in Tor mode. */
if (tor_mode) if (tor_mode)
@ -1134,37 +1176,37 @@ getsrv (const char *name,struct srventry **list)
while (count-- > 0 && pt < emsg) while (count-- > 0 && pt < emsg)
{ {
struct srventry *srv=NULL; struct srventry *srv = NULL;
u16 type,class; u16 type, class;
struct srventry *newlist; struct srventry *newlist;
newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry)); newlist = xtryrealloc (*list, (srvcount+1)*sizeof(struct srventry));
if (!newlist) if (!newlist)
goto fail; goto fail;
*list = newlist; *list = newlist;
memset(&(*list)[srvcount],0,sizeof(struct srventry)); memset (&(*list)[srvcount], 0, sizeof(struct srventry));
srv=&(*list)[srvcount]; srv = &(*list)[srvcount];
srvcount++; srvcount++;
rc = dn_skipname(pt,emsg); /* the name we just queried for */ rc = dn_skipname (pt, emsg); /* The name we just queried for. */
if (rc == -1) if (rc == -1)
goto fail; goto fail;
pt+=rc; pt += rc;
/* Truncated message? */ /* Truncated message? */
if((emsg-pt)<16) if ((emsg-pt) < 16)
goto fail; goto fail;
type = buf16_to_u16 (pt); type = buf16_to_u16 (pt);
pt += 2; pt += 2;
/* We asked for SRV and got something else !? */ /* We asked for SRV and got something else !? */
if(type!=T_SRV) if (type != T_SRV)
goto fail; goto fail;
class = buf16_to_u16 (pt); class = buf16_to_u16 (pt);
pt += 2; pt += 2;
/* We asked for IN and got something else !? */ /* We asked for IN and got something else !? */
if(class!=C_IN) if (class != C_IN)
goto fail; goto fail;
pt += 4; /* ttl */ pt += 4; /* ttl */
@ -1179,9 +1221,8 @@ getsrv (const char *name,struct srventry **list)
pt += 2; pt += 2;
/* Get the name. 2782 doesn't allow name compression, but /* Get the name. 2782 doesn't allow name compression, but
dn_expand still works to pull the name out of the * dn_expand still works to pull the name out of the packet. */
packet. */ rc = dn_expand (answer, emsg, pt, srv->target, sizeof srv->target);
rc = dn_expand(answer,emsg,pt,srv->target, sizeof srv->target);
if (rc == 1 && srv->target[0] == 0) /* "." */ if (rc == 1 && srv->target[0] == 0) /* "." */
{ {
xfree(*list); xfree(*list);
@ -1195,8 +1236,43 @@ getsrv (const char *name,struct srventry **list)
if (dlen != rc+6) if (dlen != rc+6)
goto fail; goto fail;
} }
}
return srvcount;
fail:
xfree (*list);
*list = NULL;
return -1;
#else /*!HAVE_SYSTEM_RESOLVER*/
(void)name;
(void)list;
return -1;
#endif /*!HAVE_SYSTEM_RESOLVER*/
}
int
getsrv (const char *name, struct srventry **list)
{
int srvcount;
int i;
*list = NULL;
if (0)
;
#ifdef USE_ADNS
else if (!standard_resolver)
srvcount = getsrv_adns (name, list);
#endif /*!USE_ADNS*/ #endif /*!USE_ADNS*/
else
srvcount = getsrv_standard (name, list);
if (srvcount <= 0)
return srvcount;
/* Now we have an array of all the srv records. */ /* Now we have an array of all the srv records. */
@ -1272,25 +1348,16 @@ getsrv (const char *name,struct srventry **list)
} }
return srvcount; return srvcount;
fail:
xfree(*list);
*list=NULL;
return -1;
} }
#endif /*USE_DNS_SRV*/
#ifdef USE_ADNS
/* ADNS version of get_dns_cname. */
gpg_error_t gpg_error_t
get_dns_cname (const char *name, char **r_cname) get_dns_cname_adns (const char *name, char **r_cname)
{ {
gpg_error_t err; gpg_error_t err;
int rc; int rc;
*r_cname = NULL;
#ifdef USE_ADNS
{
adns_state state; adns_state state;
adns_answer *answer = NULL; adns_answer *answer = NULL;
@ -1328,9 +1395,17 @@ get_dns_cname (const char *name, char **r_cname)
adns_free (answer); adns_free (answer);
adns_finish (state); adns_finish (state);
return err; return err;
} }
#else /*!USE_ADNS*/ #endif /*USE_ADNS*/
{
/* Standard resolver version of get_dns_cname. */
gpg_error_t
get_dns_cname_standard (const char *name, char **r_cname)
{
#ifdef HAVE_SYSTEM_RESOLVER
gpg_error_t err;
int rc;
union { union {
unsigned char ans[2048]; unsigned char ans[2048];
HEADER header[1]; HEADER header[1];
@ -1391,6 +1466,26 @@ get_dns_cname (const char *name, char **r_cname)
return err; return err;
} }
return 0; return 0;
}
#endif /*!USE_ADNS*/ #else /*!HAVE_SYSTEM_RESOLVER*/
(void)name;
(void)r_cname;
return -1;
#endif /*!HAVE_SYSTEM_RESOLVER*/
}
gpg_error_t
get_dns_cname (const char *name, char **r_cname)
{
*r_cname = NULL;
#ifdef USE_ADNS
if (!standard_resolver)
return get_dns_cname_adns (name, r_cname);
#endif /*!USE_ADNS*/
return get_dns_cname_standard (name, r_cname);
} }

View File

@ -92,6 +92,14 @@ struct srventry
}; };
/* Calling this function with YES set to True forces the use of the
* standard resolver even if dirmngr has been built with support for
* an alternative resolver. */
void enable_standard_resolver (int yes);
/* Return true if the standard resolver is used. */
int standard_resolver_p (void);
/* Calling this function switches the DNS code into Tor mode if /* Calling this function switches the DNS code into Tor mode if
possibe. Return 0 on success. */ possibe. Return 0 on success. */
gpg_error_t enable_dns_tormode (int new_circuit); gpg_error_t enable_dns_tormode (int new_circuit);

View File

@ -2323,7 +2323,6 @@ connect_server (const char *server, unsigned short port,
#endif /*!HASSUAN_SOCK_TOR*/ #endif /*!HASSUAN_SOCK_TOR*/
} }
#ifdef USE_DNS_SRV
/* Do the SRV thing */ /* Do the SRV thing */
if (srvtag) if (srvtag)
{ {
@ -2347,10 +2346,6 @@ connect_server (const char *server, unsigned short port,
} }
} }
} }
#else
(void)flags;
(void)srvtag;
#endif /*USE_DNS_SRV*/
if (!serverlist) if (!serverlist)
{ {

View File

@ -426,11 +426,9 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
int refidx; int refidx;
int is_pool = 0; int is_pool = 0;
char *cname; char *cname;
#ifdef USE_DNS_SRV
char *srvrecord; char *srvrecord;
struct srventry *srvs; struct srventry *srvs;
int srvscount; int srvscount;
#endif /* USE_DNS_SRV */
reftblsize = 100; reftblsize = 100;
reftbl = xtrymalloc (reftblsize * sizeof *reftbl); reftbl = xtrymalloc (reftblsize * sizeof *reftbl);
@ -447,7 +445,6 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
} }
hi = hosttable[idx]; hi = hosttable[idx];
#ifdef USE_DNS_SRV
if (!is_ip_address (name)) if (!is_ip_address (name))
{ {
/* Check for SRV records. */ /* Check for SRV records. */
@ -488,7 +485,6 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
xfree (srvs); xfree (srvs);
} }
} }
#endif /* USE_DNS_SRV */
/* Find all A records for this entry and put them into the pool /* Find all A records for this entry and put them into the pool
list - if any. */ list - if any. */

View File

@ -2309,13 +2309,19 @@ cmd_getinfo (assuan_context_t ctx, char *line)
} }
else if (!strcmp (line, "dnsinfo")) else if (!strcmp (line, "dnsinfo"))
{ {
if (standard_resolver_p ())
assuan_set_okay_line
(ctx, "- Forced use of System resolver (w/o Tor support)");
else
{
#if USE_ADNS && HAVE_ADNS_IF_TORMODE #if USE_ADNS && HAVE_ADNS_IF_TORMODE
assuan_set_okay_line (ctx, "- ADNS with Tor support"); assuan_set_okay_line (ctx, "- ADNS with Tor support");
#elif USE_ADNS #elif USE_ADNS
assuan_set_okay_line (ctx, "- ADNS w/o Tor support"); assuan_set_okay_line (ctx, "- ADNS w/o Tor support");
#else #else
assuan_set_okay_line (ctx, "- System resolver w/o Tor support"); assuan_set_okay_line (ctx, "- System resolver (w/o Tor support)");
#endif #endif
}
err = 0; err = 0;
} }
else else

View File

@ -66,6 +66,7 @@ main (int argc, char **argv)
"Options:\n" "Options:\n"
" --verbose print timings etc.\n" " --verbose print timings etc.\n"
" --debug flyswatter\n" " --debug flyswatter\n"
" --standard-resolver use the system's resolver\n"
" --use-tor use Tor\n" " --use-tor use Tor\n"
" --new-circuit use a new Tor circuit\n" " --new-circuit use a new Tor circuit\n"
" --bracket enclose v6 addresses in brackets\n" " --bracket enclose v6 addresses in brackets\n"
@ -96,6 +97,11 @@ main (int argc, char **argv)
opt_new_circuit = 1; opt_new_circuit = 1;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--standard-resolver"))
{
enable_standard_resolver (1);
argc--; argv++;
}
else if (!strcmp (*argv, "--bracket")) else if (!strcmp (*argv, "--bracket"))
{ {
opt_bracket = 1; opt_bracket = 1;

View File

@ -244,6 +244,13 @@ this still leaks the DNS queries; e.g. to lookup the hosts in a
keyserver pool. Certain other features are disabled if this mode is keyserver pool. Certain other features are disabled if this mode is
active. active.
@item --standard-resolver
@opindex standard-resolver
This option forces the use of the system's standard DNS resolver code.
This is mainly used for debugging. Note that on Windows a standard
resolver is not used and all DNS access will return the error ``Not
Implemented'' if this function is used.
@item --allow-version-check @item --allow-version-check
@opindex allow-version-check @opindex allow-version-check
Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get Allow Dirmngr to connect to @code{https://versions.gnupg.org} to get