diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index cae2c5737..6bf36a553 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -85,17 +85,32 @@ /* If set Tor mode shall be used. */ static int tor_mode; +/* A string to hold the credentials presented to Tor. */ +#ifdef USE_ADNS +static char tor_credentials[50]; +#endif + /* Sets the module in Tor mode. Returns 0 is this is possible or an error code. */ gpg_error_t -enable_dns_tormode (void) +enable_dns_tormode (int new_circuit) { #if defined(USE_DNS_CERT) && defined(USE_ADNS) # if HAVE_ADNS_IF_TORMODE + if (!*tor_credentials || new_circuit) + { + static unsigned int counter; + + gpgrt_snprintf (tor_credentials, sizeof tor_credentials, + "dirmngr-%lu:p%u", + (unsigned long)getpid (), counter); + counter++; + } tor_mode = 1; return 0; # endif #endif + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -145,14 +160,35 @@ map_eai_to_gpg_error (int ec) static gpg_error_t my_adns_init (adns_state *r_state) { - gpg_error_t err; + gpg_error_t err = 0; + int ret; - if (tor_mode? adns_init_strcfg (r_state, - adns_if_noerrprint|adns_if_tormode, - NULL, "nameserver 8.8.8.8") - /* */: adns_init (r_state, adns_if_noerrprint, NULL)) + if (tor_mode) + { + char *cfgstr; + + cfgstr = xtryasprintf ("nameserver %s\n" + "options adns_tormode adns_sockscred:%s", + "8.8.8.8", tor_credentials); + if (!cfgstr) + err = gpg_error_from_syserror (); + else + { + ret = adns_init_strcfg (r_state, adns_if_noerrprint, NULL, cfgstr); + if (ret) + err = gpg_error_from_errno (ret); + xfree (cfgstr); + } + } + else + { + ret = adns_init (r_state, adns_if_noerrprint, NULL); + if (ret) + err = gpg_error_from_errno (ret); + } + + if (err) { - err = gpg_error_from_syserror (); log_error ("error initializing adns: %s\n", gpg_strerror (err)); return err; } @@ -176,6 +212,9 @@ resolve_name_adns (const char *name, unsigned short port, adns_answer *answer = NULL; int count; + (void)port; + (void)want_family; + *r_dai = NULL; if (r_canonname) *r_canonname = NULL; diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h index 515a859b1..69637d61d 100644 --- a/dirmngr/dns-stuff.h +++ b/dirmngr/dns-stuff.h @@ -94,7 +94,7 @@ struct srventry /* Calling this function switches the DNS code into Tor mode if possibe. Return 0 on success. */ -gpg_error_t enable_dns_tormode (void); +gpg_error_t enable_dns_tormode (int new_circuit); void free_dns_addrinfo (dns_addrinfo_t ai); diff --git a/dirmngr/server.c b/dirmngr/server.c index 74e00fb2b..ba3750869 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -714,10 +714,10 @@ cmd_dns_cert (assuan_context_t ctx, char *line) } } - if (opt.use_tor && enable_dns_tormode ()) + if (opt.use_tor && (err = enable_dns_tormode (0))) { /* Tor mode is requested but the DNS code can't enable it. */ - err = gpg_error (GPG_ERR_FORBIDDEN); + assuan_set_error (ctx, err, "error enabling Tor mode"); goto leave; } diff --git a/dirmngr/t-dns-stuff.c b/dirmngr/t-dns-stuff.c index 191b581b4..303027755 100644 --- a/dirmngr/t-dns-stuff.c +++ b/dirmngr/t-dns-stuff.c @@ -41,6 +41,7 @@ main (int argc, char **argv) gpg_error_t err; int any_options = 0; int opt_tor = 0; + int opt_new_circuit = 0; int opt_cert = 0; int opt_srv = 0; int opt_bracket = 0; @@ -66,6 +67,7 @@ main (int argc, char **argv) " --verbose print timings etc.\n" " --debug flyswatter\n" " --use-tor use Tor\n" + " --new-circuit use a new Tor circuit\n" " --bracket enclose v6 addresses in brackets\n" " --cert lookup a CERT RR\n" " --srv lookup a SRV RR\n" @@ -89,6 +91,11 @@ main (int argc, char **argv) opt_tor = 1; argc--; argv++; } + else if (!strcmp (*argv, "--new-circuit")) + { + opt_new_circuit = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--bracket")) { opt_bracket = 1; @@ -131,7 +138,7 @@ main (int argc, char **argv) if (opt_tor) { - err = enable_dns_tormode (); + err = enable_dns_tormode (opt_new_circuit); if (err) { fprintf (stderr, "error switching into Tor mode: %s\n",