From 58ebe50bdf4837e9ab2d3f8c6e5fcf28c66f26e9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Oct 2015 19:03:26 +0200 Subject: [PATCH] dirmngr: Prefer ADNS over system resolver. * configure.ac (HAVE_ADNS_IF_TORMODE): New ac_define. (USE_DNS_CERT): Prefer ADNS over the system resolver. * dirmngr/dns-cert.c (tor_mode): New global var. (enable_dns_tormode): New func. (get_dns_cert): Use DNS resolver at 8.8.8.8 in tor-mode. * dirmngr/server.c (cmd_dns_cert): If supported allow DNS requests. --- configure.ac | 112 +++++++++++++++++++++++++-------------------- dirmngr/dns-cert.c | 19 +++++++- dirmngr/dns-cert.h | 1 + dirmngr/server.c | 3 +- 4 files changed, 83 insertions(+), 52 deletions(-) diff --git a/configure.ac b/configure.ac index 3ec989534..bdfff8846 100644 --- a/configure.ac +++ b/configure.ac @@ -948,6 +948,16 @@ if test "$with_adns" != "no"; then [have_adns=yes], [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]), [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]) + + AC_MSG_CHECKING([if adns supports adns_if_tormode]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + adns_initflags flags = adns_if_tormode; + ]],[])],[adns_if_tormode=yes],[adns_if_tormode=no]) + AC_MSG_RESULT($adns_if_tormode) + if test x"$adns_if_tormode" = xyes; then + AC_DEFINE(HAVE_ADNS_IF_TORMODE,1,[define if adns_if_tormode is available]) + fi fi if test "$have_adns" = "yes"; then ADNSLIBS="-ladns" @@ -970,24 +980,40 @@ AC_ARG_ENABLE(dns-cert, if test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then _dns_save_libs=$LIBS LIBS="" - # the double underscore thing is a glibc-ism? - AC_SEARCH_LIBS(res_query,resolv bind,, - AC_SEARCH_LIBS(__res_query,resolv bind,,have_resolver=no)) - AC_SEARCH_LIBS(dn_expand,resolv bind,, - AC_SEARCH_LIBS(__dn_expand,resolv bind,,have_resolver=no)) - AC_SEARCH_LIBS(dn_skipname,resolv bind,, - AC_SEARCH_LIBS(__dn_skipname,resolv bind,,have_resolver=no)) - if test x"$have_resolver" != xno ; then + if test x"$have_adns" = xyes ; then + # We prefer ADNS. + DNSLIBS="$ADNSLIBS" + AC_DEFINE(USE_ADNS,1,[Use ADNS as resolver library.]) - # Make sure that the BIND 4 resolver interface is workable before - # enabling any code that calls it. At some point I'll rewrite the - # code to use the BIND 8 resolver API. - # We might also want to use adns instead. Problem with ADNS is that - # it does not support v6. + if test x"$use_dns_srv" = xyes ; then + AC_DEFINE(USE_DNS_SRV,1) + fi - AC_MSG_CHECKING([whether the resolver is usable]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include + 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? + AC_SEARCH_LIBS(res_query,resolv bind,, + AC_SEARCH_LIBS(__res_query,resolv bind,,have_resolver=no)) + AC_SEARCH_LIBS(dn_expand,resolv bind,, + AC_SEARCH_LIBS(__dn_expand,resolv bind,,have_resolver=no)) + AC_SEARCH_LIBS(dn_skipname,resolv bind,, + AC_SEARCH_LIBS(__dn_skipname,resolv bind,,have_resolver=no)) + + if test x"$have_resolver" != xno ; then + + # Make sure that the BIND 4 resolver interface is workable before + # enabling any code that calls it. At some point I'll rewrite the + # code to use the BIND 8 resolver API. + # We might also want to use adns instead. Problem with ADNS is that + # it does not support v6. + + AC_MSG_CHECKING([whether the resolver is usable]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include #include #include ]], @@ -996,15 +1022,15 @@ if test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then dn_skipname(0,0); dn_expand(0,0,0,0,0); ]])],have_resolver=yes,have_resolver=no) - AC_MSG_RESULT($have_resolver) + AC_MSG_RESULT($have_resolver) - # This is Apple-specific and somewhat bizarre as they changed the - # define in bind 8 for some reason. + # This is Apple-specific and somewhat bizarre as they changed the + # define in bind 8 for some reason. - if test x"$have_resolver" != xyes ; then - AC_MSG_CHECKING( + if test x"$have_resolver" != xyes ; then + AC_MSG_CHECKING( [whether I can make the resolver usable with BIND_8_COMPAT]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define BIND_8_COMPAT + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define BIND_8_COMPAT #include #include #include @@ -1013,42 +1039,28 @@ if test x"$use_dns_srv" = xyes || test x"$use_dns_cert" = xyes; then res_query("foo.bar",C_IN,T_A,answer,PACKETSZ); dn_skipname(0,0); dn_expand(0,0,0,0,0); ]])],[have_resolver=yes ; need_compat=yes]) - AC_MSG_RESULT($have_resolver) + AC_MSG_RESULT($have_resolver) + fi fi - fi - if test x"$have_resolver" = xyes ; then - DNSLIBS=$LIBS + if test x"$have_resolver" = xyes ; then + 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_srv" = xyes ; then + AC_DEFINE(USE_DNS_SRV,1,[define to use DNS SRV]) + fi - if test x"$use_dns_cert" = xyes ; then + if test x"$use_dns_cert" = xyes ; then AC_DEFINE(USE_DNS_CERT,1,[define to use DNS CERT]) - fi + fi - if test x"$need_compat" = xyes ; then + if test x"$need_compat" = xyes ; then AC_DEFINE(BIND_8_COMPAT,1,[an Apple OSXism]) - fi - else - # If we have no resolver library but ADNS (e.g. under W32) enable the - # code parts which can be used with ADNS. - if test x"$have_adns" = xyes ; then - 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 - use_dns_srv=no - use_dns_cert=no - fi + fi + else + use_dns_srv=no + use_dns_cert=no + fi fi LIBS=$_dns_save_libs diff --git a/dirmngr/dns-cert.c b/dirmngr/dns-cert.c index 3845a4b25..712dfc017 100644 --- a/dirmngr/dns-cert.c +++ b/dirmngr/dns-cert.c @@ -59,7 +59,22 @@ /* ADNS has no support for CERT yet. */ #define my_adns_r_cert 37 +/* If set Tor mode shall be used. */ +static int tor_mode; +/* Sets the module in TOR mode. Returns 0 is this is possible or an + error code. */ +gpg_error_t +enable_dns_tormode (void) +{ +#if defined(USE_DNS_CERT) && defined(USE_ADNS) +# if HAVE_ADNS_IF_TORMODE + tor_mode = 1; + return 0; +# endif +#endif + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} /* 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 @@ -92,7 +107,9 @@ get_dns_cert (const char *name, int want_certtype, *r_fprlen = 0; *r_url = NULL; - if (adns_init (&state, adns_if_noerrprint, NULL)) + if (tor_mode? adns_init_strcfg (&state, adns_if_noerrprint|adns_if_tormode, + NULL, "nameserver 8.8.8.8") + /* */: adns_init (&state, adns_if_noerrprint, NULL)) { err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); log_error ("error initializing adns: %s\n", strerror (errno)); diff --git a/dirmngr/dns-cert.h b/dirmngr/dns-cert.h index 9dbc58c23..e5cd4eb84 100644 --- a/dirmngr/dns-cert.h +++ b/dirmngr/dns-cert.h @@ -47,6 +47,7 @@ #define DNS_CERTTYPE_RRBASE 1024 /* Base of special constants. */ #define DNS_CERTTYPE_RR61 (DNS_CERTTYPE_RRBASE + 61) +gpg_error_t enable_dns_tormode (void); 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, diff --git a/dirmngr/server.c b/dirmngr/server.c index bfcdd5759..f6225d438 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -713,8 +713,9 @@ cmd_dns_cert (assuan_context_t ctx, char *line) } } - if (opt.use_tor) + if (opt.use_tor && enable_dns_tormode ()) { + /* TOR mode is requested but the DNS code can't enable it. */ err = gpg_error (GPG_ERR_FORBIDDEN); goto leave; }