aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dirmngr/dns-stuff.c14
-rw-r--r--dirmngr/dns-stuff.h3
-rw-r--r--dirmngr/http.c26
-rw-r--r--dirmngr/ks-engine-hkp.c21
4 files changed, 62 insertions, 2 deletions
diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
index c80ee1dfa..21e5610a3 100644
--- a/dirmngr/dns-stuff.c
+++ b/dirmngr/dns-stuff.c
@@ -403,6 +403,20 @@ is_ip_address (const char *name)
}
+/* Return true if NAME is an onion address. */
+int
+is_onion_address (const char *name)
+{
+ size_t len;
+
+ len = name? strlen (name) : 0;
+ if (len < 8 || strcmp (name + len - 6, ".onion"))
+ return 0;
+ /* Note that we require at least 2 characters before the suffix. */
+ return 1; /* Yes. */
+}
+
+
#ifdef USE_ADNS
/* Init ADNS and store the new state at R_STATE. Returns 0 on
success; prints an error message and returns an error code on
diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
index c3effad83..515a859b1 100644
--- a/dirmngr/dns-stuff.h
+++ b/dirmngr/dns-stuff.h
@@ -110,6 +110,9 @@ gpg_error_t resolve_dns_addr (const struct sockaddr *addr, int addrlen,
/* Return true if NAME is a numerical IP address. */
int is_ip_address (const char *name);
+/* Return true if NAME is an onion address. */
+int is_onion_address (const char *name);
+
/* Get the canonical name for NAME. */
gpg_error_t get_dns_cname (const char *name, char **r_cname);
diff --git a/dirmngr/http.c b/dirmngr/http.c
index 1a7c1ff17..9e2ba90f8 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -2212,6 +2212,32 @@ connect_server (const char *server, unsigned short port,
init_sockets ();
#endif /*Windows*/
+ /* Onion addresses require special treatment. */
+ if (is_onion_address (server))
+ {
+#ifdef ASSUAN_SOCK_TOR
+
+ my_unprotect ();
+ sock = assuan_sock_connect_byname (server, port, 0, NULL,
+ ASSUAN_SOCK_TOR);
+ my_protect ();
+
+ if (sock == ASSUAN_INVALID_FD)
+ {
+ if (errno == EHOSTUNREACH)
+ *r_host_not_found = 1;
+ log_error ("can't connect to '%s': %s\n", server, strerror (errno));
+ }
+ return sock;
+
+#else /*!ASSUAN_SOCK_TOR*/
+
+ gpg_err_set_errno (ENETUNREACH);
+ return -1; /* Out of core. */
+
+#endif /*!HASSUAN_SOCK_TOR*/
+ }
+
#ifdef USE_DNS_SRV
/* Do the SRV thing */
if (srvtag)
diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
index 340b012ad..a6587271c 100644
--- a/dirmngr/ks-engine-hkp.c
+++ b/dirmngr/ks-engine-hkp.c
@@ -80,6 +80,7 @@ struct hostinfo_s
int poolidx; /* Index into POOL with the used host. -1 if not set. */
unsigned int v4:1; /* Host supports AF_INET. */
unsigned int v6:1; /* Host supports AF_INET6. */
+ unsigned int onion:1;/* NAME is an onion (Tor HS) address. */
unsigned int dead:1; /* Host is currently unresponsive. */
time_t died_at; /* The time the host was marked dead. If this is
0 the host has been manually marked dead. */
@@ -124,6 +125,7 @@ create_new_hostinfo (const char *name)
hi->lastfail = (time_t)(-1);
hi->v4 = 0;
hi->v6 = 0;
+ hi->onion = 0;
hi->dead = 0;
hi->died_at = 0;
hi->cname = NULL;
@@ -267,7 +269,15 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
/* See whether the host is in our table. */
idx = find_hostinfo (name);
- if (idx == -1)
+ if (idx == -1 && is_onion_address (name))
+ {
+ idx = create_new_hostinfo (name);
+ if (idx == -1)
+ return gpg_error_from_syserror ();
+ hi = hosttable[idx];
+ hi->onion = 1;
+ }
+ else if (idx == -1)
{
/* We never saw this host. Allocate a new entry. */
dns_addrinfo_t aibuf, ai;
@@ -512,6 +522,11 @@ map_host (ctrl_t ctrl, const char *name, int force_reselect,
*r_httpflags |= HTTP_FLAG_IGNORE_IPv4;
if (!hi->v6)
*r_httpflags |= HTTP_FLAG_IGNORE_IPv6;
+
+ /* Note that we do not set the HTTP_FLAG_FORCE_TOR for onion
+ addresses because the http module detects this itself. This
+ also allows us to use an onion address without Tor mode being
+ enabled. */
}
*r_host = xtrystrdup (hi->name);
@@ -683,7 +698,9 @@ ks_hkp_print_hosttable (ctrl_t ctrl)
else
diedstr = died = NULL;
err = ks_printf_help (ctrl, "%3d %s %s %s %s%s%s%s%s%s%s%s\n",
- idx, hi->v6? "6":" ", hi->v4? "4":" ",
+ idx,
+ hi->onion? "O" : hi->v6? "6":" ",
+ hi->v4? "4":" ",
hi->dead? "d":" ",
hi->name,
hi->v6addr? " v6=":"",