[torsocks/master] Add reentrant functions gethostby*

commit c4f9f73a392b9f360d3a2b25e9ac5607e2b83230 Author: David Goulet <dgoulet@ev0ke.net> Date: Tue Aug 6 08:05:30 2013 -0400 Add reentrant functions gethostby* Signed-off-by: David Goulet <dgoulet@ev0ke.net> --- src/lib/gethostbyname.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-- src/lib/torsocks.h | 32 ++++++++++++++ 2 files changed, 140 insertions(+), 3 deletions(-) diff --git a/src/lib/gethostbyname.c b/src/lib/gethostbyname.c index af47e73..87dace1 100644 --- a/src/lib/gethostbyname.c +++ b/src/lib/gethostbyname.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2008 - Shaun Clowes <delius@progsoc.org> - * 2008-2011 - Robert Hogan <robert@roberthogan.net> - * 2013 - David Goulet <dgoulet@ev0ke.net> + * Copyright (C) 2000-2008 - Shaun Clowes <delius@progsoc.org> 2008-2011 - + * Robert Hogan <robert@roberthogan.net> 2013 - David Goulet + * <dgoulet@ev0ke.net> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2 only, as @@ -374,3 +374,108 @@ LIBC_GETHOSTBYADDR_R_DECL { return tsocks_gethostbyaddr_r(LIBC_GETHOSTBYADDR_R_ARGS); } + +/* + * Torsocks call for gethostbyname(3). + * + * NOTE: GNU extension. Reentrant version. + */ +LIBC_GETHOSTBYNAME_R_RET_TYPE tsocks_gethostbyname_r(LIBC_GETHOSTBYNAME_R_SIG) +{ + int ret; + /* This call is always using AF_INET. */ + uint32_t ip; + const char *ret_str; + struct hostent *he = NULL; + + struct data { + char addr[INET_ADDRSTRLEN]; + char *addr_list[2]; + char padding[]; + } *data; + + DBG("[gethostbyname_r] Requesting %s hostname", __name); + + if (!__name) { + *__h_errnop = HOST_NOT_FOUND; + ret = -1; + goto error; + } + + if (__buflen < sizeof(*data)) { + ret = ERANGE; + goto error; + } + + /* Resolve the given hostname through Tor. */ + ret = tsocks_tor_resolve(__name, &ip); + if (ret < 0) { + goto error; + } + + data = (struct data *) __buf; + memset(data, 0, sizeof(*data)); + /* Ease our life a bit. */ + he = __ret; + + ret_str = inet_ntop(AF_INET, &ip, data->addr, sizeof(data->addr)); + if (!ret_str) { + PERROR("inet_ntop"); + *__h_errnop = NO_ADDRESS; + goto error; + } + + memcpy(data->addr, &ip, sizeof(ip)); + data->addr_list[0] = data->addr; + data->addr_list[1] = NULL; + he->h_addr_list = data->addr_list; + + he->h_name = (char *) __name; + he->h_aliases = NULL; + he->h_length = sizeof(in_addr_t); + he->h_addrtype = AF_INET; + + DBG("[gethostbyname_r] Hostname %s resolved to %s", __name, + inet_ntoa(*((struct in_addr *) &ip))); + +error: + return ret; +} + +/* + * Libc hijacked symbol gethostbyname_r(3). + */ +LIBC_GETHOSTBYNAME_R_DECL +{ + return tsocks_gethostbyname_r(LIBC_GETHOSTBYNAME_R_ARGS); +} + +/* + * Torsocks call for gethostbyname(3). + * + * NOTE: GNU extension. Reentrant version. + */ +LIBC_GETHOSTBYNAME2_R_RET_TYPE tsocks_gethostbyname2_r(LIBC_GETHOSTBYNAME2_R_SIG) +{ + DBG("[gethostbyname2_r] Requesting %s hostname", __name); + + /* + * For now, there is no way of resolving a domain name to IPv6 through Tor + * so only accept INET request thus using the original gethostbyname(). + */ + if (__af != AF_INET) { + *__h_errnop = HOST_NOT_FOUND; + return -1; + } + + return tsocks_gethostbyname_r(__name, __ret, __buf, __buflen, __result, + __h_errnop); +} + +/* + * Libc hijacked symbol gethostbyname2_r(3). + */ +LIBC_GETHOSTBYNAME2_R_DECL +{ + return tsocks_gethostbyname2_r(LIBC_GETHOSTBYNAME2_R_ARGS); +} diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h index 55d46d6..f1a93ef 100644 --- a/src/lib/torsocks.h +++ b/src/lib/torsocks.h @@ -81,6 +81,26 @@ char tsocks_he_name[255]; #define LIBC_GETHOSTBYNAME2_SIG const char *__name, int __af #define LIBC_GETHOSTBYNAME2_ARGS __name, __af +/* GNU extension. Reentrant version. */ +#define LIBC_GETHOSTBYNAME_R_NAME gethostbyname_r +#define LIBC_GETHOSTBYNAME_R_NAME_STR XSTR(LIBC_GETHOSTBYNAME_R_NAME) +#define LIBC_GETHOSTBYNAME_R_RET_TYPE int +#define LIBC_GETHOSTBYNAME_R_SIG const char *__name, \ + struct hostent *__ret, char *__buf, size_t __buflen, \ + struct hostent **__result, int *__h_errnop +#define LIBC_GETHOSTBYNAME_R_ARGS __name, __ret, __buf, \ + __buflen, __result, __h_errnop + +/* GNU extension. Reentrant version 2. */ +#define LIBC_GETHOSTBYNAME2_R_NAME gethostbyname2_r +#define LIBC_GETHOSTBYNAME2_R_NAME_STR XSTR(LIBC_GETHOSTBYNAME2_R_NAME) +#define LIBC_GETHOSTBYNAME2_R_RET_TYPE int +#define LIBC_GETHOSTBYNAME2_R_SIG const char *__name, int __af, \ + struct hostent *__ret, char *__buf, size_t __buflen, \ +struct hostent **__result, int *__h_errnop +#define LIBC_GETHOSTBYNAME2_R_ARGS __name, __af, __ret, __buf, \ + __buflen, __result, __h_errnop + /* gethostbyaddr(3) - DEPRECATED in glibc. */ #include <sys/socket.h> @@ -146,12 +166,24 @@ TSOCKS_LIBC_DECL(gethostbyname, LIBC_GETHOSTBYNAME_RET_TYPE, #define LIBC_GETHOSTBYNAME_DECL LIBC_GETHOSTBYNAME_RET_TYPE \ LIBC_GETHOSTBYNAME_NAME(LIBC_GETHOSTBYNAME_SIG) +/* gethostbyname_r(3) */ +TSOCKS_LIBC_DECL(gethostbyname_r, LIBC_GETHOSTBYNAME_R_RET_TYPE, + LIBC_GETHOSTBYNAME_R_SIG) +#define LIBC_GETHOSTBYNAME_R_DECL LIBC_GETHOSTBYNAME_R_RET_TYPE \ + LIBC_GETHOSTBYNAME_R_NAME(LIBC_GETHOSTBYNAME_R_SIG) + /* gethostbyname2(3) */ TSOCKS_LIBC_DECL(gethostbyname2, LIBC_GETHOSTBYNAME2_RET_TYPE, LIBC_GETHOSTBYNAME2_SIG) #define LIBC_GETHOSTBYNAME2_DECL LIBC_GETHOSTBYNAME2_RET_TYPE \ LIBC_GETHOSTBYNAME2_NAME(LIBC_GETHOSTBYNAME2_SIG) +/* gethostbyname2_r(3) */ +TSOCKS_LIBC_DECL(gethostbyname2_r, LIBC_GETHOSTBYNAME2_R_RET_TYPE, + LIBC_GETHOSTBYNAME2_R_SIG) +#define LIBC_GETHOSTBYNAME2_R_DECL LIBC_GETHOSTBYNAME2_R_RET_TYPE \ + LIBC_GETHOSTBYNAME2_R_NAME(LIBC_GETHOSTBYNAME2_R_SIG) + /* gethostbyaddr(3) */ TSOCKS_LIBC_DECL(gethostbyaddr, LIBC_GETHOSTBYADDR_RET_TYPE, LIBC_GETHOSTBYADDR_SIG)
participants (1)
-
dgoulet@torproject.org