commit 6c84bdee0b3da63c1492024b0f267899ae4a4ca0 Author: Robert Hogan robert@roberthogan.net Date: Thu Feb 17 20:23:16 2011 +0000
Add a rudimentary test suite --- Makefile.am | 2 +- configure.in | 2 +- src/common.h | 5 +- src/dead_pool.c | 7 +- src/parser.c | 2 +- src/torsocks.c | 26 ++-- test/Makefile.am | 6 + test/README | 5 +- test/expectedresults.txt | 120 ++++++++++++ test/gethostbyaddr.c | 21 -- test/resinit.c | 204 --------------------- test/run_tests.sh | 42 +++++ test/test_torsocks.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++ test/udp.c | 89 --------- 14 files changed, 652 insertions(+), 336 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 02520f2..44a7fbd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,4 +2,4 @@ # have all needed files, that a GNU package needs AUTOMAKE_OPTIONS = foreign 1.4
-SUBDIRS = src +SUBDIRS = src test diff --git a/configure.in b/configure.in index 614f34e..f238caa 100644 --- a/configure.in +++ b/configure.in @@ -612,5 +612,5 @@ AC_ENABLE_STATIC
AC_CONFIG_FILES([src/usewithtor src/torsocks src/torsocks.conf.5 src/torsocks.8 src/usewithtor.1 src/torsocks.1])
-AC_OUTPUT(Makefile src/Makefile) +AC_OUTPUT(Makefile src/Makefile test/Makefile)
diff --git a/src/common.h b/src/common.h index 656aefb..1fc4589 100644 --- a/src/common.h +++ b/src/common.h @@ -64,8 +64,9 @@ unsigned int resolve_ip(char *, int, int); #define MSGNONE -1 #define MSGERR 0 #define MSGWARN 1 -#define MSGNOTICE 2 -#define MSGDEBUG 2 +#define MSGTEST 2 +#define MSGNOTICE 3 +#define MSGDEBUG 3
/* Required by some BSDs */ #ifndef MAP_ANONYMOUS diff --git a/src/dead_pool.c b/src/dead_pool.c index 6f4043a..0ef0d30 100644 --- a/src/dead_pool.c +++ b/src/dead_pool.c @@ -100,7 +100,7 @@ init_pool(unsigned int pool_size, struct in_addr deadrange_base, return NULL; }
- show_msg(MSGWARN, "init_pool: sockshost %s \n", sockshost); + show_msg(MSGDEBUG, "init_pool: sockshost %s \n", sockshost);
/* Initialize the dead_pool structure */ #ifdef HAVE_INET_ATON @@ -590,7 +590,7 @@ our_gethostbyaddr(dead_pool *pool, const void *_addr, socklen_t len, int type) he.h_addrtype = type; he.h_addr_list = addrs;
- show_msg(MSGDEBUG, "our_gethostbyaddr: resolved '%s' to: '%s'\n", + show_msg(MSGTEST, "our_gethostbyaddr: resolved '%s' to: '%s'\n", inet_ntoa(*((struct in_addr *)he.h_addr)), result_hostname);
return &he; @@ -605,7 +605,7 @@ our_gethostbyname(dead_pool *pool, const char *name) static struct hostent he; static char *addrs[2];
- show_msg(MSGDEBUG, "our_gethostbyname: '%s' requested\n", name); + show_msg(MSGTEST, "our_gethostbyname: '%s' requested\n", name);
pos = store_pool_entry(pool,(char *) name, &addr); if(pos == -1) { @@ -735,6 +735,7 @@ our_getaddrinfo(dead_pool *pool, const char *node, const char *service, ret = realgetaddrinfo(node, service, hints, res); }
+ show_msg(MSGTEST, "our_getaddrinfo: '%s' requested\n", service); return ret; }
diff --git a/src/parser.c b/src/parser.c index 592af18..c7c6290 100644 --- a/src/parser.c +++ b/src/parser.c @@ -82,7 +82,7 @@ int read_config (char *filename, struct parsedfile *config) { /* Insure null termination */ line[sizeof(line) - 1] = (char) 0; filename = line; - show_msg(MSGWARN, "Configuration file not provided by TORSOCKS_CONF_FILE " + show_msg(MSGDEBUG, "Configuration file not provided by TORSOCKS_CONF_FILE " "environment variable, attempting to use defaults in %s.\n", filename); }
diff --git a/src/torsocks.c b/src/torsocks.c index 98af4b0..8099a5e 100644 --- a/src/torsocks.c +++ b/src/torsocks.c @@ -140,13 +140,11 @@ void torsocks_init(void) /* This has been observed on Snow Leopard for instance. */ torsocks_init_complete = 1;
- show_msg(MSGWARN, "In torsocks_init \n"); + show_msg(MSGDEBUG, "In torsocks_init \n");
get_environment(); get_config();
- show_msg(MSGWARN, "In torsocks_init after env/config\n"); - #ifdef USE_OLD_DLSYM void *lib; #endif @@ -202,7 +200,7 @@ void torsocks_init(void) torsocks_init_complete=1; pthread_mutex_unlock(&torsocks_init_mutex);
- show_msg(MSGWARN, "Exit torsocks_init \n"); + show_msg(MSGDEBUG, "Exit torsocks_init \n"); }
static int get_environment() @@ -220,7 +218,7 @@ static int get_environment() loglevel = atoi(env); if (((env = getenv("TORSOCKS_DEBUG_FILE"))) && !suid) logfile = env; - set_log_options(loglevel, logfile, 1); + set_log_options(loglevel, logfile, (loglevel == MSGTEST) ? 0 : 1);
done = 1;
@@ -287,7 +285,7 @@ int torsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIG return(-1); }
- show_msg(MSGDEBUG, "Got connection request\n"); + show_msg(MSGTEST, "Got connection request\n");
connaddr = (struct sockaddr_in *) __addr;
@@ -456,6 +454,7 @@ int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATU if (!torsocks_init_complete) torsocks_init();
+ show_msg(MSGTEST, "Intercepted call to select\n"); show_msg(MSGDEBUG, "Intercepted call to select with %d fds, " "0x%08x 0x%08x 0x%08x, timeout %08x\n", n, readfds, writefds, exceptfds, timeout); @@ -641,6 +640,7 @@ int torsocks_poll_guts(POLL_SIGNATURE, int (*original_poll)(POLL_SIGNATURE)) if (!torsocks_init_complete) torsocks_init();
+ show_msg(MSGTEST, "Intercepted call to poll\n"); show_msg(MSGDEBUG, "Intercepted call to poll with %d fds, " "0x%08x timeout %d\n", nfds, ufds, timeout);
@@ -807,6 +807,7 @@ int torsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE)) return(-1); }
+ show_msg(MSGTEST, "Got call to close()\n"); show_msg(MSGDEBUG, "Call to close(%d)\n", fd);
rc = original_close(fd); @@ -854,6 +855,7 @@ int torsocks_getpeername_guts(GETPEERNAME_SIGNATURE, return(-1); }
+ show_msg(MSGTEST, "Intercepted call to getpeername\n"); show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
@@ -882,7 +884,7 @@ int res_init(void) if (!realres_init && ((realres_init = dlsym(RTLD_NEXT, "res_init")) == NULL)) LOAD_ERROR("res_init", MSGERR);
- show_msg(MSGDEBUG, "Got res_init request\n"); + show_msg(MSGTEST, "Got res_init request\n");
/* See comment in close() */ if (!torsocks_init_complete) @@ -907,7 +909,7 @@ int EXPAND_GUTS_NAME(res_query)(RES_QUERY_SIGNATURE, int (*original_res_query)(R if (!original_res_query && ((original_res_query = dlsym(RTLD_NEXT, "res_query")) == NULL)) LOAD_ERROR("res_query", MSGERR);
- show_msg(MSGDEBUG, "Got res_query request\n"); + show_msg(MSGTEST, "Got res_query request\n");
/* See comment in close() */ if (!torsocks_init_complete) @@ -967,7 +969,7 @@ int EXPAND_GUTS_NAME(res_search)(RES_SEARCH_SIGNATURE, int (*original_res_search ((original_res_search = dlsym(RTLD_NEXT, "res_search")) == NULL)) LOAD_ERROR("res_search", MSGERR);
- show_msg(MSGDEBUG, "Got res_search request\n"); + show_msg(MSGTEST, "Got res_search request\n");
/* See comment in close() */ if (!torsocks_init_complete) @@ -996,7 +998,7 @@ int EXPAND_GUTS_NAME(res_send)(RES_SEND_SIGNATURE, int (*original_res_send)(RES_ if (!original_res_send && ((original_res_send = dlsym(RTLD_NEXT, "res_send")) == NULL)) LOAD_ERROR("res_send", MSGERR);
- show_msg(MSGDEBUG, "Got res_send request\n"); + show_msg(MSGTEST, "Got res_send request\n");
/* See comment in close() */ if (!torsocks_init_complete) @@ -1089,7 +1091,7 @@ ssize_t torsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO return(-1); }
- show_msg(MSGDEBUG, "Got sendto request\n"); + show_msg(MSGTEST, "Got sendto request\n");
/* Get the type of the socket */ getsockopt(s, SOL_SOCKET, SO_TYPE, @@ -1133,7 +1135,7 @@ ssize_t torsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SEN return(-1); }
- show_msg(MSGDEBUG, "Got sendmsg request\n"); + show_msg(MSGTEST, "Got sendmsg request\n");
/* Get the type of the socket */ getsockopt(s, SOL_SOCKET, SO_TYPE, diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..47b78f3 --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,6 @@ +noinst_PROGRAMS= test_torsocks + +LIBS = -lresolv + +torsocks_test_SOURCES= test_torsocks.c +CLEANFILES= test_torsocks diff --git a/test/README b/test/README index c746800..4d65948 100644 --- a/test/README +++ b/test/README @@ -1,2 +1,3 @@ -This folder contains some simple test utilties for various libc function that -libtorsocks is expected to hook. \ No newline at end of file +To run the tests: +$./run_tests.sh + diff --git a/test/expectedresults.txt b/test/expectedresults.txt new file mode 100644 index 0000000..53f1105 --- /dev/null +++ b/test/expectedresults.txt @@ -0,0 +1,120 @@ +libtorsocks: The symbol getipnodebyname() was not found in any shared library. The error reported was: not found! +libtorsocks: The symbol getipnodebyname() was not found in any shared library. The error reported was: not found! +libtorsocks: The symbol getipnodebyname() was not found in any shared library. The error reported was: not found! +libtorsocks: our_getaddrinfo: 'www.torproject.org' requested +libtorsocks: Got sendmsg request +libtorsocks: sendmsg: Connection is a UDP or ICMP stream, may be a DNS request or other form of leak: rejecting. +libtorsocks: Got sendto request +libtorsocks: sendto: Connection is a UDP or ICMP stream, may be a DNS request or other form of leak: rejecting. +libtorsocks: Got sendto request +libtorsocks: sendto: Connection is a UDP or ICMP stream, may be a DNS request or other form of leak: rejecting. +libtorsocks: Got connection request +libtorsocks: connect: Connection is a UDP or ICMP stream, may be a DNS request or other form of leak: rejecting. +libtorsocks: our_gethostbyaddr: resolved '38.229.70.16' to: 'vescum.torproject.org' +libtorsocks: our_gethostbyname: 'www.torproject.org' requested +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +libtorsocks: Got connection request +libtorsocks: Intercepted call to getpeername +libtorsocks: Got res_init request +libtorsocks: Got connection request +libtorsocks: Intercepted call to getpeername +libtorsocks: Got connection request +libtorsocks: Intercepted call to getpeername +libtorsocks: Got connection request +libtorsocks: Intercepted call to getpeername +libtorsocks: Got connection request +libtorsocks: Intercepted call to getpeername +libtorsocks: Got res_init request +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +libtorsocks: Got connection request +libtorsocks: connect: Connection is to a local address (192.168.1.1), may be a TCP DNS request to a local DNS server so have to reject to be safe. Please report a bug to http://code.google.com/p/torsocks/issues/entry if this is preventing a program from working properly with torsocks. +socket: Operation not permitted + +----------------------getaddrinfo() TEST----------------- + +getaddrinfo: Servname not supported for ai_socktype + +----------------------UDP TEST---------------------- + + +----------------------udp sendmsg() TEST------------------- + +sendmsg() returned ret=-1 wb=0 + +----------------------udp sendto() TEST-------------------- + +sendto() returned ret=-1 wb=0 + +----------------------udp connect() TEST------------------- + +Connect returned ret=-1 + +----------------------udp send() TEST---------------------- + +Note: no interception by torsocks expected as send() requires a socket in a connected state. +send() returned ret=-1 wb=0 + +----------------------gethostbyaddr() TEST----------------- + +vescum.torproject.org -> 38.229.70.16 + +----------------------gethostbyname() TEST----------------- + +www.torproject.org -> 38.229.70.16 + +---------------------- local connect() TEST---------------------- + + +---------------------- internet connect() TEST---------------------- + + +---------------------- internet res_init() TEST---------------------- + +nameserver for test: 8.8.8.8 + +---------------------- internet res_query() TEST---------------------- + +return code: 102 + +---------------------- internet res_search() TEST---------------------- + +return code: 102 + +--------------- internet res_querydomain() TEST---------------------- + +return code: -1 + +---------------------- internet res_send() TEST---------------------- + +return code: -1 + +---------------------- local res_init() TEST---------------------- + +nameserver for test: 192.168.1.1 + +---------------------- local res_query() TEST---------------------- + +return code: -1 + +---------------------- local res_search() TEST---------------------- + +return code: -1 + +--------------- local res_querydomain() TEST---------------------- + +return code: -1 + +---------------------- local res_send() TEST---------------------- + +return code: -1 + +----------------icmp() TEST---------------------------- + diff --git a/test/gethostbyaddr.c b/test/gethostbyaddr.c deleted file mode 100644 index c3e719e..0000000 --- a/test/gethostbyaddr.c +++ /dev/null @@ -1,21 +0,0 @@ -#include <netdb.h> -#include <stdio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -//gcc -fPIC -g -O2 -Wall -I. -o gethostbyaddr gethostbyaddr.c -lc -int main() { - struct in_addr bar; - struct hostent *foo; - inet_aton("64.4.33.7",&bar); - foo=gethostbyaddr(&bar,4,AF_INET); - if (foo) { - int i; - for (i=0; foo->h_addr_list[i]; ++i) - printf("%s -> %s\n",foo->h_name,inet_ntoa(*(struct in_addr*)foo->h_addr_list[i])); - for (i=0; foo->h_aliases[i]; ++i) - printf(" also known as %s\n",foo->h_aliases[i]); - } - return 0; -} - diff --git a/test/resinit.c b/test/resinit.c deleted file mode 100644 index 73a9d57..0000000 --- a/test/resinit.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2004 Tomasz Kojm tkojm@clamav.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 <stdio.h> - -#include <string.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include <sys/types.h> - - -#include <netdb.h> -#include <stdio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sysexits.h> -#include <syslog.h> -#include <pthread.h> - -#include <netdb.h> -#include <arpa/nameser.h> -#include <resolv.h> - -#ifndef LINUX -#include <sys/queue.h> -#else -#include "queue.h" -#endif - -#ifndef PACKETSZ -#define PACKETSZ 512 -#endif - -static char *txtquery(const char *domain, unsigned int *ttl) -{ - unsigned char answer[PACKETSZ], *answend, *pt; - char *txt, host[128]; - int len, type, qtype; - unsigned int cttl, size, txtlen = 0; - - - *ttl = 0; - if(res_init() < 0) { - printf("^res_init failed\n"); - return NULL; - } - - printf("*Querying %s\n", domain); - - memset(answer, 0, PACKETSZ); - qtype = T_TXT; - if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) { - /* The DNS server in the SpeedTouch Alcatel 510 modem can't - * handle a TXT-query, but it can resolve an ANY-query to a - * TXT-record, so we try an ANY-query now. The thing we try - * to resolve normally only has a TXT-record anyway. - */ - memset(answer, 0, PACKETSZ); - qtype=T_ANY; - if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) { - printf("^Can't query %s\n", domain); - return NULL; - } - } - - answend = answer + len; - pt = answer + sizeof(HEADER); - - if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { - printf("^dn_expand failed\n"); - return NULL; - } - - pt += len; - if(pt > answend-4) { - printf("^Bad (too short) DNS reply\n"); - return NULL; - } - - GETSHORT(type, pt); - if(type != qtype) { - printf("^Broken DNS reply.\n"); - return NULL; - } - - pt += INT16SZ; /* class */ - size = 0; - do { /* recurse through CNAME rr's */ - pt += size; - if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { - printf("^second dn_expand failed\n"); - return NULL; - } - printf("^Host: %s\n", host); - pt += len; - if(pt > answend-10) { - printf("^Bad (too short) DNS reply\n"); - return NULL; - } - GETSHORT(type, pt); - pt += INT16SZ; /* class */ - GETLONG(cttl, pt); - GETSHORT(size, pt); - if(pt + size < answer || pt + size > answend) { - printf("^DNS rr overflow\n"); - return NULL; - } - } while(type == T_CNAME); - - if(type != T_TXT) { - printf("^Not a TXT record\n"); - return NULL; - } - - if(!size || (txtlen = *pt) >= size || !txtlen) { - printf("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size); - return NULL; - } - - if(!(txt = (char *) malloc(txtlen + 1))) - return NULL; - - memcpy(txt, pt+1, txtlen); - txt[txtlen] = 0; - *ttl = cttl; - - return txt; -} - - -//gcc -fPIC -g -O2 -Wall -I. -o resinit resinit.c -lc -lresolv -int main() { - unsigned char dnsreply[1024]; - unsigned char host[128]; - char *dnsrep; - int ret = 0; - unsigned int ttl=0; - - memset( dnsreply, '\0', sizeof( dnsreply )); -// if (res_init() == -1) -// { -// printf("res_init failed\n"); -// return -1; -// } - - snprintf((char *)host, 127, "www.google.com"); - dnsrep = txtquery((const char *)host, &ttl); - printf("RES_QUERY results: %s.", dnsrep); - printf("return code: %i\n", ret); - - snprintf((char *)host, 127, "www.google.com"); - ret = res_query( (char *) host, C_IN, T_TXT, dnsreply, sizeof( dnsreply )); - printf("RES_QUERY results: %s.", dnsreply); - printf("return code: %i\n", ret); - - memset( dnsreply, '\0', sizeof( dnsreply )); - ret = res_search( (char *) host, C_IN, T_TXT, dnsreply, sizeof( dnsreply )); - printf("RES_SEARCH results: %s.", dnsreply); - printf("return code: %i\n", ret); - - memset( dnsreply, '\0', sizeof( dnsreply )); - ret = res_querydomain( "www.google.com", "google.com", C_IN, T_TXT, dnsreply, sizeof( dnsreply )); - printf("RES_QUERYDOMAIN results: %s.", dnsreply); - printf("return code: %i\n", ret); - - memset( dnsreply, '\0', sizeof( dnsreply )); - ret = res_send( host, 32, dnsreply, sizeof( dnsreply )); - printf("RES_SEND results: %s.", dnsreply); - printf("return code: %i\n", ret); - - return ret; -} - - diff --git a/test/run_tests.sh b/test/run_tests.sh new file mode 100755 index 0000000..5776bfe --- /dev/null +++ b/test/run_tests.sh @@ -0,0 +1,42 @@ +#! /bin/sh +# *************************************************************************** +# * * +# * Copyright (C) 2008-2011 Robert Hogan robert@roberthogan.net * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +# * 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., * +#* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +# *************************************************************************** +TORSOCKS="`which torsocks`" + +if [ ! -x "$TORSOCKS" ]; then + echo "torsocks doesn't exist." >&2 + echo "Perhaps you haven't installed torsocks yet?" >&2 + exit 1 +fi + +if [ ! -f ./test_torsocks ]; then + echo "test_torsocks binary doesn't exist in this directory." >&2 + echo "Perhaps you haven't compiled torsocks yet?" >&2 + exit 1 +fi + +torsocks ./test_torsocks > /tmp/newresults.txt 2>&1 +output=`diff expectedresults.txt /tmp/newresults.txt` +if ["$output" = ""]; then + echo "Tests passed" +else + echo "Tests failed. Please post this output to http://code.google.com/p/torsocks/issues/entry" +fi +rm -f /tmp/newresults.txt diff --git a/test/test_torsocks.c b/test/test_torsocks.c new file mode 100644 index 0000000..e67de0a --- /dev/null +++ b/test/test_torsocks.c @@ -0,0 +1,457 @@ +/*************************************************************************** + * * + * Copyright (c) 2000 Alessandro Iurlano. * + * Copyright (C) 2004 Tomasz Kojm tkojm@clamav.net * + * Copyright (C) 2011 Robert Hogan robert@roberthogan.net * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <arpa/inet.h> +#include <arpa/nameser.h> +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip_icmp.h> +#include <pthread.h> +#include <resolv.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/un.h> +#include <sysexits.h> +#include <syslog.h> +#include <unistd.h> + +#ifndef LINUX +#include <sys/queue.h> +#else +#include "queue.h" +#endif + +#ifndef PACKETSZ +#define PACKETSZ 512 +#endif + +static unsigned short csum (unsigned short *buf, int nwords) +{ + unsigned long sum; + for (sum = 0; nwords > 0; nwords--) + sum += *buf++; + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return ~sum; +} + +static int icmp_test() +{ + + int sockfd; + char datagram[400]; + struct sockaddr_in dest; + struct ip *iphdr=(struct ip *) datagram; + struct icmphdr *icmphdr=(struct icmphdr *)(iphdr +1); + char *buff=(icmphdr +1); + printf("\n----------------icmp() TEST----------------------------\n\n"); + + if((sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) + { + perror("socket"); + exit(1); + } + + memset(datagram,0,400); + strcpy(buff,"entzwei"); + dest.sin_family=AF_INET; + dest.sin_addr.s_addr=inet_addr("192.168.1.33"); + + iphdr->ip_v=4; + iphdr->ip_hl=5; + iphdr->ip_len=sizeof(datagram); + iphdr->ip_id=htonl(54321); + iphdr->ip_off=0; + iphdr->ip_ttl=225; + iphdr->ip_p=1; + iphdr->ip_sum=0; + iphdr->ip_tos=0; + iphdr->ip_src.s_addr=inet_addr("192.168.1.35"); + iphdr->ip_dst.s_addr=dest.sin_addr.s_addr; + iphdr->ip_sum=csum((unsigned short *)datagram,iphdr->ip_len >> 1); + + icmphdr->type=130; + icmphdr->code=0; + icmphdr->checksum=htons(0xc3b0); + icmphdr->un.echo.sequence=0; + icmphdr->un.echo.id=0; + + int one=1; + int *val=&one; + if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one))<0) + printf("cannot set HDRINCL!\n"); + + + if(sendto(sockfd,datagram,35,0,(struct sockaddr *)&dest,sizeof(dest))<0) + { + perror("sendto"); + exit(1); + } + + return(0); +} + +static char *txtquery(const char *domain, unsigned int *ttl) +{ + unsigned char answer[PACKETSZ], *answend, *pt; + char *txt, host[128]; + int len, type, qtype; + unsigned int cttl, size, txtlen = 0; + + + *ttl = 0; + if(res_init() < 0) { + printf("^res_init failed\n"); + return NULL; + } + + printf("*Querying %s\n", domain); + + memset(answer, 0, PACKETSZ); + qtype = T_TXT; + if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) { + /* The DNS server in the SpeedTouch Alcatel 510 modem can't + * handle a TXT-query, but it can resolve an ANY-query to a + * TXT-record, so we try an ANY-query now. The thing we try + * to resolve normally only has a TXT-record anyway. + */ + memset(answer, 0, PACKETSZ); + qtype=T_ANY; + if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) { + printf("^Can't query %s\n", domain); + return NULL; + } + } + + answend = answer + len; + pt = answer + sizeof(HEADER); + + if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { + printf("^dn_expand failed\n"); + return NULL; + } + + pt += len; + if(pt > answend-4) { + printf("^Bad (too short) DNS reply\n"); + return NULL; + } + + GETSHORT(type, pt); + if(type != qtype) { + printf("^Broken DNS reply.\n"); + return NULL; + } + + pt += INT16SZ; /* class */ + size = 0; + do { /* recurse through CNAME rr's */ + pt += size; + if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) { + printf("^second dn_expand failed\n"); + return NULL; + } + printf("^Host: %s\n", host); + pt += len; + if(pt > answend-10) { + printf("^Bad (too short) DNS reply\n"); + return NULL; + } + GETSHORT(type, pt); + pt += INT16SZ; /* class */ + GETLONG(cttl, pt); + GETSHORT(size, pt); + if(pt + size < answer || pt + size > answend) { + printf("^DNS rr overflow\n"); + return NULL; + } + } while(type == T_CNAME); + + if(type != T_TXT) { + printf("^Not a TXT record\n"); + return NULL; + } + + if(!size || (txtlen = *pt) >= size || !txtlen) { + printf("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size); + return NULL; + } + + if(!(txt = (char *) malloc(txtlen + 1))) + return NULL; + + memcpy(txt, pt+1, txtlen); + txt[txtlen] = 0; + *ttl = cttl; + + return txt; +} + +static int res_tests(char *ip, char *test) { + unsigned char dnsreply[1024]; + unsigned char host[128]; + int ret = 0, i; + char buf[16]; + struct sockaddr_in addr; + + memset( dnsreply, '\0', sizeof( dnsreply )); + + printf("\n---------------------- %s res_init() TEST----------------------\n\n", test); + if (res_init() == -1) { + printf("res_init failed\n"); + return -1; + } + + inet_ntop(AF_INET, &_res.nsaddr_list[0].sin_addr.s_addr, buf, sizeof(buf)); + + addr.sin_family=AF_INET; + addr.sin_port=htons(53); + addr.sin_addr.s_addr=inet_addr(ip); + + for (i = 0; i < _res.nscount; i++) + memcpy(&_res.nsaddr_list[i], &addr, sizeof(struct sockaddr_in)); + + inet_ntop(AF_INET, &_res.nsaddr_list[0].sin_addr.s_addr, buf, sizeof(buf)); + printf("nameserver for test: %s\n", buf); + + printf("\n---------------------- %s res_query() TEST----------------------\n\n", test); + snprintf((char *)host, 127, "www.google.com"); + ret = res_nquery( &_res, (char *) host, C_IN, T_TXT, dnsreply, sizeof( dnsreply )); +// printf("RES_QUERY results: %s.\n", dnsreply); + printf("return code: %i\n", ret); + + printf("\n---------------------- %s res_search() TEST----------------------\n\n", test); + memset( dnsreply, '\0', sizeof( dnsreply )); + ret = res_nsearch( &_res, (char *) host, C_IN, T_TXT, dnsreply, sizeof( dnsreply )); +// printf("RES_SEARCH results: %s.\n", dnsreply); + printf("return code: %i\n", ret); + + printf("\n--------------- %s res_querydomain() TEST----------------------\n\n", test); + memset( dnsreply, '\0', sizeof( dnsreply )); + ret = res_nquerydomain( &_res, "www.google.com", "google.com", C_IN, T_TXT, dnsreply, sizeof( dnsreply )); +// printf("RES_QUERYDOMAIN results: %s.\n", dnsreply); + printf("return code: %i\n", ret); + + printf("\n---------------------- %s res_send() TEST----------------------\n\n", test); + memset( dnsreply, '\0', sizeof( dnsreply )); + ret = res_nsend( &_res, host, 32, dnsreply, sizeof( dnsreply )); +// printf("RES_SEND results: %s.\n", dnsreply); + printf("return code: %i\n", ret); + + return ret; +} + +static int res_internet_tests() { + char *ip = "8.8.8.8"; + char *test = "internet"; + return res_tests(ip, test); +} + +static int res_local_tests() { + char *ip = "192.168.1.1"; + char *test = "local"; + return res_tests(ip, test); +} + +static int udp_test() { + struct sockaddr_in addr; + char testtext[]="This message should be sent via udp\nThis is row number 2\nAnd then number three\n"; + int sock,ret,wb,flags=0; + char *ip = "6.6.6.6"; + + printf("\n----------------------UDP TEST----------------------\n\n"); + + addr.sin_family=AF_INET; + addr.sin_port=53; + addr.sin_addr.s_addr=inet_addr(ip); + + sock=socket(AF_INET,SOCK_DGRAM,0); + + struct iovec iov; + struct msghdr msg; + + iov.iov_base = (void *)testtext; + iov.iov_len = strlen(testtext); + + msg.msg_name = (struct sockaddr *)&addr; + msg.msg_namelen = sizeof(addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + + printf("\n----------------------udp sendmsg() TEST-------------------\n\n"); + wb=0; + ret=sendmsg(sock, &msg, flags); + printf("sendmsg() returned ret=%d wb=%d\n",ret,wb); + + printf("\n----------------------udp sendto() TEST--------------------\n\n"); + wb=0; + ret=sendto(sock,testtext,strlen(testtext)+1,wb, (struct sockaddr*)&addr, sizeof(addr)); + ret=sendto(sock,"CiaoCiao",strlen("CiaoCiao")+1,wb, (struct sockaddr*)&addr, sizeof(addr)); + printf("sendto() returned ret=%d wb=%d\n",ret,wb); + + printf("\n----------------------udp connect() TEST-------------------\n\n"); + ret=connect(sock,(struct sockaddr*)&addr,sizeof(addr)); + printf("Connect returned ret=%d\n",ret); + + printf("\n----------------------udp send() TEST----------------------\n\n"); + wb=0; + ret=send(sock,testtext,strlen(testtext)+1,wb); + ret=send(sock,"CiaoCiao",strlen("CiaoCiao")+1,wb); + printf("Note: no interception by torsocks expected as send() requires a socket in a connected state.\n"); + printf("send() returned ret=%d wb=%d\n",ret,wb); + + return 0; +} + +static int gethostbyname_test() { + struct hostent *foo; + + printf("\n----------------------gethostbyname() TEST-----------------\n\n"); + + foo=gethostbyname("www.torproject.org"); + if (foo) { + int i; + for (i=0; foo->h_addr_list[i]; ++i) + printf("%s -> %s\n",foo->h_name,inet_ntoa(*(struct in_addr*)foo->h_addr_list[i])); +/* for (i=0; foo->h_aliases[i]; ++i) + printf(" also known as %s\n",foo->h_aliases[i]);*/ + } + return 0; +} + +static int gethostbyaddr_test() { + struct in_addr bar; + struct hostent *foo; + + printf("\n----------------------gethostbyaddr() TEST-----------------\n\n"); + + inet_aton("38.229.70.16",&bar); + foo=gethostbyaddr(&bar,4,AF_INET); + if (foo) { + int i; + for (i=0; foo->h_addr_list[i]; ++i) + printf("%s -> %s\n",foo->h_name,inet_ntoa(*(struct in_addr*)foo->h_addr_list[i])); + for (i=0; foo->h_aliases[i]; ++i) + printf(" also known as %s\n",foo->h_aliases[i]); + } + return 0; +} + +static int getaddrinfo_test() { + struct addrinfo hints; + struct addrinfo *result; + int s; + + printf("\n----------------------getaddrinfo() TEST-----------------\n\n"); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + s = getaddrinfo(NULL, "www.torproject.org", &hints, &result); + if (s != 0) { + printf("getaddrinfo: %s\n", gai_strerror(s)); + } + + return 0; +} + +/* Unavailable in glibc. */ +/* +static int getipnodebyname_test() { + int error; + + printf("\n----------------------getipnodebyname() TEST-----------------\n\n"); + + getipnodebyname("www.torproject.org", AF_INET, 0, &error); + if (error != 0) { + printf("getipnodebyname error: %i\n", error); + } + + return 0; +} +*/ + +static int connect_test(const char *name, const char *ip, int port) +{ + int sock; + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip); + addr.sin_port = htons(port); + + printf("\n---------------------- %s connect() TEST----------------------\n\n", name); + + if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + return 1; + + if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) + return 1; + + return 0; +} + +static int connect_local_test() +{ + const char *ip = "192.168.1.1"; + const char *name = "local"; + int port = 80; + return connect_test(name, ip, port); +} + +static int connect_internet_test() +{ + const char *ip = "8.8.8.8"; + int port = 53; + const char *name = "internet"; + return connect_test(name, ip, port); +} + +int main() { + + getaddrinfo_test(); + udp_test(); + gethostbyaddr_test(); + gethostbyname_test(); + connect_local_test(); + connect_internet_test(); + res_internet_tests(); + res_local_tests(); + icmp_test(); + + return 0; +} diff --git a/test/udp.c b/test/udp.c deleted file mode 100644 index 4926c66..0000000 --- a/test/udp.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * OSSO - A Micro Kernel OS - * Copyright (c) 2000 Alessandro Iurlano. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * 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., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -/******************************* O S S O *********************************** - * file : $Source: /home/robert/Development/torsockstosvn/torsocks-cvsbackup/torsocks/test/udp.c,v $ - * Description: UDP protocol testing program. - *************************************************************************** - - *************************************************************************** - * $Id: udp.c,v 1.1 2008-06-23 19:38:34 hoganrobert Exp $ - ***************************************************************************/ - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <netdb.h> -#include <unistd.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/types.h> - -//gcc -fPIC -g -O2 -Wall -I. -o udp udp.c -lc - -struct sockaddr_in addr; -char testtext[]="This message should be sent via udp\nThis is row number 2\nAnd then number three\n"; - - -int main(int argc, char *argv[]) { - int sock,ret,wb,flags=0; - - printf("\n----------------------UDP TEST----------------------\n\n"); - - addr.sin_family=AF_INET; - addr.sin_port=53; - addr.sin_addr.s_addr=159|(134<<8)|(237<<16)|(6<<24); - - sock=socket(AF_INET,SOCK_DGRAM,0); - - printf("socket returned %d\n",sock); - - struct iovec iov; - struct msghdr msg; - - iov.iov_base = (void *)testtext; - iov.iov_len = strlen(testtext); - - msg.msg_name = (struct sockaddr *)&addr; - msg.msg_namelen = sizeof(addr); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - - wb=0; - ret=sendmsg(sock, &msg, flags); - printf("sendmsg() returned ret=%d wb=%d\n",ret,wb); - - wb=0; - ret=sendto(sock,testtext,strlen(testtext)+1,wb, (struct sockaddr*)&addr, sizeof(addr)); - ret=sendto(sock,"CiaoCiao",strlen("CiaoCiao")+1,wb, (struct sockaddr*)&addr, sizeof(addr)); - printf("sendto() returned ret=%d wb=%d\n",ret,wb); - - ret=connect(sock,(struct sockaddr*)&addr,sizeof(addr)); - printf("Connect returned ret=%d\n",ret); - wb=0; - ret=send(sock,testtext,strlen(testtext)+1,wb); - ret=send(sock,"CiaoCiao",strlen("CiaoCiao")+1,wb); - printf("send() returned ret=%d wb=%d\n",ret,wb); - - - return 0; -}
tor-commits@lists.torproject.org