[tor-commits] [torsocks/master] Implement gethostbyaddr libc call

dgoulet at torproject.org dgoulet at torproject.org
Fri Apr 4 22:40:25 UTC 2014


commit 4c90e9e112cd1f72bc7f90af9f3d59dc37c832dc
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Sun Jun 23 22:38:40 2013 -0400

    Implement gethostbyaddr libc call
    
    Also add the tor resolve ptr function call in torsocks used by
    gethostbyaddr().
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/lib/gethostbyname.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/torsocks.c      |   48 ++++++++++++++++++++++++++++++++++
 src/lib/torsocks.h      |   19 +++++++++++++-
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/src/lib/gethostbyname.c b/src/lib/gethostbyname.c
index d9afec9..3e89e9b 100644
--- a/src/lib/gethostbyname.c
+++ b/src/lib/gethostbyname.c
@@ -24,6 +24,7 @@
 #include <common/log.h>
 
 #include "torsocks.h"
+
 /*
  * Torsocks call for gethostbyname(3).
  *
@@ -113,3 +114,68 @@ LIBC_GETHOSTBYNAME2_DECL
 {
 	return tsocks_gethostbyname2(LIBC_GETHOSTBYNAME2_ARGS);
 }
+
+/*
+ * Torsocks call for gethostbyaddr(3).
+ *
+ * NOTE: This call is OBSOLETE in the glibc. Also, this call returns a pointer
+ * to a static pointer.
+ */
+LIBC_GETHOSTBYADDR_RET_TYPE tsocks_gethostbyaddr(LIBC_GETHOSTBYADDR_SIG)
+{
+	int ret;
+	char *hostname;
+
+	/*
+	 * Tor does not allow to resolve to an IPv6 pointer so only accept inet
+	 * return address.
+	 */
+	if (!__addr || __type != AF_INET) {
+		h_errno = HOST_NOT_FOUND;
+		goto error;
+	}
+
+	DBG("[gethostbyaddr] Requesting address %s of len %d and type %d",
+			inet_ntoa(*((struct in_addr *) __addr)), __len, __type);
+
+	/* Reset static host entry of tsocks. */
+	memset(&tsocks_he, 0, sizeof(tsocks_he));
+	memset(tsocks_he_addr_list, 0, sizeof(tsocks_he_addr_list));
+	memset(tsocks_he_name, 0, sizeof(tsocks_he_name));
+
+	ret = tsocks_tor_resolve_ptr(__addr, &hostname, __type);
+	if (ret < 0) {
+		const char *ret_str;
+
+		ret_str = inet_ntop(__type, __addr, tsocks_he_name,
+				sizeof(tsocks_he_name));
+		if (!ret_str) {
+			h_errno = HOST_NOT_FOUND;
+			goto error;
+		}
+	} else {
+		memcpy(tsocks_he_name, hostname, sizeof(tsocks_he_name));
+		free(hostname);
+		tsocks_he_addr_list[0] = (char *) __addr;
+	}
+
+	tsocks_he.h_name = tsocks_he_name;
+	tsocks_he.h_aliases = NULL;
+	tsocks_he.h_length = strlen(tsocks_he_name);
+	tsocks_he.h_addrtype = __type;
+	tsocks_he.h_addr_list = tsocks_he_addr_list;
+
+	errno = 0;
+	return &tsocks_he;
+
+error:
+	return NULL;
+}
+
+/*
+ * Libc hijacked symbol gethostbyaddr(3).
+ */
+LIBC_GETHOSTBYADDR_DECL
+{
+	return tsocks_gethostbyaddr(LIBC_GETHOSTBYADDR_ARGS);
+}
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index 6b657ef..bc5959a 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -19,6 +19,7 @@
 
 #include <assert.h>
 #include <dlfcn.h>
+#include <inttypes.h>
 #include <stdlib.h>
 
 #include <common/config-file.h>
