commit 50e740492c0a1a547fe56952332c1d6fd2751371 Author: David Goulet dgoulet@ev0ke.net Date: Fri Feb 7 22:14:30 2014 -0500
Add portable is localhost function
This removes the utils_is_ipv4_local() call and move to a generic portable way of checking if the sockaddr is localhost (both ipv4 and ipv6 are supported).
Reported-by: Nick Mathewson nickm@torproject.org Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/common/compat.h | 11 +++-------- src/common/utils.c | 29 +++++++++++++++++++++++++++++ src/common/utils.h | 11 +---------- src/lib/connect.c | 7 +++---- 4 files changed, 36 insertions(+), 22 deletions(-)
diff --git a/src/common/compat.h b/src/common/compat.h index e9a59e7..077bcce 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -98,13 +98,8 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#endif /* __FreeBSD__, __FreeBSD_kernel__, __darwin__, __NetBSD__ */
-/* - * Shamelessly taken from linux/in.h of the libc. This is consider trivial code - * by the GPL license thus copying it as is should be OK. Slight modification - * was made to make the check in host byte order. - */ -#ifndef IN_LOOPBACK -#define IN_LOOPBACK(a) ((((long int) (a)) & 0x000000ff) == 0x0000007f) -#endif +#define TSOCKS_CLASSA_NET 0xff000000 +#define TSOCKS_LOOPBACK_NET 0x7f000000 +#define TSOCKS_IN6_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
#endif /* TORSOCKS_COMPAT_H */ diff --git a/src/common/utils.c b/src/common/utils.c index 0c5c2c8..4ecb9f4 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -18,12 +18,14 @@ */
#include <arpa/inet.h> +#include <netinet/in.h> #include <sys/socket.h> #include <assert.h> #include <errno.h> #include <stdlib.h> #include <string.h>
+#include "compat.h" #include "macros.h" #include "utils.h"
@@ -176,3 +178,30 @@ int utils_strcasecmpend(const char *s1, const char *s2) return strncasecmp(s1 + (n1 - n2), s2, n2); } } + +/* + * Return 1 if the given sockaddr is localhost else 0 + */ +ATTR_HIDDEN +int utils_sockaddr_is_localhost(const struct sockaddr *sa) +{ + int is_localhost; + + assert(sa); + + if (sa->sa_family == AF_INET) { + const struct sockaddr_in *sin = (const struct sockaddr_in *) sa; + is_localhost = ((ntohl(sin->sin_addr.s_addr) & TSOCKS_CLASSA_NET) == + TSOCKS_LOOPBACK_NET); + } else if (sa->sa_family == AF_INET6) { + const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) sa; + static const uint8_t addr[] = TSOCKS_IN6_INIT; + is_localhost = !memcmp(sin6->sin6_addr.s6_addr, addr, + sizeof(sin6->sin6_addr.s6_addr)); + } else { + /* Unknown sockaddr family thus not localhost. */ + is_localhost = 0; + } + + return is_localhost; +} diff --git a/src/common/utils.h b/src/common/utils.h index 474b2df..7721dc5 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -30,15 +30,6 @@ int utils_tokenize_ignore_comments(const char *_line, size_t size, char **tokens
int utils_is_address_ipv4(const char *ip); int utils_is_address_ipv6(const char *ip); - -/* - * Check if the given IPv4 is in the loopback net (127.x.x.x). - * - * Return 1 if so else 0 if not. - */ -static inline int utils_is_ipv4_local(in_addr_t addr) -{ - return IN_LOOPBACK(addr); -} +int utils_sockaddr_is_localhost(const struct sockaddr *sa);
#endif /* TORSOCKS_UTILS_H */ diff --git a/src/lib/connect.c b/src/lib/connect.c index bdc9e6f..8f34e37 100644 --- a/src/lib/connect.c +++ b/src/lib/connect.c @@ -109,11 +109,10 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG) new_conn->dest_addr.hostname.port = inet_addr->sin_port; } else { /* - * Check if address is local IPv4. At this point, we are sure it's not - * a .onion cookie address that is by default in the loopback network. + * Check if address is localhost. At this point, we are sure it's not a + * .onion cookie address that is by default in the loopback network. */ - if (__addr->sa_family == AF_INET && - utils_is_ipv4_local(inet_addr->sin_addr.s_addr)) { + if (utils_sockaddr_is_localhost(__addr)) { WARN("[connect] Connection to a local address are denied since it " "might be a TCP DNS query to a local DNS server. " "Rejecting it for safety reasons.");
tor-commits@lists.torproject.org