[tor-commits] [torsocks/master] Fix: deny connection to ANY address
dgoulet at torproject.org
dgoulet at torproject.org
Fri Apr 4 22:40:27 UTC 2014
commit ebbcae0c5f6ad4772e459a80e6d99cacb731fb1f
Author: David Goulet <dgoulet at ev0ke.net>
Date: Thu Feb 20 10:59:10 2014 +0000
Fix: deny connection to ANY address
It's possible to connect to 0.0.0.0/:: which are addresses that Tor
can't of course handle thus deny the call and send back EINVAL.
Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
src/common/compat.h | 2 ++
src/common/utils.c | 30 ++++++++++++++++++++++++++++++
src/common/utils.h | 1 +
src/lib/connect.c | 9 +++++++++
tests/unit/test_utils.c | 38 +++++++++++++++++++++++++++++++++++++-
5 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/src/common/compat.h b/src/common/compat.h
index ee8263f..e977b41 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -104,5 +104,7 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
/* Loopback address in network byte order. */
#define TSOCKS_LOOPBACK 0x0100007f
#define TSOCKS_LOOPBACK6 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
+#define TSOCKS_ANY ((unsigned long int) 0x00000000)
+#define TSOCKS_ANY6 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
#endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/utils.c b/src/common/utils.c
index e526ce7..578d290 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -306,3 +306,33 @@ match:
error:
return -EINVAL;
}
+
+/*
+ * For a given sockaddr, check if the IP address is ANY which is 0.0.0.0 for
+ * IPv4 and :: for IPv6.
+ *
+ * Return 1 if it is else 0.
+ */
+ATTR_HIDDEN
+int utils_is_addr_any(const struct sockaddr *sa)
+{
+ int ret;
+
+ assert(sa);
+
+ if (sa->sa_family == AF_INET) {
+ const struct sockaddr_in *sin = (const struct sockaddr_in *) sa;
+ ret = (sin->sin_addr.s_addr == TSOCKS_ANY);
+ } else if (sa->sa_family == AF_INET6) {
+ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) sa;
+ const uint8_t addr[] = TSOCKS_ANY6;
+ ret = !memcmp(sin6->sin6_addr.s6_addr, addr,
+ sizeof(sin6->sin6_addr.s6_addr));
+ } else {
+ ret = 0;
+ goto end;
+ }
+
+end:
+ return ret;
+}
diff --git a/src/common/utils.h b/src/common/utils.h
index b0281eb..2f950aa 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -32,5 +32,6 @@ int utils_is_address_ipv4(const char *ip);
int utils_is_address_ipv6(const char *ip);
int utils_sockaddr_is_localhost(const struct sockaddr *sa);
int utils_localhost_resolve(const char *name, int af, void *buf, size_t len);
+int utils_is_addr_any(const struct sockaddr *sa);
#endif /* TORSOCKS_UTILS_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index bb15882..e47ab38 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -65,6 +65,15 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
goto error;
}
+ /*
+ * Trying to connect to ANY address will evidently not work for Tor thus we
+ * deny the call.
+ */
+ if (utils_is_addr_any(addr)) {
+ errno = EINVAL;
+ goto error;
+ }
+
DBG("[connect] Socket family %s and type %d",
addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
diff --git a/tests/unit/test_utils.c b/tests/unit/test_utils.c
index 2db255b..8efa19a 100644
--- a/tests/unit/test_utils.c
+++ b/tests/unit/test_utils.c
@@ -24,7 +24,7 @@
#include <tap/tap.h>
-#define NUM_TESTS 26
+#define NUM_TESTS 30
static void test_is_address_ipv4(void)
{
@@ -178,6 +178,41 @@ static void test_utils_tokenize_ignore_comments(void)
ok(nb_token == 0, "Returns 0 tokens for comment");
}
+static void test_is_addr_any(void)
+{
+ int ret;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(42);
+ inet_pton(sin.sin_family, "0.0.0.0", &sin.sin_addr);
+
+ ret = utils_is_addr_any((const struct sockaddr *) &sin);
+ ok(ret == 1, "This address is 0.0.0.0");
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(42);
+ inet_pton(sin.sin_family, "1.0.0.0", &sin.sin_addr);
+
+ ret = utils_is_addr_any((const struct sockaddr *) &sin);
+ ok(ret == 0, "This address is NOT 0.0.0.0");
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(42);
+ inet_pton(sin6.sin6_family, "::", &sin6.sin6_addr);
+
+ ret = utils_is_addr_any((const struct sockaddr *) &sin6);
+ ok(ret == 1, "This address is ::");
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(42);
+ inet_pton(sin6.sin6_family, "fe80::1", &sin6.sin6_addr);
+
+ ret = utils_is_addr_any((const struct sockaddr *) &sin6);
+ ok(ret == 0, "This address is NOT ::");
+}
+
int main(int argc, char **argv)
{
/* Libtap call for the number of tests planned. */
@@ -188,6 +223,7 @@ int main(int argc, char **argv)
test_localhost_resolve();
test_sockaddr_is_localhost();
test_utils_tokenize_ignore_comments();
+ test_is_addr_any();
return exit_status();
}
More information about the tor-commits
mailing list