[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [torsocks/master] Fix: fix localhost resolution address
commit 467f3a847b7f9c529bf1ffc1f65eb275dfaa8062
Author: David Goulet <dgoulet@xxxxxxxxx>
Date: Thu Nov 7 20:03:31 2013 -0500
Fix: fix localhost resolution address
Every DNS resolving call now will query the local host table (usually
/etc/hosts) before trying through Tor. Thus this fixes the issue of
localhost resolution.
If the application tries to connect to localhost, it is refused since it
might be a TCP DNS query to a local DNS server.
Adds a test for localhost resolution with getaddrinfo().
Fixes #14
Signed-off-by: David Goulet <dgoulet@xxxxxxxxx>
---
src/common/compat.h | 8 ++++++++
src/common/utils.c | 15 +++++++++++++++
src/common/utils.h | 2 ++
src/lib/connect.c | 11 +++++++++++
src/lib/torsocks.c | 39 +++++++++++++++++++++++++++++++++++++++
tests/test_dns.c | 9 ++++++++-
6 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/src/common/compat.h b/src/common/compat.h
index 9173caf..faadfdb 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -101,4 +101,12 @@ 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.
+ */
+#ifndef IN_LOOPBACK
+#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
+#endif
+
#endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/utils.c b/src/common/utils.c
index 0c5c2c8..33fc109 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
+#include "compat.h"
#include "macros.h"
#include "utils.h"
@@ -176,3 +177,17 @@ int utils_strcasecmpend(const char *s1, const char *s2)
return strncasecmp(s1 + (n1 - n2), s2, n2);
}
}
+
+
+/*
+ * Check if the given IPv4 is in the loopback net (127.x.x.x).
+ *
+ * Return 1 if so else 0 if not.
+ */
+ATTR_HIDDEN
+int utils_is_ipv4_local(in_addr_t addr)
+{
+ assert(addr);
+
+ return IN_LOOPBACK(addr);
+}
diff --git a/src/common/utils.h b/src/common/utils.h
index aeda872..062441e 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -29,4 +29,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);
+int utils_is_ipv4_local(in_addr_t addr);
+
#endif /* TORSOCKS_UTILS_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index bc3ac9d..09d3be6 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -22,6 +22,7 @@
#include <common/connection.h>
#include <common/log.h>
#include <common/onion.h>
+#include <common/utils.h>
#include "torsocks.h"
@@ -70,6 +71,16 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
inet_addr = (struct sockaddr_in *) __addr;
+ /* Check if address is local IPv4. */
+ if (__addr->sa_family == AF_INET &&
+ utils_is_ipv4_local(be32toh(inet_addr->sin_addr.s_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.");
+ errno = EPERM;
+ goto error;
+ }
+
/*
* Lock registry to get the connection reference if one. In this code path,
* if a connection object is found, it will not be used since a double
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index 55ae98b..93c2c35 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -322,6 +322,40 @@ error:
}
/*
+ * Lookup the local host table (usually /etc/hosts) for a given hostname.
+ *
+ * If found, ip_addr is populated and 0 is returned.
+ * If NOT found, -1 is return and ip_addr is untouched.
+ */
+static int hosts_file_resolve(const char *hostname, uint32_t *ip_addr)
+{
+ int ret;
+ struct hostent *host;
+
+ assert(hostname);
+ assert(ip_addr);
+
+ DBG("Looking in local host table for %s", hostname);
+
+ /* Query the local host table if the hostname is present. */
+ while ((host = gethostent()) != NULL) {
+ if (strncasecmp(hostname, host->h_name, strlen(hostname)) == 0) {
+ /* IP is found, copying and returning success. */
+ memcpy(ip_addr, host->h_addr_list[0], sizeof(uint32_t));
+ ret = 0;
+ goto end;
+ }
+ }
+
+ /* Not found. */
+ ret = -1;
+
+end:
+ endhostent();
+ return ret;
+}
+
+/*
* Initiate a SOCK5 connection to the Tor network using the given connection.
* The socks5 API will use the torsocks configuration object to find the tor
* daemon.
@@ -369,6 +403,11 @@ int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr)
assert(hostname);
assert(ip_addr);
+ ret = hosts_file_resolve(hostname, ip_addr);
+ if (!ret) {
+ goto end;
+ }
+
DBG("Resolving %s on the Tor network", hostname);
/*
diff --git a/tests/test_dns.c b/tests/test_dns.c
index 01bb5d9..58c7675 100644
--- a/tests/test_dns.c
+++ b/tests/test_dns.c
@@ -24,7 +24,7 @@
#include <tap/tap.h>
-#define NUM_TESTS 3
+#define NUM_TESTS 4
struct test_host {
const char *name;
@@ -49,6 +49,12 @@ static const struct test_host tor_dir_auth2 = {
.ip = "171.25.193.9",
};
+/* localhost resolution. */
+static const struct test_host tor_localhost = {
+ .name = "localhost",
+ .ip = "127.0.0.1",
+};
+
static void test_gethostbyname(const struct test_host *host)
{
struct hostent *he;
@@ -133,6 +139,7 @@ int main(int argc, char **argv)
test_getaddrinfo(&tor_check);
test_gethostbyname(&tor_dir_auth1);
test_gethostbyaddr(&tor_dir_auth2);
+ test_getaddrinfo(&tor_localhost);
return 0;
}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits