Loading TODO +1 −1 Original line number Diff line number Diff line Version 2.0 ----------- * Support res_* API * Get sendmsg FD passing on Unix socket and for TCP socket, clean exit * Check recvmmsg() FD passing on Unix socket and for TCP socket, clean exit * Deny ICMP * Support the complete list of dangerous syscall number with syscall() Loading src/lib/Makefile.am +1 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ lib_LTLIBRARIES = libtorsocks.la libtorsocks_la_SOURCES = torsocks.c torsocks.h \ connect.c gethostbyname.c getaddrinfo.c close.c \ getpeername.c socket.c syscall.c socketpair.c getpeername.c socket.c syscall.c socketpair.c recv.c libtorsocks_la_LIBADD = \ $(top_builddir)/src/common/libcommon.la \ Loading src/lib/recv.c 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * 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 <assert.h> #include <stdlib.h> #include <common/log.h> #include "torsocks.h" /* * Torsocks call for recvmsg(2) * * We only hijack this call to handle the FD passing between process on Unix * socket. If an INET/INET6 socket is recevied, we stop everything because at * that point we can't guarantee traffic going through Tor. */ LIBC_RECVMSG_RET_TYPE tsocks_recvmsg(LIBC_RECVMSG_SIG) { int fd; ssize_t ret = 0; char dummy, recv_fd[CMSG_SPACE(sizeof(fd))]; struct iovec iov[1]; struct cmsghdr *cmsg; struct msghdr msg; memset(&msg, 0, sizeof(msg)); /* Prepare to receive the structures */ iov[0].iov_base = &dummy; iov[0].iov_len = 1; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = recv_fd; msg.msg_controllen = sizeof(recv_fd); do { /* Just peek the data to inspect the payload for fd. */ ret = tsocks_libc_recvmsg(__sockfd, &msg, MSG_PEEK); } while (ret < 0 && errno == EINTR); cmsg = CMSG_FIRSTHDR(&msg); if (!cmsg) { goto end; } /* * Detecting FD passing, the next snippet of code will check if we get a * inet/inet6 socket. If so, everything stops immediately before going * further. */ if (cmsg->cmsg_type == SCM_RIGHTS || cmsg->cmsg_level == SOL_SOCKET) { socklen_t optlen; int sock_dom; memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); /* Get socket domain. */ optlen = sizeof(sock_dom); ret = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &sock_dom, &optlen); if (ret < 0) { /* Use the getsockopt() errno value. */ goto end; } if (sock_dom == AF_INET || sock_dom == AF_INET6) { ERR("[recvmsg] Inet socket passing detected. Aborting everything! " "A non Tor socket could be used thus leaking information."); exit(EXIT_FAILURE); } } end: return tsocks_libc_recvmsg(LIBC_RECVMSG_ARGS); } /* * Libc hijacked symbol recvmsg(2). */ LIBC_RECVMSG_DECL { /* Find symbol if not already set. Exit if not found. */ tsocks_libc_recvmsg = tsocks_find_libc_symbol(LIBC_RECVMSG_NAME_STR, TSOCKS_SYM_EXIT_NOT_FOUND); return tsocks_recvmsg(LIBC_RECVMSG_ARGS); } src/lib/torsocks.h +13 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,14 @@ struct hostent **__result, int *__h_errnop int __sockfd, struct sockaddr *__addr, socklen_t *__addrlen #define LIBC_GETPEERNAME_ARGS __sockfd, __addr, __addrlen #define LIBC_RECVMSG_NAME recvmsg #define LIBC_RECVMSG_NAME_STR XSTR(LIBC_RECVMSG_NAME) #define LIBC_RECVMSG_RET_TYPE ssize_t #define LIBC_RECVMSG_SIG \ int __sockfd, struct msghdr *__msg, int __flags #define LIBC_RECVMSG_ARGS \ __sockfd, __msg, __flags #else #error "OS not supported." #endif /* __linux__ , __FreeBSD__, __darwin__ */ Loading Loading @@ -191,6 +199,11 @@ TSOCKS_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG) #define LIBC_CONNECT_DECL \ LIBC_CONNECT_RET_TYPE LIBC_CONNECT_NAME(LIBC_CONNECT_SIG) /* recvmsg(2) */ TSOCKS_LIBC_DECL(recvmsg, LIBC_RECVMSG_RET_TYPE, LIBC_RECVMSG_SIG) #define LIBC_RECVMSG_DECL \ LIBC_RECVMSG_RET_TYPE LIBC_RECVMSG_NAME(LIBC_RECVMSG_SIG) /* socket(2) */ TSOCKS_LIBC_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) TSOCKS_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) Loading Loading
TODO +1 −1 Original line number Diff line number Diff line Version 2.0 ----------- * Support res_* API * Get sendmsg FD passing on Unix socket and for TCP socket, clean exit * Check recvmmsg() FD passing on Unix socket and for TCP socket, clean exit * Deny ICMP * Support the complete list of dangerous syscall number with syscall() Loading
src/lib/Makefile.am +1 −1 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ lib_LTLIBRARIES = libtorsocks.la libtorsocks_la_SOURCES = torsocks.c torsocks.h \ connect.c gethostbyname.c getaddrinfo.c close.c \ getpeername.c socket.c syscall.c socketpair.c getpeername.c socket.c syscall.c socketpair.c recv.c libtorsocks_la_LIBADD = \ $(top_builddir)/src/common/libcommon.la \ Loading
src/lib/recv.c 0 → 100644 +100 −0 Original line number Diff line number Diff line /* * 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 <assert.h> #include <stdlib.h> #include <common/log.h> #include "torsocks.h" /* * Torsocks call for recvmsg(2) * * We only hijack this call to handle the FD passing between process on Unix * socket. If an INET/INET6 socket is recevied, we stop everything because at * that point we can't guarantee traffic going through Tor. */ LIBC_RECVMSG_RET_TYPE tsocks_recvmsg(LIBC_RECVMSG_SIG) { int fd; ssize_t ret = 0; char dummy, recv_fd[CMSG_SPACE(sizeof(fd))]; struct iovec iov[1]; struct cmsghdr *cmsg; struct msghdr msg; memset(&msg, 0, sizeof(msg)); /* Prepare to receive the structures */ iov[0].iov_base = &dummy; iov[0].iov_len = 1; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = recv_fd; msg.msg_controllen = sizeof(recv_fd); do { /* Just peek the data to inspect the payload for fd. */ ret = tsocks_libc_recvmsg(__sockfd, &msg, MSG_PEEK); } while (ret < 0 && errno == EINTR); cmsg = CMSG_FIRSTHDR(&msg); if (!cmsg) { goto end; } /* * Detecting FD passing, the next snippet of code will check if we get a * inet/inet6 socket. If so, everything stops immediately before going * further. */ if (cmsg->cmsg_type == SCM_RIGHTS || cmsg->cmsg_level == SOL_SOCKET) { socklen_t optlen; int sock_dom; memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); /* Get socket domain. */ optlen = sizeof(sock_dom); ret = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &sock_dom, &optlen); if (ret < 0) { /* Use the getsockopt() errno value. */ goto end; } if (sock_dom == AF_INET || sock_dom == AF_INET6) { ERR("[recvmsg] Inet socket passing detected. Aborting everything! " "A non Tor socket could be used thus leaking information."); exit(EXIT_FAILURE); } } end: return tsocks_libc_recvmsg(LIBC_RECVMSG_ARGS); } /* * Libc hijacked symbol recvmsg(2). */ LIBC_RECVMSG_DECL { /* Find symbol if not already set. Exit if not found. */ tsocks_libc_recvmsg = tsocks_find_libc_symbol(LIBC_RECVMSG_NAME_STR, TSOCKS_SYM_EXIT_NOT_FOUND); return tsocks_recvmsg(LIBC_RECVMSG_ARGS); }
src/lib/torsocks.h +13 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,14 @@ struct hostent **__result, int *__h_errnop int __sockfd, struct sockaddr *__addr, socklen_t *__addrlen #define LIBC_GETPEERNAME_ARGS __sockfd, __addr, __addrlen #define LIBC_RECVMSG_NAME recvmsg #define LIBC_RECVMSG_NAME_STR XSTR(LIBC_RECVMSG_NAME) #define LIBC_RECVMSG_RET_TYPE ssize_t #define LIBC_RECVMSG_SIG \ int __sockfd, struct msghdr *__msg, int __flags #define LIBC_RECVMSG_ARGS \ __sockfd, __msg, __flags #else #error "OS not supported." #endif /* __linux__ , __FreeBSD__, __darwin__ */ Loading Loading @@ -191,6 +199,11 @@ TSOCKS_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG) #define LIBC_CONNECT_DECL \ LIBC_CONNECT_RET_TYPE LIBC_CONNECT_NAME(LIBC_CONNECT_SIG) /* recvmsg(2) */ TSOCKS_LIBC_DECL(recvmsg, LIBC_RECVMSG_RET_TYPE, LIBC_RECVMSG_SIG) #define LIBC_RECVMSG_DECL \ LIBC_RECVMSG_RET_TYPE LIBC_RECVMSG_NAME(LIBC_RECVMSG_SIG) /* socket(2) */ TSOCKS_LIBC_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) TSOCKS_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) Loading