@@ -305,6 +306,53 @@ error:
 }
 
 /*
+ * Resolve a hostname through Tor and set the ip address in the given pointer.
+ *
+ * Return 0 on success else a negative value and the result addr is untouched.
+ */
+int tsocks_tor_resolve_ptr(const char *addr, char **ip, int af)
+{
+	int ret;
+	struct connection conn;
+
+	assert(addr);
+	assert(ip);
+
+	DBG("Resolving %" PRIu32 " on the Tor network", addr);
+
+	conn.fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (conn.fd < 0) {
+		PERROR("socket");
+		ret = -errno;
+		goto error;
+	}
+
+	ret = setup_tor_connection(&conn);
+	if (ret < 0) {
+		goto error;
+	}
+
+	ret = socks5_send_resolve_ptr_request(addr, &conn);
+	if (ret < 0) {
+		goto error;
+	}
+
+	/* Force IPv4 resolution for now. */
+	ret = socks5_recv_resolve_ptr_reply(&conn, ip);
+	if (ret < 0) {
+		goto error;
+	}
+
+	ret = close(conn.fd);
+	if (ret < 0) {
+		PERROR("close");
+	}
+
+error:
+	return ret;
+}
+
+/*
  * Lookup symbol in the loaded libraries of the binary.
  *
  * Return the function pointer or NULL on error.
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 0121716..2e6fd50 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -45,7 +45,7 @@
 #define LIBC_CONNECT_ARGS \
 	__sockfd, __addr, __addrlen
 
-/* gethostbyname(3) */
+/* gethostbyname(3) - DEPRECATED in glibc. */
 #include <netdb.h>
 
 /*
@@ -57,6 +57,7 @@
 struct hostent tsocks_he;
 char *tsocks_he_addr_list[2];
 char tsocks_he_addr[INET_ADDRSTRLEN];
+char tsocks_he_name[255];
 
 #define LIBC_GETHOSTBYNAME_NAME gethostbyname
 #define LIBC_GETHOSTBYNAME_NAME_STR XSTR(LIBC_GETHOSTBYNAME_NAME)
@@ -71,6 +72,15 @@ char tsocks_he_addr[INET_ADDRSTRLEN];
 #define LIBC_GETHOSTBYNAME2_SIG const char *__name, int __af
 #define LIBC_GETHOSTBYNAME2_ARGS __name, __af
 
+/* gethostbyaddr(3) - DEPRECATED in glibc. */
+#include <sys/socket.h>
+
+#define LIBC_GETHOSTBYADDR_NAME gethostbyaddr
+#define LIBC_GETHOSTBYADDR_NAME_STR XSTR(LIBC_GETHOSTBYADDR_NAME)
+#define LIBC_GETHOSTBYADDR_RET_TYPE struct hostent *
+#define LIBC_GETHOSTBYADDR_SIG const void *__addr, socklen_t __len, int __type
+#define LIBC_GETHOSTBYADDR_ARGS __addr, __len, __type
+
 /* getaddrinfo(3) */
 #include <netdb.h>
 
@@ -108,6 +118,12 @@ TSOCKS_LIBC_DECL(gethostbyname2, LIBC_GETHOSTBYNAME2_RET_TYPE,
 #define LIBC_GETHOSTBYNAME2_DECL LIBC_GETHOSTBYNAME2_RET_TYPE \
 		LIBC_GETHOSTBYNAME2_NAME(LIBC_GETHOSTBYNAME2_SIG)
 
+/* gethostbyaddr(3) */
+TSOCKS_LIBC_DECL(gethostbyaddr, LIBC_GETHOSTBYADDR_RET_TYPE,
+		LIBC_GETHOSTBYADDR_SIG)
+#define LIBC_GETHOSTBYADDR_DECL LIBC_GETHOSTBYADDR_RET_TYPE \
+		LIBC_GETHOSTBYADDR_NAME(LIBC_GETHOSTBYADDR_SIG)
+
 /* getaddrinfo(3) */
 TSOCKS_LIBC_DECL(getaddrinfo, LIBC_GETADDRINFO_RET_TYPE,
 		LIBC_GETADDRINFO_SIG)
@@ -131,5 +147,6 @@ int tsocks_connect_to_tor(struct connection *conn);
 void *tsocks_find_libc_symbol(const char *symbol,
 		enum tsocks_sym_action action);
 int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr);
+int tsocks_tor_resolve_ptr(const char *addr, char **ip, int af);
 
 #endif /* TORSOCKS_H */





More information about the tor-commits mailing list