commit fb388753632387f0c25d7be91f8d132418915d4c Author: David Goulet dgoulet@ev0ke.net Date: Mon Aug 5 12:00:15 2013 -0400
Add getpeername(2) support
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/lib/Makefile.am | 3 ++- src/lib/getpeername.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/torsocks.h | 16 ++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index ec9ef0f..f27db5c 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -11,7 +11,8 @@ EXTRA_DIST = torsocks.in usewithtor.in lib_LTLIBRARIES = libtorsocks.la
libtorsocks_la_SOURCES = torsocks.c torsocks.h \ - connect.c gethostbyname.c getaddrinfo.c close.c + connect.c gethostbyname.c getaddrinfo.c close.c \ + getpeername.c
libtorsocks_la_LIBADD = \ $(top_builddir)/src/common/libcommon.la \ diff --git a/src/lib/getpeername.c b/src/lib/getpeername.c new file mode 100644 index 0000000..8e4b671 --- /dev/null +++ b/src/lib/getpeername.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 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 + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <arpa/inet.h> +#include <assert.h> + +#include <common/log.h> + +#include "torsocks.h" + +/* + * Torsocks call for getpeername(2). + */ +LIBC_GETPEERNAME_RET_TYPE tsocks_getpeername(LIBC_GETPEERNAME_SIG) +{ + int ret = 0; + struct connection *conn; + + DBG("[getpeername] Requesting address on socket %d", __sockfd); + + connection_registry_lock(); + conn = connection_find(__sockfd); + if (!conn) { + errno = ENOTCONN; + ret = -1; + goto end; + } + connection_registry_unlock(); + + errno = 0; +end: + return ret; +} + +/* + * Libc hijacked symbol getpeername(2). + */ +LIBC_GETPEERNAME_DECL +{ + int ret; + + tsocks_libc_getpeername = tsocks_find_libc_symbol(LIBC_GETPEERNAME_NAME_STR, + TSOCKS_SYM_EXIT_NOT_FOUND); + + ret = tsocks_libc_getpeername(LIBC_GETPEERNAME_ARGS); + if (ret < 0) { + /* errno is populated by the previous call at this point. */ + return ret; + } + + return tsocks_getpeername(LIBC_GETPEERNAME_ARGS); +} diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h index 3cd51d0..55d46d6 100644 --- a/src/lib/torsocks.h +++ b/src/lib/torsocks.h @@ -111,6 +111,16 @@ char tsocks_he_name[255]; struct addrinfo **__res #define LIBC_GETADDRINFO_ARGS __node, __service, __hints, __res
+/* getpeername(2) */ +#include <sys/socket.h> + +#define LIBC_GETPEERNAME_NAME getpeername +#define LIBC_GETPEERNAME_NAME_STR XSTR(LIBC_GETPEERNAME_NAME) +#define LIBC_GETPEERNAME_RET_TYPE int +#define LIBC_GETPEERNAME_SIG \ + int __sockfd, struct sockaddr *__addr, socklen_t *__addrlen +#define LIBC_GETPEERNAME_ARGS __sockfd, __addr, __addrlen + #else #error "OS not supported." #endif /* __linux__ , __FreeBSD__, __darwin__ */ @@ -160,6 +170,12 @@ TSOCKS_LIBC_DECL(getaddrinfo, LIBC_GETADDRINFO_RET_TYPE, #define LIBC_GETADDRINFO_DECL LIBC_GETADDRINFO_RET_TYPE \ LIBC_GETADDRINFO_NAME(LIBC_GETADDRINFO_SIG)
+/* getpeername(2) */ +TSOCKS_LIBC_DECL(getpeername, LIBC_GETPEERNAME_RET_TYPE, + LIBC_GETPEERNAME_SIG) +#define LIBC_GETPEERNAME_DECL LIBC_GETPEERNAME_RET_TYPE \ + LIBC_GETPEERNAME_NAME(LIBC_GETPEERNAME_SIG) + /* * Those are actions to do during the lookup process of libc symbols. For * instance the connect(2) syscall is essential to Torsocks so the function
tor-commits@lists.torproject.org