[tor-commits] [torsocks/osx] Add a rudimentary test suite
hoganrobert at torproject.org
hoganrobert at torproject.org
Sun Oct 23 18:27:16 UTC 2011
commit 6c84bdee0b3da63c1492024b0f267899ae4a4ca0
Author: Robert Hogan <robert at 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 at 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 at 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 at clamav.net> *
+ * Copyright (C) 2011 Robert Hogan <robert at 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;
-}
More information about the tor-commits
mailing list