mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
dirmngr: Fix Tor access for v6 addresses.
* dirmngr/http.c (use_socks): New. (my_sock_new_for_addr): New. (connect_server): Replace assuan_sock_new by my_sock_new_for_addr. -- Libassuan always uses 127.0.0.1 to connect to the local Tor proxy. https.c used to create a socket for the actual address family and thus the connect call in Libassuan fails when it tries to connect to a v6 address using a v4 socket. It would be cleaner to have the my_sock_new_for_addr function as a public interface in Libassuan; for now we need to duplicate some code. from Libassuan. GnuPG-bug-id: 2902 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
915864e7f0
commit
09aeac41c9
@ -2337,6 +2337,68 @@ start_server ()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return true if SOCKS shall be used. This is the case if tor_mode
|
||||||
|
* is enabled and the desired address is not the loopback address.
|
||||||
|
* This function is basically a copy of the same internal fucntion in
|
||||||
|
* Libassuan. */
|
||||||
|
static int
|
||||||
|
use_socks (struct sockaddr *addr)
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
|
||||||
|
if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)
|
||||||
|
return 0; /* Not in Tor mode. */
|
||||||
|
else if (addr->sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
|
||||||
|
const unsigned char *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s = (unsigned char *)&addr_in6->sin6_addr.s6_addr;
|
||||||
|
if (s[15] != 1)
|
||||||
|
return 1; /* Last octet is not 1 - not the loopback address. */
|
||||||
|
for (i=0; i < 15; i++, s++)
|
||||||
|
if (*s)
|
||||||
|
return 1; /* Non-zero octet found - not the loopback address. */
|
||||||
|
|
||||||
|
return 0; /* This is the loopback address. */
|
||||||
|
}
|
||||||
|
else if (addr->sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
|
||||||
|
|
||||||
|
if (*(unsigned char*)&addr_in->sin_addr.s_addr == 127)
|
||||||
|
return 0; /* Loopback (127.0.0.0/8) */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper around assuan_sock_new which takes the domain from an
|
||||||
|
* address parameter. */
|
||||||
|
static assuan_fd_t
|
||||||
|
my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
|
||||||
|
{
|
||||||
|
int domain;
|
||||||
|
|
||||||
|
if (use_socks (addr))
|
||||||
|
{
|
||||||
|
/* Libassaun always uses 127.0.0.1 to connect to the socks
|
||||||
|
* server (i.e. the Tor daemon). */
|
||||||
|
domain = AF_INET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
domain = addr->sa_family;
|
||||||
|
|
||||||
|
return assuan_sock_new (domain, type, proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Actually connect to a server. Returns the file descriptor or -1 on
|
/* Actually connect to a server. Returns the file descriptor or -1 on
|
||||||
error. ERRNO is set on error. */
|
error. ERRNO is set on error. */
|
||||||
static assuan_fd_t
|
static assuan_fd_t
|
||||||
@ -2436,7 +2498,7 @@ connect_server (const char *server, unsigned short port,
|
|||||||
|
|
||||||
if (sock != ASSUAN_INVALID_FD)
|
if (sock != ASSUAN_INVALID_FD)
|
||||||
assuan_sock_close (sock);
|
assuan_sock_close (sock);
|
||||||
sock = assuan_sock_new (ai->family, ai->socktype, ai->protocol);
|
sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
|
||||||
if (sock == ASSUAN_INVALID_FD)
|
if (sock == ASSUAN_INVALID_FD)
|
||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user