commit 4c90e9e112cd1f72bc7f90af9f3d59dc37c832dc Author: David Goulet dgoulet@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@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 */