tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2014
- 22 participants
- 2020 discussions
commit df40ceaaa17dbe4fb5431f6cb41bc1560192f9cb
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 13:49:43 2014 -0400
Tests: add socket() test
Add unit test for socket() and socketpair().
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
.gitignore | 1 +
tests/Makefile.am | 5 ++-
tests/test_list | 1 +
tests/test_socket.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 129 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 59fcadb..c474007 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,7 @@ doc/usewithtor.1
src/bin/torsocks
tests/test_dns
+tests/test_socket
tests/unit/test_onion
tests/unit/test_connection
tests/unit/test_utils
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 18eb5a9..ae3c2d1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,11 +6,14 @@ LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la
LIBTORSOCKS=$(top_builddir)/src/lib/libtorsocks.la
-noinst_PROGRAMS = test_dns
+noinst_PROGRAMS = test_dns test_socket
test_dns_SOURCES = test_dns.c
test_dns_LDADD = $(LIBTAP) $(LIBTORSOCKS)
+test_socket_SOURCES = test_socket.c
+test_socket_LDADD = $(LIBTAP) $(LIBTORSOCKS)
+
check-am:
./run.sh test_list
diff --git a/tests/test_list b/tests/test_list
index d5f09ba..542b93f 100644
--- a/tests/test_list
+++ b/tests/test_list
@@ -1,4 +1,5 @@
./test_dns
+./test_socket
./unit/test_onion
./unit/test_connection
./unit/test_utils
diff --git a/tests/test_socket.c b/tests/test_socket.c
new file mode 100644
index 0000000..55f1586
--- /dev/null
+++ b/tests/test_socket.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2014 - David Goulet <dgoulet(a)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 <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+
+#include <lib/torsocks.h>
+
+#include <tap/tap.h>
+
+#define NUM_TESTS 18
+
+static void test_socketpair_types(void)
+{
+ int fd[2], ret1, ret2, err;
+
+ err = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
+ ret1 = close(fd[0]);
+ ret2 = close(fd[1]);
+ ok (fd[0] != -1 && fd[1] != -1 && !err && ret1 == 0 && ret2 == 0,
+ "Unix socket valid for socketpair");
+
+ err = socketpair(AF_INET, SOCK_STREAM, 0, fd);
+ ok (err == -1 && errno == EPERM, "INET socket NOT valid for socketpair");
+
+ err = socketpair(AF_INET6, SOCK_STREAM, 0, fd);
+ ok (err == -1 && errno == EPERM, "INET6 socket NOT valid for socketpair");
+}
+
+static void test_socket_types(void)
+{
+ int fd, ret;
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "Unix socket is valid");
+
+ fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "AF local socket is valid");
+
+ fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv4 TCP socket is valid");
+
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv4 TCP non block socket is valid");
+
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
+ IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv4 TCP non block/cloexec socket is valid");
+
+ fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv6 TCP socket is valid");
+
+ fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv6 TCP non block socket is valid");
+
+ fd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
+ IPPROTO_IP);
+ ret = close(fd);
+ ok (fd != -1 && ret == 0, "IPv6 TCP non block/cloexec socket is valid");
+
+ fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ ok (fd == -1 && errno == EPERM,
+ "IPv4 UDP socket is NOT valid");
+
+ fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
+ ok (fd == -1 && errno == EPERM,
+ "IPv4 UDP non block socket is NOT valid");
+
+ fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
+ IPPROTO_UDP);
+ ok (fd == -1 && errno == EPERM,
+ "IPv4 UDP non block/cloexec socket is NOT valid");
+
+ fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ ok (fd == -1 && errno == EPERM,
+ "IPv6 UDP socket is NOT valid");
+
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+ ok (fd == -1 && errno == EPERM,
+ "IPv4 RAW socket is NOT valid");
+
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ ok (fd == -1 && errno == EPERM,
+ "IPv4 RAW ICMP socket is NOT valid");
+
+ fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
+ ok (fd == -1 && errno == EPERM,
+ "IPv6 RAW socket is NOT valid");
+}
+
+int main(int argc, char **argv)
+{
+ /* Libtap call for the number of tests planned. */
+ plan_tests(NUM_TESTS);
+
+ test_socket_types();
+ test_socketpair_types();
+
+ return 0;
+}
1
0

04 Apr '14
commit 3b8687973757cbecfe22a7e5708da15523111c55
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 13:49:32 2014 -0400
Fix: socket() type check SOCK_STREAM
Even though connect() makes a check, deny socket creation that are
INET/INET6 but NOT of type SOCK_STREAM. This fix makes our wrapper
handle socket type flags that can be passed to the kernel such as
SOCK_NONBLOCK and SOCK_CLOEXEC.
Furthermore, the type check was *not* right since having a type set to
SOCK_DGRAM also matches SOCK_STREAM when using the & operator.
A unit test is added for the IS_SOCK_STREAM(type) macro that test if a
socket type is a SOCK_STREAM.
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
.gitignore | 1 +
src/common/compat.h | 12 ++++++++
src/lib/connect.c | 2 +-
src/lib/socket.c | 39 ++++++++++++++++----------
tests/test_list | 1 +
tests/unit/Makefile.am | 5 +++-
tests/unit/test_compat.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 114 insertions(+), 16 deletions(-)
diff --git a/.gitignore b/.gitignore
index 5394c5b..59fcadb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,4 @@ tests/unit/test_connection
tests/unit/test_utils
tests/unit/test_config-file
tests/unit/test_socks5
+tests/unit/test_compat
diff --git a/src/common/compat.h b/src/common/compat.h
index 2058a23..87191f0 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -107,4 +107,16 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#define TSOCKS_ANY ((unsigned long int) 0x00000000)
#define TSOCKS_ANY6 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+/*
+ * Macro to tell if a given socket type is a SOCK_STREAM or not. The macro
+ * resolve to 1 if yes else 0.
+ */
+#if defined(__NetBSD__)
+#define IS_SOCK_STREAM(type) \
+ ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC | SOCK_NOSIGPIPE)) == SOCK_STREAM)
+#else /* __NetBSD__ */
+#define IS_SOCK_STREAM(type) \
+ ((type & ~(SOCK_NONBLOCK | SOCK_CLOEXEC)) == SOCK_STREAM)
+#endif /* __NetBSD__ */
+
#endif /* TORSOCKS_COMPAT_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index 6622119..0973e1e 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -58,7 +58,7 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
* Refuse non stream socket. There is a chance that this might be a DNS
* request that we can't pass through Tor using raw UDP packet.
*/
- if (sock_type != SOCK_STREAM) {
+ if (!IS_SOCK_STREAM(sock_type)) {
WARN("[connect] UDP or ICMP stream can't be handled. Rejecting.");
errno = EBADF;
goto error;
diff --git a/src/lib/socket.c b/src/lib/socket.c
index cf080b5..bdac610 100644
--- a/src/lib/socket.c
+++ b/src/lib/socket.c
@@ -32,23 +32,34 @@ LIBC_SOCKET_RET_TYPE tsocks_socket(LIBC_SOCKET_SIG)
DBG("[socket] Creating socket with domain %d, type %d and protocol %d",
domain, type, protocol);
- if (type & SOCK_STREAM) {
+ if (IS_SOCK_STREAM(type)) {
+ /*
+ * The socket family is not checked here since we accept local socket
+ * (AF_UNIX) that can NOT do outbound traffic.
+ */
goto end;
} else {
- if (domain == AF_INET || domain == AF_INET6) {
- /*
- * Print this message only in debug mode. Very often, applications
- * uses the libc to do DNS resolution which first tries with UDP
- * and then with TCP. It's not critical for the user to know that a
- * non TCP socket has been denied and since the libc has a fallback
- * that works, this message most of the time, simply polutes the
- * application's output which can cause issues with external
- * applications parsing the output.
- */
- DBG("Non TCP inet socket denied. Tor network can't handle it.");
- errno = EINVAL;
- return -1;
+ /*
+ * Non INET[6] socket can't be handle by tor else create the socket.
+ * The connect function will deny anything that Tor can NOT handle.
+ */
+ if (domain != AF_INET && domain != AF_INET6) {
+ goto end;
}
+
+ /*
+ * Print this message only in debug mode. Very often, applications uses
+ * the libc to do DNS resolution which first tries with UDP and then
+ * with TCP. It's not critical for the user to know that a non TCP
+ * socket has been denied and since the libc has a fallback that works,
+ * this message most of the time, simply polutes the application's
+ * output which can cause issues with external applications parsing the
+ * output.
+ */
+ DBG("IPv4/v6 non TCP socket denied. Tor network can't handle it.");
+ errno = EPERM;
+ return -1;
+
}
end:
diff --git a/tests/test_list b/tests/test_list
index 0c22c5e..d5f09ba 100644
--- a/tests/test_list
+++ b/tests/test_list
@@ -4,3 +4,4 @@
./unit/test_utils
./unit/test_config-file
./unit/test_socks5
+./unit/test_compat
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 3fd9c19..b85f910 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -11,7 +11,7 @@ LIBCOMMON=$(top_builddir)/src/common/libcommon.la
LIBTORSOCKS=$(top_builddir)/src/lib/libtorsocks.la
-noinst_PROGRAMS = test_onion test_connection test_utils test_config-file test_socks5
+noinst_PROGRAMS = test_onion test_connection test_utils test_config-file test_socks5 test_compat
EXTRA_DIST = fixtures
@@ -29,3 +29,6 @@ test_config_file_LDADD = $(LIBTAP) $(LIBCOMMON)
test_socks5_SOURCES = test_socks5.c
test_socks5_LDADD = $(LIBTAP) $(LIBCOMMON) $(LIBTORSOCKS)
+
+test_compat_SOURCES = test_compat.c
+test_compat_LDADD = $(LIBTAP) $(LIBCOMMON) $(LIBTORSOCKS)
diff --git a/tests/unit/test_compat.c b/tests/unit/test_compat.c
new file mode 100644
index 0000000..dec12c3
--- /dev/null
+++ b/tests/unit/test_compat.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 - David Goulet <dgoulet(a)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 <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+
+#include <common/compat.h>
+
+#include <tap/tap.h>
+
+#define NUM_TESTS 7
+
+static void test_socket_stream(void)
+{
+ int type, ret;
+
+ type = SOCK_STREAM;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 1, "Type SOCK_STREAM valid");
+
+ type = SOCK_STREAM | SOCK_NONBLOCK;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 1, "Type SOCK_STREAM | SOCK_NONBLOCK valid");
+
+ type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 1, "Type SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC valid");
+
+ type = SOCK_STREAM | 42;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 0, "Type SOCK_STREAM | 42 is NOT a stream socket");
+
+ type = SOCK_DGRAM;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 0, "Type SOCK_DGRAM is NOT a stream socket");
+
+ type = SOCK_DGRAM | SOCK_NONBLOCK;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 0, "Type SOCK_DGRAM | SOCK_NONBLOCK is NOT a stream socket");
+
+ type = SOCK_RAW;
+ ret = IS_SOCK_STREAM(type);
+ ok (ret == 0, "Type SOCK_RAW is NOT a stream socket");
+}
+
+int main(int argc, char **argv)
+{
+ /* Libtap call for the number of tests planned. */
+ plan_tests(NUM_TESTS);
+
+ test_socket_stream();
+
+ return 0;
+}
1
0
commit 4e142e770791c56d14af826a7a48d0a6f1bed44d
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 18:56:10 2014 -0400
Tests: add connect() test
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
.gitignore | 1 +
tests/Makefile.am | 5 ++-
tests/test_connect.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test_list | 1 +
4 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index c474007..cc74d05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@ doc/usewithtor.1
src/bin/torsocks
+tests/test_connect
tests/test_dns
tests/test_socket
tests/unit/test_onion
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ae3c2d1..141ac5e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,7 +6,7 @@ LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la
LIBTORSOCKS=$(top_builddir)/src/lib/libtorsocks.la
-noinst_PROGRAMS = test_dns test_socket
+noinst_PROGRAMS = test_dns test_socket test_connect
test_dns_SOURCES = test_dns.c
test_dns_LDADD = $(LIBTAP) $(LIBTORSOCKS)
@@ -14,6 +14,9 @@ test_dns_LDADD = $(LIBTAP) $(LIBTORSOCKS)
test_socket_SOURCES = test_socket.c
test_socket_LDADD = $(LIBTAP) $(LIBTORSOCKS)
+test_connect_SOURCES = test_connect.c
+test_connect_LDADD = $(LIBTAP) $(LIBTORSOCKS)
+
check-am:
./run.sh test_list
diff --git a/tests/test_connect.c b/tests/test_connect.c
new file mode 100644
index 0000000..705219d
--- /dev/null
+++ b/tests/test_connect.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 - David Goulet <dgoulet(a)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 <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+
+#include <lib/torsocks.h>
+
+#include <tap/tap.h>
+
+#define NUM_TESTS 8
+
+/* Suppress output messages. */
+int tsocks_loglevel = MSGNONE;
+//int tsocks_loglevel = MSGDEBUG;
+
+static void test_connect_deny(void)
+{
+ int fd, ret;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+
+ fd = tsocks_libc_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+ ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
+ ok (ret == -1 && errno == EBADF, "Connect with RAW socket NOT valid");
+ close(fd);
+
+ sin.sin_family = AF_INET;
+ fd = tsocks_libc_socket(sin.sin_family, SOCK_DGRAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
+ ok (ret == -1 && errno == EBADF, "Connect with UDP socket NOT valid");
+ close(fd);
+
+ inet_pton(sin.sin_family, "0.0.0.0", &sin.sin_addr);
+ fd = tsocks_libc_socket(sin.sin_family, SOCK_STREAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
+ ok (ret == -1 && errno == EINVAL,
+ "Connect with ANY address is NOT valid.");
+ close(fd);
+
+ inet_pton(sin.sin_family, "127.0.0.1", &sin.sin_addr);
+ fd = tsocks_libc_socket(sin.sin_family, SOCK_STREAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
+ ok (ret == -1 && errno == EPERM,
+ "Connect with local address is NOT valid.");
+ close(fd);
+
+ sin6.sin6_family = AF_INET6;
+ fd = tsocks_libc_socket(sin6.sin6_family, SOCK_DGRAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin6, sizeof(sin6));
+ ok (ret == -1 && errno == EBADF, "Connect with UDPv6 socket NOT valid");
+ close(fd);
+
+ inet_pton(sin6.sin6_family, "::", &sin6.sin6_addr);
+ fd = tsocks_libc_socket(sin6.sin6_family, SOCK_STREAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin6, sizeof(sin6));
+ ok (ret == -1 && errno == EINVAL,
+ "Connect with ANYv6 address is NOT valid.");
+ close(fd);
+
+ inet_pton(sin6.sin6_family, "::1", &sin6.sin6_addr);
+ fd = tsocks_libc_socket(sin6.sin6_family, SOCK_STREAM, 0);
+ ret = connect(fd, (struct sockaddr *) &sin6, sizeof(sin6));
+ ok (ret == -1 && errno == EPERM,
+ "Connect with local v6 address is NOT valid.");
+ close(fd);
+
+ /* Bad fd. */
+ ret = connect(42, NULL, 42);
+ ok (ret == -1 && errno == EBADF, "Bad socket FD");
+}
+
+int main(int argc, char **argv)
+{
+ /* Libtap call for the number of tests planned. */
+ plan_tests(NUM_TESTS);
+
+ test_connect_deny();
+
+ return 0;
+}
diff --git a/tests/test_list b/tests/test_list
index 542b93f..bb812b1 100644
--- a/tests/test_list
+++ b/tests/test_list
@@ -1,3 +1,4 @@
+./test_connect
./test_dns
./test_socket
./unit/test_onion
1
0

[torsocks/master] Fix: nullify constant that might be undefined
by dgoulet@torproject.org 04 Apr '14
by dgoulet@torproject.org 04 Apr '14
04 Apr '14
commit 62dab5b2ca9fc1a5e92d07feabf70851420de371
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 20:08:33 2014 -0400
Fix: nullify constant that might be undefined
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/common/compat.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/common/compat.h b/src/common/compat.h
index 87191f0..bda18f0 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -108,6 +108,19 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#define TSOCKS_ANY6 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
/*
+ * Both socket flags here are defined on some BSD and Linux but not on OS X so
+ * simply nullify them. Include socket.h so the constants are defined before we
+ * test them.
+ */
+#include <sys/socket.h>
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 0
+#endif
+
+/*
* Macro to tell if a given socket type is a SOCK_STREAM or not. The macro
* resolve to 1 if yes else 0.
*/
1
0

04 Apr '14
commit e70264869c19e0ff44ecf5898858af37e7a9fabd
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Thu Apr 3 17:36:01 2014 -0400
Fix: memory leak in connect error path
Fixes coverity issue 1072757.
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/lib/connect.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/lib/connect.c b/src/lib/connect.c
index 5ecb2ff..5e56e4e 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -105,7 +105,7 @@ error:
*/
LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
{
- int ret;
+ int ret, ret_errno;
struct connection *new_conn;
struct onion_entry *on_entry;
@@ -162,8 +162,8 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
new_conn->dest_addr.hostname.port = utils_get_port_from_addr(addr);
new_conn->dest_addr.hostname.addr = strdup(on_entry->hostname);
if (!new_conn->dest_addr.hostname.addr) {
- errno = ENOMEM;
- goto error;
+ ret_errno = ENOMEM;
+ goto error_free;
}
} else {
/*
@@ -189,8 +189,8 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
/* Connect the socket to the Tor network. */
ret = tsocks_connect_to_tor(new_conn);
if (ret < 0) {
- errno = -ret;
- goto error;
+ ret_errno = -ret;
+ goto error_free;
}
connection_registry_lock();
@@ -204,6 +204,14 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
libc_connect:
return tsocks_libc_connect(LIBC_CONNECT_ARGS);
+
+error_free:
+ /*
+ * Put back reference of newly created connection. Will be freed if
+ * refcount goes down to 0.
+ */
+ connection_put_ref(new_conn);
+ errno = ret_errno;
error:
/* At this point, errno MUST be set to a valid connect() error value. */
return -1;
1
0

04 Apr '14
commit aba207d0033ae149bfa19c2dfeb0823af6a2ebc3
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 19:55:47 2014 -0400
Refactor the connect() code flow for clarity
This adds a "validate_socket()" function that is called first to make
sure all criteria of a valid socket that torsocks can handle are met.
This has been done to have a single callsite that can do this validation
thus improving the clarity and flow of the code.
It now also returns EPERM for things that we deny instead of EINVAL or
EBADF. Because of that, the connect test has been changed to handle this
new errno value.
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/lib/connect.c | 95 ++++++++++++++++++++++++++++++++++++++------------
tests/test_connect.c | 12 +++----
2 files changed, 79 insertions(+), 28 deletions(-)
diff --git a/src/lib/connect.c b/src/lib/connect.c
index 0973e1e..5ecb2ff 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -30,51 +30,101 @@
TSOCKS_LIBC_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG)
/*
- * Torsocks call for connect(2).
+ * Validate the given sock fd and address that we receive in the connect()
+ * call. Criteria are:
+ *
+ * -) Non INET/INET6 socket should return to the libc, LIBC.
+ * -) Non stream socket can't be handled, DENY.
+ * -) Connection to the any address won't work with Tor, DENY.
+ * -) ALLOW.
+ *
+ * Return 0 if validation passes and socket handling should continue. Return 1
+ * if the socket can't be handle by Tor but is still valid thus the caller
+ * should send it directly to the libc connect function.
+ *
+ * On error or if validation fails, errno is set and -1 is returned. The caller
+ * should *return* right away an error.
*/
-LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
+static int validate_socket(int sockfd, const struct sockaddr *addr)
{
int ret, sock_type;
socklen_t optlen;
- struct connection *new_conn;
- struct onion_entry *on_entry;
- DBG("Connect catched on fd %d", sockfd);
+ if (!addr) {
+ /* Go directly to libc, connect() will handle a NULL value. */
+ goto libc_call;
+ }
+
+ /*
+ * We can't handle a non inet socket thus directly go to the libc. This is
+ * to allow AF_UNIX/_LOCAL socket to work with torsocks.
+ */
+ if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6) {
+ DBG("[conect] Connection is not IPv4/v6. Ignoring.");
+ /* Ask the call to use the libc connect. */
+ goto libc_call;
+ }
optlen = sizeof(sock_type);
ret = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
if (ret < 0) {
- /* Use the getsockopt() errno value. */
+ DBG("[connect] Fail getsockopt() on sock %d", sockfd);
+ errno = EBADF;
goto error;
}
- /* We can't handle a non inet socket. */
- if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6) {
- DBG("[conect] Connection is not IPv4/v6. Ignoring.");
- goto libc_connect;
- }
+ DBG("[connect] Socket family %s and type %d",
+ addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
- /*
- * Refuse non stream socket. There is a chance that this might be a DNS
- * request that we can't pass through Tor using raw UDP packet.
- */
+ /* Refuse non stream socket since Tor can't handle that. */
if (!IS_SOCK_STREAM(sock_type)) {
- WARN("[connect] UDP or ICMP stream can't be handled. Rejecting.");
- errno = EBADF;
+ DBG("[connect] UDP or ICMP stream can't be handled. Rejecting.");
+ errno = EPERM;
goto error;
}
/*
* Trying to connect to ANY address will evidently not work for Tor thus we
- * deny the call.
+ * deny the call with an invalid argument error.
*/
if (utils_is_addr_any(addr)) {
- errno = EINVAL;
+ errno = EPERM;
goto error;
}
- DBG("[connect] Socket family %s and type %d",
- addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
+ return 0;
+
+libc_call:
+ return 1;
+error:
+ return -1;
+}
+
+/*
+ * Torsocks call for connect(2).
+ */
+LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
+{
+ int ret;
+ struct connection *new_conn;
+ struct onion_entry *on_entry;
+
+ DBG("Connect catched on fd %d", sockfd);
+
+ /*
+ * Validate socket values in order to see if we can handle this connect
+ * through Tor.
+ */
+ ret = validate_socket(sockfd, addr);
+ if (ret == 1) {
+ /* Tor can't handle it so send it to the libc. */
+ goto libc_connect;
+ } else if (ret == -1) {
+ /* Validation failed. Stop right now. */
+ goto error;
+ }
+ /* Implicit else statement meaning we continue processing the connect. */
+ assert(!ret);
/*
* Lock registry to get the connection reference if one. In this code path,
@@ -118,7 +168,8 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
} else {
/*
* Check if address is localhost. At this point, we are sure it's not a
- * .onion cookie address that is by default in the loopback network.
+ * .onion cookie address that is by default in the loopback network
+ * thus this check is done after the onion entry lookup.
*/
if (utils_sockaddr_is_localhost(addr)) {
WARN("[connect] Connection to a local address are denied since it "
diff --git a/tests/test_connect.c b/tests/test_connect.c
index 705219d..a282255 100644
--- a/tests/test_connect.c
+++ b/tests/test_connect.c
@@ -36,7 +36,7 @@ static void test_connect_deny(void)
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
- fd = tsocks_libc_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+ fd = tsocks_libc_socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
ok (ret == -1 && errno == EBADF, "Connect with RAW socket NOT valid");
close(fd);
@@ -44,13 +44,13 @@ static void test_connect_deny(void)
sin.sin_family = AF_INET;
fd = tsocks_libc_socket(sin.sin_family, SOCK_DGRAM, 0);
ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
- ok (ret == -1 && errno == EBADF, "Connect with UDP socket NOT valid");
+ ok (ret == -1 && errno == EPERM, "Connect with UDP socket NOT valid");
close(fd);
inet_pton(sin.sin_family, "0.0.0.0", &sin.sin_addr);
fd = tsocks_libc_socket(sin.sin_family, SOCK_STREAM, 0);
ret = connect(fd, (struct sockaddr *) &sin, sizeof(sin));
- ok (ret == -1 && errno == EINVAL,
+ ok (ret == -1 && errno == EPERM,
"Connect with ANY address is NOT valid.");
close(fd);
@@ -64,13 +64,13 @@ static void test_connect_deny(void)
sin6.sin6_family = AF_INET6;
fd = tsocks_libc_socket(sin6.sin6_family, SOCK_DGRAM, 0);
ret = connect(fd, (struct sockaddr *) &sin6, sizeof(sin6));
- ok (ret == -1 && errno == EBADF, "Connect with UDPv6 socket NOT valid");
+ ok (ret == -1 && errno == EPERM, "Connect with UDPv6 socket NOT valid");
close(fd);
inet_pton(sin6.sin6_family, "::", &sin6.sin6_addr);
fd = tsocks_libc_socket(sin6.sin6_family, SOCK_STREAM, 0);
ret = connect(fd, (struct sockaddr *) &sin6, sizeof(sin6));
- ok (ret == -1 && errno == EINVAL,
+ ok (ret == -1 && errno == EPERM,
"Connect with ANYv6 address is NOT valid.");
close(fd);
@@ -82,7 +82,7 @@ static void test_connect_deny(void)
close(fd);
/* Bad fd. */
- ret = connect(42, NULL, 42);
+ ret = connect(42, (struct sockaddr *) &sin, 42);
ok (ret == -1 && errno == EBADF, "Bad socket FD");
}
1
0

04 Apr '14
commit dcbdeb2093e46e2a74293f03d15d8e202d322a06
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Thu Apr 3 17:40:23 2014 -0400
Fix: fix NULL dereference on error
Fixes coverity issue 1195182.
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/lib/torsocks.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index af4ab79..5734af1 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -192,7 +192,7 @@ static void init_libc_symbols(void)
libc_ptr = dlopen(LIBC_NAME, RTLD_LAZY);
if (!libc_ptr) {
ERR("Unable to dlopen() library " LIBC_NAME "(%s)", dlerror());
- goto error;
+ goto error_dlopen;
}
dlerror();
@@ -217,6 +217,7 @@ error:
if (ret != 0) {
ERR("dlclose: %s", dlerror());
}
+error_dlopen:
clean_exit(EXIT_FAILURE);
}
1
0
commit f4f9ee87e4ab0aec3ce683c9be0131e68da96688
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Mon Mar 31 21:23:51 2014 -0400
Delete old source directory
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src.old/Makefile.am | 18 -
src.old/common.c | 224 ---------
src.old/common.h | 104 -----
src.old/darwin_warts.c | 59 ---
src.old/dead_pool.c | 805 --------------------------------
src.old/dead_pool.h | 67 ---
src.old/expansion_table.h | 125 -----
src.old/parser.c | 872 -----------------------------------
src.old/parser.h | 69 ---
src.old/socks.c | 633 --------------------------
src.old/socks.h | 116 -----
src.old/torsocks.c | 1108 ---------------------------------------------
src.old/torsocks.in | 167 -------
src.old/usewithtor.in | 113 -----
14 files changed, 4480 deletions(-)
diff --git a/src.old/Makefile.am b/src.old/Makefile.am
deleted file mode 100644
index e3a01c9..0000000
--- a/src.old/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-# Makefile used by configure to create real Makefile
-
-libdir = @libdir@/torsocks
-
-# Install invocation scripts
-bin_SCRIPTS = torsocks usewithtor
-INSTALL_SCRIPT = $(install_sh) -c -m 755
-
-libtorsocks_la_LDFLAGS= $(TORSOCKSLDFLAGS)
-# Install main library to $(prefix)/lib/tor (must match torsocks.in)
-lib_LTLIBRARIES = libtorsocks.la
-libtorsocks_la_SOURCES = torsocks.c common.c parser.c dead_pool.c darwin_warts.c socks.c\
- common.h dead_pool.h expansion_table.h parser.h socks.h
-
-DISTCLEANFILES=parser.lo dead_pool.lo common.lo libtorsocks.lo torsocks.lo darwin_warts.lo socks.lo\
- config.cache config.log config.h Makefile \
- aclocal.m4 config.status usewithtor torsocks \
- autom4te.cache .libs .deps
diff --git a/src.old/common.c b/src.old/common.c
deleted file mode 100644
index 8fe3303..0000000
--- a/src.old/common.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- * *
- * Some code taken from Tor: *
- * Copyright (c) 2003, Roger Dingledine *
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. *
- * Copyright (c) 2007-2008, The Tor Project, Inc. *
- * *
- ***************************************************************************/
-/*
-
- commmon.c - Common routines for the torsocks package
-
-*/
-
-#include <config.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#include "common.h"
-
-/* Globals */
-int loglevel = MSGERR; /* The default logging level is to only log
- error messages */
-char logfilename[256]; /* Name of file to which log messages should
- be redirected */
-FILE *logfile = NULL; /* File to which messages should be logged */
-int logstamp = 0; /* Timestamp (and pid stamp) messages */
-
-
-/**
- * Read a 16-bit value beginning at <b>cp</b>. Equivalent to
- * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
- * unaligned memory access.
- */
-uint16_t
-get_uint16(const char *cp)
-{
- uint16_t v;
- memcpy(&v,cp,2);
- return v;
-}
-/**
- * Read a 32-bit value beginning at <b>cp</b>. Equivalent to
- * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
- * unaligned memory access.
- */
-uint32_t
-get_uint32(const char *cp)
-{
- uint32_t v;
- memcpy(&v,cp,4);
- return v;
-}
-/**
- * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
- * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
- * unaligned memory access. */
-void
-set_uint16(char *cp, uint16_t v)
-{
- memcpy(cp,&v,2);
-}
-/**
- * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
- * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
- * unaligned memory access. */
-void
-set_uint32(char *cp, uint32_t v)
-{
- memcpy(cp,&v,4);
-}
-
-unsigned int resolve_ip(char *host, int showmsg, int allownames) {
- struct hostent *new;
- unsigned int hostaddr;
- struct in_addr *ip;
-
- if ((hostaddr = inet_addr(host)) == (unsigned int) -1) {
- /* We couldn't convert it as a numerical ip so */
- /* try it as a dns name */
- if (allownames) {
- #ifdef HAVE_GETHOSTBYNAME
- if ((new = gethostbyname(host)) == (struct hostent *) 0) {
- #endif
- return(0);
- #ifdef HAVE_GETHOSTBYNAME
- } else {
- ip = ((struct in_addr *) * new->h_addr_list);
- hostaddr = ip -> s_addr;
- if (showmsg)
- printf("Connecting to %s...\n", inet_ntoa(*ip));
- }
- #endif
- } else
- return(0);
- }
-
- return (hostaddr);
-}
-
-/* Set logging options, the options are as follows: */
-/* level - This sets the logging threshold, messages with */
-/* a higher level (i.e lower importance) will not be */
-/* output. For example, if the threshold is set to */
-/* MSGWARN a call to log a message of level MSGDEBUG */
-/* would be ignored. This can be set to -1 to disable */
-/* messages entirely */
-/* filename - This is a filename to which the messages should */
-/* be logged instead of to standard error */
-/* timestamp - This indicates that messages should be prefixed */
-/* with timestamps (and the process id) */
-void set_log_options(int level, char *filename, int timestamp) {
-
- loglevel = level;
- if (loglevel < MSGERR)
- loglevel = MSGNONE;
-
- if (filename) {
- strncpy(logfilename, filename, sizeof(logfilename));
- logfilename[sizeof(logfilename) - 1] = '\0';
- }
-
- logstamp = timestamp;
-}
-
-/* Count the bits in a netmask. This is a little bit buggy; it assumes
- all the zeroes are on the right... */
-
-int count_netmask_bits(uint32_t mask)
-{
- int i;
- int nbits = 0;
-
- for(i=0; i<32; i++) {
- if((mask >> i) & 1) {
- nbits++;
- }
- }
- mask = ~mask;
- mask = ntohl(mask);
- if(mask & (mask+1)) {
- return -1; /* Noncontiguous */
- }
- return nbits;
-}
-
-void show_msg(int level, const char *fmt, ...) {
- va_list ap;
- int saveerr;
- extern char *torsocks_progname;
- char timestring[20];
- time_t timestamp;
-
- if ((loglevel == MSGNONE) || (level > loglevel))
- return;
-
- if (!logfile) {
- if (logfilename[0]) {
- logfile = fopen(logfilename, "a");
- if (logfile == NULL) {
- logfile = stderr;
- show_msg(MSGERR, "Could not open log file, %s, %s\n",
- logfilename, strerror(errno));
- }
- } else
- logfile = stderr;
- }
-
- if (logstamp) {
- timestamp = time(NULL);
- strftime(timestring, sizeof(timestring), "%H:%M:%S",
- localtime(×tamp));
- fprintf(logfile, "%s ", timestring);
- }
-
- fputs(torsocks_progname, logfile);
-
- if (logstamp) {
- fprintf(logfile, "(%d)", getpid());
- }
-
- fputs(": ", logfile);
-
- va_start(ap, fmt);
-
- /* Save errno */
- saveerr = errno;
-
- vfprintf(logfile, fmt, ap);
-
- fflush(logfile);
-
- errno = saveerr;
-
- va_end(ap);
-}
-
diff --git a/src.old/common.h b/src.old/common.h
deleted file mode 100644
index f84a2f7..0000000
--- a/src.old/common.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-
-/* Common functions provided in common.c */
-/* GCC has several useful attributes. */
-#include <sys/types.h>
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define ATTR_NORETURN __attribute__((noreturn))
-#define ATTR_PURE __attribute__((pure))
-#define ATTR_CONST __attribute__((const))
-#define ATTR_MALLOC __attribute__((malloc))
-#define ATTR_NORETURN __attribute__((noreturn))
-#define ATTR_NONNULL(x) __attribute__((nonnull x))
-/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be true. */
-#define PREDICT_LIKELY(exp) __builtin_expect((exp), 1)
-/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be false. */
-#define PREDICT_UNLIKELY(exp) __builtin_expect((exp), 0)
-#else
-#define ATTR_NORETURN
-#define ATTR_PURE
-#define ATTR_CONST
-#define ATTR_MALLOC
-#define ATTR_NORETURN
-#define ATTR_NONNULL(x)
-#define PREDICT_LIKELY(exp) (exp)
-#define PREDICT_UNLIKELY(exp) (exp)
-#endif
-
-/** Try to find the symbol that is either m or __m.
- * If one of them exists, in that order, then save its address in r,
- * otherwise we want to print a message at log level l stating that
- * we could not find it.
- */
-#define torsocks_find_library(m,l,r) \
- do { \
- char * dl_error_msg = ""; \
- char * dl_error_msg2 = ""; \
- dlerror(); \
- if ((r = dlsym(RTLD_NEXT, m)) == NULL) { \
- dl_error_msg = dlerror(); \
- if (dl_error_msg != NULL) { \
- dl_error_msg = strdup(dl_error_msg); \
- } \
- if ((r = dlsym(RTLD_NEXT, "__" m)) == NULL) { \
- dl_error_msg2 = dlerror(); \
- show_msg(l, "WARNING: The symbol %s() was not found in any shared " \
- "library with the reported error: %s!\n" \
- " Also, we failed to find the symbol %s() with the reported error:" \
- " %s\n", m, (dl_error_msg ? dl_error_msg : "Not Found"), \
- "__"m, (dl_error_msg2 ? dl_error_msg2 : "Not Found")); \
- } \
- if (dl_error_msg) \
- free(dl_error_msg); \
- } \
- } while (0)
-
-uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1));
-uint32_t get_uint32(const char *cp) ATTR_PURE ATTR_NONNULL((1));
-void set_uint16(char *cp, uint16_t v) ATTR_NONNULL((1));
-void set_uint32(char *cp, uint32_t v) ATTR_NONNULL((1));
-
-int is_internal_IP(uint32_t ip, int for_listening) ATTR_PURE;
-int parse_addr_port(int severity, const char *addrport, char **address,
- uint32_t *addr, uint16_t *port_out);
-
-void set_log_options(int, char *, int);
-void show_msg(int level, const char *, ...);
-int count_netmask_bits(uint32_t mask);
-unsigned int resolve_ip(char *, int, int);
-
-#define MSGNONE -1
-#define MSGERR 0
-#define MSGWARN 1
-#define MSGTEST 2
-#define MSGNOTICE 3
-#define MSGDEBUG 3
-
-/* Required by some BSDs */
-#ifndef MAP_ANONYMOUS
-#ifdef MAP_ANON
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-#endif
diff --git a/src.old/darwin_warts.c b/src.old/darwin_warts.c
deleted file mode 100644
index 65bdd04..0000000
--- a/src.old/darwin_warts.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2010 Alex Rosenberg <alex(a)ohmantics.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. *
- ***************************************************************************/
-
-/* Mac OS X 10.6 forces any function named "select" to be named "_select$1050"
- * in the output to the assembler. We need to patch select as well, so this
- * isolated code exists without tripping over the Darwin header that causes the
- * probkem.
- */
-
-#if defined(__APPLE__) || defined(__darwin__)
-
-#include <AvailabilityMacros.h>
-
-#if defined(MAC_OS_X_VERSION_10_6)
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <string.h>
-#include <errno.h>
-#include "common.h"
-
-#define SELECT_SIGNATURE int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout
-#define SELECT_ARGNAMES n, readfds, writefds, exceptfds, timeout
-
-/* forward declare opaque structures instead of bringing in real Darwin decls. */
-typedef struct fd_set fd_set;
-struct timeval;
-
-int (*realselect)(SELECT_SIGNATURE);
-int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE));
-
-int select(SELECT_SIGNATURE) {
- if (!realselect) {
- torsocks_find_library("select", MSGERR, realselect);
- }
- return torsocks_select_guts(SELECT_ARGNAMES, realselect);
-}
-
-#endif /* 10.6 */
-#endif /* darwin */
diff --git a/src.old/dead_pool.c b/src.old/dead_pool.c
deleted file mode 100644
index 13e5740..0000000
--- a/src.old/dead_pool.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2005 Total Information Security Ltd. *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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 <stdio.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include "common.h"
-#include "dead_pool.h"
-
-int store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr);
-void get_next_dead_address(dead_pool *pool, uint32_t *result);
-
-static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
- uint32_t *result_addr, const void *addr,
- int version, int reverse, char **result_hostname);
-
-/* Compares the last strlen(s2) characters of s1 with s2. Returns as for
- strcasecmp. */
-static int
-strcasecmpend(const char *s1, const char *s2)
-{
- size_t n1 = strlen(s1), n2 = strlen(s2);
- if (n2>n1) /* then they can't be the same; figure out which is bigger */
- return strcasecmp(s1,s2);
- else
- return strncasecmp(s1+(n1-n2), s2, n2);
-}
-
-dead_pool *
-init_pool(unsigned int pool_size, struct in_addr deadrange_base,
- struct in_addr deadrange_mask, char *sockshost, uint16_t socksport)
-{
- unsigned int i, deadrange_size, deadrange_width;
- int deadrange_bits;
- struct in_addr socks_server;
- dead_pool *newpool = NULL;
-
- /* Count bits in netmask and determine deadrange width. */
- deadrange_bits = count_netmask_bits(deadrange_mask.s_addr);
- if(deadrange_bits == -1) {
- show_msg(MSGERR, "init_pool: invalid netmask for deadrange\n");
- return NULL;
- }
- deadrange_width = 32 - deadrange_bits;
-
- show_msg(MSGDEBUG, "deadrange width is %d bits\n", deadrange_width);
-
- /* Now work out how many IPs are available in the deadrange and check
- that this number makes sense. If the deadpool is bigger than the
- deadrange we shrink the pool. */
-
- for(i=0, deadrange_size = 1; i < deadrange_width; i++) {
- deadrange_size *= 2;
- }
-
- if(deadrange_size < pool_size) {
- show_msg(MSGWARN, "tordns cache size was %d, but deadrange size is %d: "
- "shrinking pool size to %d entries\n", pool_size,
- deadrange_size, deadrange_size);
- pool_size = deadrange_size;
- }
- if(pool_size < 1) {
- show_msg(MSGERR, "tordns cache size is 0, disabling tordns\n");
- return NULL;
- }
-
- /* Allocate space for the dead_pool structure */
- newpool = (dead_pool *) mmap(0, sizeof(dead_pool),
- PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if(!newpool) {
- show_msg(MSGERR, "init_pool: unable to mmap deadpool "
- "(tried to map %d bytes)\n", sizeof(dead_pool));
- return NULL;
- }
-
- show_msg(MSGDEBUG, "init_pool: sockshost %s \n", sockshost);
-
- /* Initialize the dead_pool structure */
-#ifdef HAVE_INET_ATON
- inet_aton(sockshost, &socks_server);
-#elif defined(HAVE_INET_ADDR)
- socks_server.s_addr = inet_addr(sockshost);
-#endif
- newpool->sockshost = ntohl(socks_server.s_addr);
- newpool->socksport = socksport;
- newpool->deadrange_base = ntohl(deadrange_base.s_addr);
- newpool->deadrange_mask = ntohl(deadrange_mask.s_addr);
- newpool->deadrange_size = deadrange_size;
- newpool->write_pos = 0;
- newpool->dead_pos = 0;
- newpool->n_entries = pool_size;
-
- /* Allocate space for the entries */
- newpool->entries = (pool_ent *) mmap(0, newpool->n_entries * sizeof(pool_ent),
- PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if(!newpool->entries) {
- munmap((void *)newpool, sizeof(dead_pool));
- show_msg(MSGERR, "init_pool: unable to mmap deadpool entries "
- "(tried to map %d bytes)\n",
- newpool->n_entries * sizeof(pool_ent));
- return NULL;
- }
-
- /* Initialize the entries */
- for(i=0; i < newpool->n_entries; i++) {
- newpool->entries[i].ip = -1;
- newpool->entries[i].name[0] = '\0';
- }
-
- return newpool;
-}
-
-int
-is_dead_address(dead_pool *pool, uint32_t addr)
-{
- uint32_t haddr = ntohl(addr);
- if(pool == NULL) {
- return 0;
- }
- return (pool->deadrange_base == (haddr & pool->deadrange_mask));
-}
-
-void
-get_next_dead_address(dead_pool *pool, uint32_t *result)
-{
- *result = htonl(pool->deadrange_base + pool->dead_pos++);
- if(pool->dead_pos >= pool->deadrange_size) {
- pool->dead_pos = 0;
- }
-}
-
-int
-store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr)
-{
- int position = pool->write_pos;
- int oldpos;
- int rc;
- uint32_t intaddr;
- char *result_hostname;
-
- show_msg(MSGDEBUG, "store_pool_entry: storing '%s'\n", hostname);
- show_msg(MSGDEBUG, "store_pool_entry: write pos is: %d\n", pool->write_pos);
-
- /* Check to see if name already exists in pool */
- oldpos = search_pool_for_name(pool, hostname);
- if(oldpos != -1){
- show_msg(MSGDEBUG, "store_pool_entry: not storing (entry exists)\n");
- addr->s_addr = pool->entries[oldpos].ip;
- return oldpos;
- }
-
- /* If this is a .onion host, then we return a bogus ip from our deadpool,
- otherwise we try to resolve it and store the 'real' IP */
- if(strcasecmpend(hostname, ".onion") == 0) {
- get_next_dead_address(pool, &pool->entries[position].ip);
- } else {
- rc = do_resolve(hostname, pool->sockshost, pool->socksport, &intaddr, 0,
- 4 /*SOCKS5*/, 0 /*Reverse*/, &result_hostname);
-
- if(rc != 0) {
- show_msg(MSGWARN, "failed to resolve: %s\n", hostname);
- return -1;
- }
- if(is_dead_address(pool, intaddr)) {
- show_msg(MSGERR, "resolved %s -> %d (deadpool address) IGNORED\n");
- return -1;
- }
- pool->entries[position].ip = intaddr;
- }
-
- strncpy(pool->entries[position].name, hostname, 255);
- pool->entries[position].name[255] = '\0';
- pool->write_pos++;
- if(pool->write_pos >= pool->n_entries) {
- pool->write_pos = 0;
- }
- addr->s_addr = pool->entries[position].ip;
-
- show_msg(MSGDEBUG, "store_pool_entry: stored entry in slot '%d'\n", position);
-
- return position;
-}
-
-int
-search_pool_for_name(dead_pool *pool, const char *name)
-{
- unsigned int i;
- for(i=0; i < pool->n_entries; i++){
- if(strcmp(name, pool->entries[i].name) == 0){
- return i;
- }
- }
- return -1;
-}
-
-char *
-get_pool_entry(dead_pool *pool, struct in_addr *addr)
-{
- unsigned int i;
- uint32_t intaddr = addr->s_addr;
-
- if(pool == NULL) {
- return NULL;
- }
-
- show_msg(MSGDEBUG, "get_pool_entry: searching for: %s\n", inet_ntoa(*addr));
- for(i=0; i<pool->n_entries; i++) {
- if(intaddr == pool->entries[i].ip) {
- show_msg(MSGDEBUG, "get_pool_entry: found: %s\n", pool->entries[i].name);
- return pool->entries[i].name;
- }
- }
- show_msg(MSGDEBUG, "get_pool_entry: address not found\n");
-
- return NULL;
-}
-
-static int
-build_socks4a_resolve_request(char **out,
- const char *username,
- const char *hostname)
-{
- size_t len;
- uint16_t port = htons(0); /* port: 0. */
- uint32_t addr = htonl(0x00000001u); /* addr: 0.0.0.1 */
-
- len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
- *out = malloc(len);
- (*out)[0] = 4; /* SOCKS version 4 */
- (*out)[1] = '\xF0'; /* Command: resolve. */
-
- memcpy((*out)+2, &port, sizeof(port));
- memcpy((*out)+4, &addr, sizeof(addr));
- strcpy((*out)+8, username);
- strcpy((*out)+8+strlen(username)+1, hostname);
-
- return len;
-}
-
-static int
-build_socks5_resolve_ptr_request(char **out, const void *_addr)
-{
- size_t len;
- const struct in_addr *addr=_addr;
-
- len = 12;
- *out = malloc(len);
- (*out)[0] = 5; /* SOCKS version 5 */
- (*out)[1] = '\xF1'; /* Command: reverse resolve.
- see doc/socks-extensions.txt*/
- (*out)[2] = '\x00'; /* RSV */
- (*out)[3] = '\x01'; /* ATYP: IP V4 address: X'01' */
-
- set_uint32((*out)+4, addr->s_addr);/*IP*/
- set_uint16((*out)+4+4, 0); /* port */
-
- return len;
-}
-
-#define RESPONSE_LEN 8
-#define SOCKS5_LEN 4
-#define METHODRESPONSE_LEN 2
-
-static int
-parse_socks4a_resolve_response(const char *response, size_t len,
- uint32_t *addr_out)
-{
- uint8_t status;
- uint16_t port;
-
- if (len < RESPONSE_LEN) {
- show_msg(MSGWARN,"Truncated socks response.\n");
- return -1;
- }
- if (((uint8_t)response[0])!=0) { /* version: 0 */
- show_msg(MSGWARN,"Nonzero version in socks response: bad format.\n");
- return -1;
- }
- status = (uint8_t)response[1];
-
- memcpy(&port, response+2, sizeof(port));
- if (port!=0) { /* port: 0 */
- show_msg(MSGWARN,"Nonzero port in socks response: bad format.\n");
- return -1;
- }
- if (status != 90) {
- show_msg(MSGWARN,"Bad status: socks request failed.\n");
- return -1;
- }
-
- memcpy(addr_out, response+4, sizeof(*addr_out));
-
- return 0;
-}
-
-static int
-parse_socks5_resolve_ptr_response(int s,const char *response, size_t len,
- uint32_t *result_addr, char ***result_hostname)
-{
- char reply_buf[4];
- int r;
-
- len=0;
- while (len < SOCKS5_LEN) {
- r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n");
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading SOCKS5 response\n");
- return -1;
- }
- len += r;
- }
-
- if (reply_buf[0] != 5) {
- show_msg(MSGWARN, "Bad SOCKS5 reply version.");
- return -1;
- }
- if (reply_buf[1] != 0) {
- show_msg(MSGWARN,"Got status response '%u': SOCKS5 request failed.",
- (unsigned)reply_buf[1]);
- return -1;
- }
- if (reply_buf[3] == 1) {
- /* IPv4 address */
- len=0;
- while (len < SOCKS5_LEN) {
- r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n");
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading address in SOCKS5 response\n");
- return -1;
- }
- len += r;
- }
- *result_addr = ntohl(get_uint32(reply_buf));
- } else if (reply_buf[3] == 3) {
- size_t result_len;
- len=0;
- while (len < 1) {
- r = recv(s, reply_buf+len, 1-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n");
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading address length in SOCKS5 response\n");
- return -1;
- }
- len += r;
- }
- result_len = *(uint8_t*)(reply_buf);
- **result_hostname = malloc(result_len+1);
- len=0;
- while (len < (int) result_len) {
- r = recv(s, **result_hostname+len, result_len-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n");
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading hostname in SOCKS5 response\n");
- return -1;
- }
- len += r;
- }
-
- (**result_hostname)[result_len] = '\0';
- }
-
- return 0;
-}
-
-static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
- uint32_t *result_addr, const void *addr,
- int version, int reverse, char **result_hostname)
-{
- int s;
- struct sockaddr_in socksaddr;
- char *req, *cp=NULL;
- int r, len, hslen;
- char response_buf[RESPONSE_LEN];
- const char *handshake="\x05\x01\x00";
-
- show_msg(MSGDEBUG, "do_resolve: resolving %s\n", hostname);
-
- /* Create SOCKS connection */
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s<0) {
- show_msg(MSGWARN, "do_resolve: problem creating socket\n");
- return -1;
- }
-
- /* Connect to SOCKS server */
- memset(&socksaddr, 0, sizeof(socksaddr));
- socksaddr.sin_family = AF_INET;
- socksaddr.sin_port = htons(socksport);
- socksaddr.sin_addr.s_addr = htonl(sockshost);
- if (realconnect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
- show_msg(MSGWARN, "do_resolve: error connecting to SOCKS server\n");
- realclose(s);
- return -1;
- }
-
- /* If a SOCKS5 connection, perform handshake */
- if (version == 5) {
- char method_buf[2];
- hslen=3;
- while (hslen) {
- r = send(s, handshake, hslen, 0);
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error sending SOCKS5 method list.\n");
- realclose(s);
- return -1;
- }
- hslen -= r;
- handshake += r;
- }
-
- len = 0;
- while (len < METHODRESPONSE_LEN) {
- r = recv(s, method_buf+len, METHODRESPONSE_LEN-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
- realclose(s);
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
- realclose(s);
- return -1;
- }
- len += r;
- }
-
- if (method_buf[0] != '\x05') {
- show_msg(MSGWARN, "Unrecognized socks version: %u",
- (unsigned)method_buf[0]);
- realclose(s);
- return -1;
- }
- if (method_buf[1] != '\x00') {
- show_msg(MSGWARN, "Unrecognized socks authentication method: %u",
- (unsigned)method_buf[1]);
- realclose(s);
- return -1;
- }
- }
-
- /* Create SOCKS request */
- if (reverse) {
- if ((len = build_socks5_resolve_ptr_request(&req, addr))<0) {
- show_msg(MSGWARN, "do_resolve: error generating reverse SOCKS request\n");
- realclose(s);
- return -1;
- }
- }else{
- if ((len = build_socks4a_resolve_request(&req, "", hostname))<0) {
- show_msg(MSGWARN, "do_resolve: error generating SOCKS request\n");
- realclose(s);
- return -1;
- }
- }
-
- /* Send SOCKS request */
- cp = req;
- while (len) {
- r = send(s, cp, len, 0);
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error sending SOCKS request\n");
- free(req);
- realclose(s);
- return -1;
- }
- len -= r;
- cp += r;
- }
- free(req);
-
- /* Handle SOCKS Response */
- if (reverse) {
- if (parse_socks5_resolve_ptr_response(s, response_buf, RESPONSE_LEN,
- result_addr, &result_hostname) < 0){
- show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
- realclose(s);
- return -1;
- }
- }else{
- /* Process SOCKS response */
- len = 0;
- while (len < RESPONSE_LEN) {
- r = recv(s, response_buf+len, RESPONSE_LEN-len, 0);
- if (r==0) {
- show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
- realclose(s);
- return -1;
- }
- if (r<0) {
- show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
- realclose(s);
- return -1;
- }
- len += r;
- }
- realclose(s);
-
- /* Parse SOCKS response */
- if (parse_socks4a_resolve_response(response_buf, RESPONSE_LEN, result_addr) < 0){
- show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
- return -1;
- }
- }
-
-
- show_msg(MSGDEBUG, "do_resolve: success\n");
-
- return 0;
-}
-
-struct hostent *
-our_gethostbyaddr(dead_pool *pool, const void *_addr, socklen_t len, int type)
-{
- const struct in_addr *addr=_addr;
- static struct hostent he;
- uint32_t intaddr=0;
- char *result_hostname=NULL;
- int rc=0;
- static char *addrs[2];
- static char *aliases[2];
-
- rc = do_resolve("", pool->sockshost, pool->socksport, &intaddr, addr,
- 5 /*SOCKS5*/, 1 /*Reverse*/, &result_hostname);
-
-
- if(rc != 0) {
- show_msg(MSGWARN, "failed to reverse resolve: %s\n",
- inet_ntoa(*((struct in_addr *)addr)));
- result_hostname=NULL;
- addrs[0] = NULL;
- addrs[1] = NULL;
- }else{
- addrs[0] = (char *)addr;
- addrs[1] = NULL;
- }
-
- if (result_hostname)
- he.h_name = result_hostname;
- else
- he.h_name = inet_ntoa(*((struct in_addr *)addr));
-
- aliases[0] = NULL;
- aliases[1] = NULL;
-
- he.h_aliases = aliases;
- he.h_length = len;
- he.h_addrtype = type;
- he.h_addr_list = addrs;
-
- if (result_hostname)
- show_msg(MSGTEST, "our_gethostbyaddr: resolved '%s' to: '%s'\n",
- inet_ntoa(*((struct in_addr *)he.h_addr)), result_hostname);
-
- return &he;
-
-}
-
-struct hostent *
-our_gethostbyname(dead_pool *pool, const char *name)
-{
- int pos;
- static struct in_addr addr;
- static struct hostent he;
- static char *addrs[2];
-
- show_msg(MSGTEST, "our_gethostbyname: '%s' requested\n", name);
-
- pos = store_pool_entry(pool,(char *) name, &addr);
- if(pos == -1) {
- h_errno = HOST_NOT_FOUND;
- return NULL;
- }
-
- addrs[0] = (char *)&addr;
- addrs[1] = NULL;
-
- he.h_name = pool->entries[pos].name;
- he.h_aliases = NULL;
- he.h_length = 4;
- he.h_addrtype = AF_INET;
- he.h_addr_list = addrs;
-
- show_msg(MSGDEBUG, "our_gethostbyname: resolved '%s' to: '%s'\n",
- name, inet_ntoa(*((struct in_addr *)he.h_addr)));
-
- return &he;
-}
-
-static struct hostent *
-alloc_hostent(int af)
-{
- struct hostent *he = NULL;
- char **addr_list = NULL;
- void *addr = NULL;
- char **aliases = NULL;
-
- if(af != AF_INET && af != AF_INET6) {
- return NULL;
- }
-
- /* Since the memory we allocate here will be free'd by freehostent and
- that function is opaque to us, it's likely that we'll leak a little
- bit of memory here. */
-
- he = malloc(sizeof(struct hostent));
- addr_list = malloc(2 * sizeof(char *));
- if(af == AF_INET6) {
- addr = malloc(sizeof(struct in6_addr));
- } else {
- addr = malloc(sizeof(struct in_addr));
- }
- aliases = malloc(sizeof(char *));
-
- if(he == NULL || addr_list == NULL || addr == NULL || aliases == NULL) {
- if(he)
- free(he);
- if(addr_list)
- free(addr_list);
- if(addr)
- free(addr);
- if(aliases)
- free(aliases);
- }
-
- he->h_name = NULL;
- he->h_addr_list = addr_list;
- he->h_addr_list[0] = addr;
- he->h_addr_list[1] = NULL;
- he->h_aliases = aliases;
- he->h_aliases[0] = NULL;
- he->h_length = af == AF_INET ? 4 : 16;
- he->h_addrtype = af;
-
- return he;
-}
-
-/* On Linux, there's no freehostent() anymore; we might as well implement
- this ourselves. */
-
-static void
-free_hostent(struct hostent *he)
-{
- int i;
- if(he->h_name) {
- free(he->h_name);
- }
- if(he->h_aliases) {
- for(i=0; he->h_aliases[i] != NULL; i++) {
- free(he->h_aliases[i]);
- }
- free(he->h_aliases);
- }
- if(he->h_addr_list) {
- free(he->h_addr_list);
- }
- free(he);
-}
-
-int
-our_getaddrinfo(dead_pool *pool, const char *node, const char *service,
- void *hints, void *res)
-{
- int pos;
- struct in_addr addr;
- char *ipstr;
- int ret;
-
- /* If "node" looks like a dotted-decimal ip address, then just call
- the real getaddrinfo; otherwise we'll need to get an address from
- our pool. */
-
- /* TODO: work out what to do with AF_INET6 requests */
-
-#ifdef HAVE_INET_ATON
- if(node && inet_aton(node, &addr) == 0 && memcmp(node,"*",1)) {
-#elif defined(HAVE_INET_ADDR)
- /* If we're stuck with inet_addr, then getaddrinfo() won't work
- properly with 255.255.255.255 (= -1). There's not much we can
- do about this */
- in_addr_t is_valid;
- is_valid = inet_addr(node);
- if(is_valid == -1) {
-#endif
- pos = store_pool_entry(pool, (char *) node, &addr);
- if(pos == -1) {
- return EAI_NONAME;
- } else {
- ipstr = strdup(inet_ntoa(addr));
- ret = realgetaddrinfo(ipstr, service, hints, res);
- free(ipstr);
- }
- } else {
- ret = realgetaddrinfo(node, service, hints, res);
- }
-
- show_msg(MSGTEST, "our_getaddrinfo: '%s' requested\n", service);
- return ret;
-}
-
-struct hostent *
-our_getipnodebyname(dead_pool *pool, const char *name, int af, int flags,
- int *error_num)
-{
- int pos;
- struct hostent *he = NULL;
- int want_4in6 = 0;
- char addr_convert_buf[80];
- struct in_addr pool_addr;
-
- if(af == AF_INET6) {
- /* Caller has requested an AF_INET6 address, and is not prepared to
- accept IPv4-mapped IPV6 addresses. There's nothing we can do to
- service their request. */
-#ifdef OPENBSD
- /* OpenBSD doesn't support the AI_V4MAPPED flag, so just return. */
- return NULL;
-#else
- if((flags & AI_V4MAPPED) == 0) {
- show_msg(MSGWARN, "getipnodebyname: asked for V6 addresses only, "
- "but torsocks can't handle that\n");
- *error_num = NO_RECOVERY;
- return NULL;
- } else {
- want_4in6 = 1;
- }
-#endif
- }
-
- pos = store_pool_entry(pool, (char *)name, &pool_addr);
- if(pos == -1) {
- *error_num = HOST_NOT_FOUND;
- return NULL;
- }
-
- he = alloc_hostent(af);
- if(he == NULL) {
- show_msg(MSGERR, "getipnodebyname: failed to allocate hostent\n");
- *error_num = NO_RECOVERY;
- return NULL;
- }
-
- if(want_4in6) {
- /* Convert the ipv4 address in *addr to an IPv4 in IPv6 mapped
- address. TODO: inet_ntoa() is thread-safe on Solaris but might
- not be on other platforms. */
- strcpy(addr_convert_buf, "::FFFF:");
- strcpy(addr_convert_buf+7, inet_ntoa(pool_addr));
- if(inet_pton(AF_INET6, addr_convert_buf, he->h_addr_list[0]) != 1) {
- show_msg(MSGERR, "getipnodebyname: inet_pton() failed!\n");
- free_hostent(he);
- *error_num = NO_RECOVERY;
- return NULL;
- }
- } else {
- ((struct in_addr *) he->h_addr_list[0])->s_addr = pool_addr.s_addr;
- }
- he->h_name = strdup(name);
-
- return he;
-}
-
-
diff --git a/src.old/dead_pool.h b/src.old/dead_pool.h
deleted file mode 100644
index d6e3e10..0000000
--- a/src.old/dead_pool.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2005 Total Information Security Ltd. *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-
-#ifndef _DEAD_POOL_H
-#define _DEAD_POOL_H
-
-#include <config.h>
-
-extern int (*realconnect)(CONNECT_SIGNATURE);
-extern int (*realclose)(CLOSE_SIGNATURE);
-extern int (*realgetaddrinfo)(GETADDRINFO_SIGNATURE);
-
-struct struct_pool_ent {
- unsigned int ip;
- char name[256];
-};
-
-typedef struct struct_pool_ent pool_ent;
-
-struct struct_dead_pool {
- pool_ent *entries; /* Points to array of pool entries */
- unsigned int n_entries; /* Number of entries in the deadpool */
- unsigned int deadrange_base; /* Deadrange start IP in host byte order */
- unsigned int deadrange_mask; /* Deadrange netmask in host byte order */
- unsigned int deadrange_size; /* Number of IPs in the deadrange */
- unsigned int write_pos; /* Next position to use in the pool array */
- unsigned int dead_pos; /* Next 'unused' deadpool IP */
- uint32_t sockshost;
- uint16_t socksport;
- char pad[2];
-};
-
-typedef struct struct_dead_pool dead_pool;
-
-dead_pool *init_pool(unsigned int deadpool_size, struct in_addr deadrange_base,
- struct in_addr deadrange_mask, char *sockshost, uint16_t socksport);
-int is_dead_address(dead_pool *pool, uint32_t addr);
-char *get_pool_entry(dead_pool *pool, struct in_addr *addr);
-int search_pool_for_name(dead_pool *pool, const char *name);
-struct hostent *our_gethostbyname(dead_pool *pool, const char *name);
-struct hostent *our_gethostbyaddr(dead_pool *pool, const void *addr,
- socklen_t len, int type);
-int our_getaddrinfo(dead_pool *pool, const char *node, const char *service,
- void *hints, void *res);
-struct hostent *our_getipnodebyname(dead_pool *pool, const char *name,
- int af, int flags, int *error_num);
-
-#endif /* _DEAD_POOL_H */
-
diff --git a/src.old/expansion_table.h b/src.old/expansion_table.h
deleted file mode 100644
index 14fabe1..0000000
--- a/src.old/expansion_table.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2010 Alex Rosenberg <alex(a)ohmantics.net> *
- * Copyright (C) 2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-
-#undef FUNC
-#undef FUNCD
-#undef FUND32
-#undef FUNCD64
-
-#ifdef SUPPORT_RES_API
-#define RES_FUNC FUNC
-#define RES_FUNCD FUNCD
-#define RES_FUNCD32 FUNCD32
-#define RES_FUNCD64 FUNCD64
-#else
-#define RES_FUNC EMPTY_FUNC
-#define RES_FUNCD EMPTY_FUNC
-#define RES_FUNCD32 EMPTY_FUNC
-#define RES_FUNCD64 EMPTY_FUNC
-#endif /* SUPPORT_RES_API */
-
-#define DNS_FUNC FUNC
-#define DNS_FUNCD FUNCD
-#define DNS_FUNCD32 FUNCD32
-#define DNS_FUNCD64 FUNCD64
-
-#define EMPTY_FUNC(e,r,s,n,b,m)
-
-#if defined(__APPLE__) || defined(__darwin__)
-#ifndef DARWIN_EXPANSION
-#define DARWIN_EXPANSION PATCH_TABLE_EXPANSION
-#endif /* DARWIN_EXPANSION */
-#define FUNCD(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m)
-#if (__LP64__)
-#define FUNCD32(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m)
-/* This tests if we're building with 10.6 or later headers, not
- if we're running on 10.6. We'd rather do the latter. */
-#ifdef MAC_OS_X_VERSION_10_6
-#define FUNCD64_106(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m)
-#else
-#define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* MAC_OS_X_VERSION_10_6 */
-#else
-#define FUNCD32(e,r,s,n,b,m) DARWIN_EXPANSION(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* (__LP64__) */
-#else
-#define FUNCD(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD32(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64_106(e,r,s,n,b,m) EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* defined(__APPLE__) || defined(__darwin__) */
-#define FUNC(e,r,s,n,b,m) PATCH_TABLE_EXPANSION(e,r,s,n,b,m)
-
-/* dlsym return type SIG/ARGS C name base name asm name */
-/* res_init takes void, so we do that one manually. */
-/*RES_FUNC (ERR, int, RES_INIT_, res_init, res_init, "res_init") */
-RES_FUNC (ERR, int, RES_QUERY_, res_query, res_query, "res_query")
-RES_FUNC (ERR, int, RES_SEARCH_, res_search, res_search, "res_search")
-RES_FUNC (ERR, int, RES_SEND_, res_send, res_send, "res_send")
-RES_FUNC (ERR, int, RES_QUERYDOMAIN_, res_querydomain, res_querydomain, "res_querydomain")
-
-DNS_FUNC (ERR, struct hostent *, GETHOSTBYNAME_, gethostbyname, gethostbyname, "gethostbyname")
-DNS_FUNC (ERR, struct hostent *, GETHOSTBYADDR_, gethostbyaddr, gethostbyaddr, "gethostbyaddr")
-DNS_FUNC (ERR, int, GETADDRINFO_, getaddrinfo, getaddrinfo, "getaddrinfo")
-/* getipnodebyname is deprecated so do not report an error if it is not available.*/
-DNS_FUNC (WARN, struct hostent *, GETIPNODEBYNAME_, getipnodebyname, getipnodebyname, "getipnodebyname")
-
-DNS_FUNC (ERR, ssize_t, SENDTO_, sendto, sendto, "sendto")
-DNS_FUNCD32 (ERR, ssize_t, SENDTO_, sendto_unix2003, sendto, "sendto$UNIX2003")
-DNS_FUNCD32 (ERR, ssize_t, SENDTO_, sendto_nocancel_unix2003, sendto, "sendto$NOCANCEL$UNIX2003")
-DNS_FUNCD64 (ERR, ssize_t, SENDTO_, sendto_nocancel, sendto, "sendto$NOCANCEL")
-
-DNS_FUNC (ERR, ssize_t, SENDMSG_, sendmsg, sendmsg, "sendmsg")
-DNS_FUNCD32 (ERR, ssize_t, SENDMSG_, sendmsg_unix2003, sendmsg, "sendmsg$UNIX2003")
-DNS_FUNCD32 (ERR, ssize_t, SENDMSG_, sendmsg_nocancel_unix2003, sendmsg, "sendmsg$NOCANCEL$UNIX2003")
-DNS_FUNCD64 (ERR, ssize_t, SENDMSG_, sendmsg_nocancel, sendmsg, "sendmsg$NOCANCEL")
-
-FUNC (ERR, int, CONNECT_, connect, connect, "connect")
-FUNCD32 (ERR, int, CONNECT_, connect_unix2003, connect, "connect$UNIX2003")
-FUNCD32 (ERR, int, CONNECT_, connect_nocancel_unix2003, connect, "connect$NOCANCEL$UNIX2003")
-FUNCD64 (ERR, int, CONNECT_, connect_nocancel, connect, "connect$NOCANCEL")
-
-#if !(defined(__APPLE__) || defined(__darwin__) && defined(MAX_OS_X_VERSION_10_6))
-/* see darwin_warts.c */
-FUNC (ERR, int, SELECT_, select, select, "select")
-#endif
-FUNCD (ERR, int, SELECT_, select_darwinextsn, select, "select$DARWIN_EXTSN")
-FUNCD (ERR, int, SELECT_, select_darwinextsn_nocancel, select, "select$DARWIN_EXTSN$NOCANCEL")
-FUNCD32 (ERR, int, SELECT_, select_unix2003, select, "select$UNIX2003")
-FUNCD32 (ERR, int, SELECT_, select_nocancel_unix2003, select, "select$NOCANCEL$UNIX2003")
-FUNCD64 (ERR, int, SELECT_, select_nocancel, select, "select$NOCANCEL")
-FUNCD64_106 (ERR, int, SELECT_, select_1050, select, "select$1050")
-
-FUNC (ERR, int, POLL_, poll, poll, "poll")
-FUNCD32 (ERR, int, POLL_, poll_unix2003, poll, "poll$UNIX2003")
-FUNCD32 (ERR, int, POLL_, poll_nocancel_unix2003, poll, "poll$NOCANCEL$UNIX2003")
-FUNCD64 (ERR, int, POLL_, poll_nocancel, poll, "poll$NOCANCEL")
-
-FUNC (ERR, int, CLOSE_, close, close, "close")
-FUNCD32 (ERR, int, CLOSE_, close_unix2003, close, "close$UNIX2003")
-FUNCD32 (ERR, int, CLOSE_, close_nocancel_unix2003, close, "close$NOCANCEL$UNIX2003")
-FUNCD64 (ERR, int, CLOSE_, close_nocancel, close, "close$NOCANCEL")
-
-FUNC (ERR, int, GETPEERNAME_, getpeername, getpeername, "getpeername")
-FUNCD32 (ERR, int, GETPEERNAME_, getpeername_unix2003, getpeername, "getpeername$UNIX2003")
diff --git a/src.old/parser.c b/src.old/parser.c
deleted file mode 100644
index 8f24be6..0000000
--- a/src.old/parser.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-/*
-
- parser.c - Parsing routines for torsocks.conf
-
-*/
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <config.h>
-
-#include "common.h"
-#include "parser.h"
-
-/* Global configuration variables */
-#define MAXLINE BUFSIZ /* Max length of conf line */
-static struct serverent *currentcontext = NULL;
-
-static int handle_line(struct parsedfile *, char *, int);
-static int check_server(struct serverent *);
-static int tokenize(char *, int, char *[]);
-static int handle_path(struct parsedfile *, int, int, char *[]);
-static int handle_endpath(struct parsedfile *, int, int);
-static int handle_reaches(int, char *);
-static int handle_server(struct parsedfile *, int, char *);
-static int handle_type(struct parsedfile *config, int, char *);
-static int handle_port(struct parsedfile *config, int, char *);
-static int handle_local(struct parsedfile *, int, const char *);
-static int handle_tordns_enabled(struct parsedfile *, int, char *);
-static int handle_tordns_deadpool_range(struct parsedfile *, int, const char *);
-static int handle_tordns_cache_size(struct parsedfile *, char *);
-static int handle_defuser(struct parsedfile *, int, char *);
-static int handle_defpass(struct parsedfile *, int, char *);
-static int make_netent(char *value, struct netent **ent);
-
-int read_config (char *filename, struct parsedfile *config) {
- FILE *conf;
- char line[MAXLINE];
- int rc = 0;
- int lineno = 1;
- struct serverent *server;
-
- /* Clear out the structure */
- memset(config, 0x0, sizeof(*config));
-
- /* Initialization */
- currentcontext = &(config->defaultserver);
-
- /* Tordns defaults */
- config->tordns_cache_size = 256;
- config->tordns_enabled = 1;
-
-
- /* If a filename wasn't provided, use the default */
- if (filename == NULL) {
- strncpy(line, CONF_FILE, sizeof(line) - 1);
- /* Insure null termination */
- line[sizeof(line) - 1] = (char) 0;
- filename = line;
- show_msg(MSGDEBUG, "Configuration file not provided by TORSOCKS_CONF_FILE "
- "environment variable, attempting to use defaults in %s.\n", filename);
- }
-
- /* If there is no configuration file use reasonable defaults for Tor */
- if ((conf = fopen(filename, "r")) == NULL) {
- show_msg(MSGERR, "Could not open socks configuration file "
- "(%s) errno (%d), assuming sensible defaults for Tor.\n", filename, errno);
- memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
- check_server(&(config->defaultserver));
- handle_local(config, 0, "127.0.0.0/255.0.0.0");
- handle_local(config, 0, "10.0.0.0/255.0.0.0");
- handle_local(config, 0, "192.168.0.0/255.255.0.0");
- handle_local(config, 0, "172.16.0.0/255.240.0.0");
- handle_local(config, 0, "169.254.0.0/255.255.0.0");
- rc = 1; /* Severe errors reading configuration */
- } else {
- memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
-
- while (NULL != fgets(line, MAXLINE, conf)) {
- /* This line _SHOULD_ end in \n so we */
- /* just chop off the \n and hand it on */
- if (strlen(line) > 0)
- line[strlen(line) - 1] = '\0';
- handle_line(config, line, lineno);
- lineno++;
- }
- fclose(conf);
-
- /* Always add the 127.0.0.1/255.0.0.0 subnet to local */
- handle_local(config, 0, "127.0.0.0/255.0.0.0");
- /* We always consider this local, because many users' dsl
- routers act as their DNS. */
- handle_local(config, 0, "10.0.0.0/255.0.0.0");
- handle_local(config, 0, "192.168.0.0/255.255.0.0");
- handle_local(config, 0, "172.16.0.0/255.240.0.0");
- handle_local(config, 0, "169.254.0.0/255.255.0.0");
- handle_local(config, 0, "192.168.0.0/255.255.0.0");
-
- /* Check default server */
- check_server(&(config->defaultserver));
- server = (config->paths);
- while (server != NULL) {
- check_server(server);
- server = server->next;
- }
- }
-
- /* Initialize tordns deadpool_range if not supplied */
- if(config->tordns_deadpool_range == NULL) {
- handle_tordns_deadpool_range(config, 0, "127.0.69.0/255.255.255.0");
- }
-
- return(rc);
-}
-
-/* Check server entries (and establish defaults) */
-static int check_server(struct serverent *server) {
-
- /* Default to the default Tor Socks port */
- if (server->port == 0) {
- server->port = 9050;
- }
-
- /* Default to a presumably local installation of Tor */
- if (server->address == NULL) {
- server->address = strdup("127.0.0.1");
- }
-
- /* Default to SOCKS V4 */
- if (server->type == 0) {
- server->type = 4;
- }
-
- return(0);
-}
-
-
-
-static int handle_line(struct parsedfile *config, char *line, int lineno) {
- char *words[10];
- static char savedline[MAXLINE];
- int nowords = 0, i;
-
- /* Save the input string */
- strncpy(savedline, line, MAXLINE - 1);
- savedline[MAXLINE - 1] = (char) 0;
- /* Tokenize the input string */
- nowords = tokenize(line, 10, words);
-
- /* Set the spare slots to an empty string to simplify */
- /* processing */
- for (i = nowords; i < 10; i++)
- words[i] = NULL;
-
- if (nowords > 0) {
- /* Now this can either be a "path" block starter or */
- /* ender, otherwise it has to be a pair (<name> = */
- /* <value>) */
- if (!strcmp(words[0], "path")) {
- handle_path(config, lineno, nowords, words);
- } else if (!strcmp(words[0], "}")) {
- handle_endpath(config, lineno, nowords);
- } else {
- /* Has to be a pair */
- if ((nowords != 3) || (strcmp(words[1], "="))) {
- show_msg(MSGERR, "Malformed configuration pair "
- "on line %d in configuration "
- "file, \"%s\"\n", lineno, savedline);
- } else if (!strcmp(words[0], "reaches")) {
- handle_reaches(lineno, words[2]);
- } else if (!strcmp(words[0], "server")) {
- handle_server(config, lineno, words[2]);
- } else if (!strcmp(words[0], "server_port")) {
- handle_port(config, lineno, words[2]);
- } else if (!strcmp(words[0], "server_type")) {
- handle_type(config, lineno, words[2]);
- } else if (!strcmp(words[0], "default_user")) {
- handle_defuser(config, lineno, words[2]);
- } else if (!strcmp(words[0], "default_pass")) {
- handle_defpass(config, lineno, words[2]);
- } else if (!strcmp(words[0], "local")) {
- handle_local(config, lineno, words[2]);
- } else if (!strcmp(words[0], "tordns_enable")) {
- handle_tordns_enabled(config, lineno, words[2]);
- } else if (!strcmp(words[0], "tordns_deadpool_range")) {
- handle_tordns_deadpool_range(config, lineno, words[2]);
- } else if (!strcmp(words[0], "tordns_cache_size")) {
- handle_tordns_cache_size(config, words[2]);
- } else {
- show_msg(MSGERR, "Invalid pair type (%s) specified "
- "on line %d in configuration file, "
- "\"%s\"\n", words[0], lineno,
- savedline);
- }
- }
- }
-
- return(0);
-}
-
-/* This routines breaks up input lines into tokens */
-/* and places these tokens into the array specified */
-/* by tokens */
-static int tokenize(char *line, int arrsize, char *tokens[]) {
- int tokenno = -1;
- int finished = 0;
-
- /* Whitespace is ignored before and after tokens */
- while ((tokenno < (arrsize - 1)) &&
- (line = line + strspn(line, " \t")) &&
- (*line != (char) 0) &&
- (!finished)) {
- tokenno++;
- tokens[tokenno] = line;
- line = line + strcspn(line, " \t");
- *line = (char) 0;
- line++;
-
- /* We ignore everything after a # */
- if (*tokens[tokenno] == '#') {
- finished = 1;
- tokenno--;
- }
- }
-
- return(tokenno + 1);
-}
-
-static int handle_path(struct parsedfile *config, int lineno, int nowords, char *words[]) {
- struct serverent *newserver;
-
- if ((nowords != 2) || (strcmp(words[1], "{"))) {
- show_msg(MSGERR, "Badly formed path open statement on line %d "
- "in configuration file (should look like "
- "\"path {\")\n", lineno);
- } else if (currentcontext != &(config->defaultserver)) {
- /* You cannot nest path statements so check that */
- /* the current context is defaultserver */
- show_msg(MSGERR, "Path statements cannot be nested on line %d "
- "in configuration file\n", lineno);
- } else {
- /* Open up a new serverent, put it on the list */
- /* then set the current context */
- if ((newserver = malloc(sizeof(*newserver))) == NULL)
- exit(-1);
-
- /* Initialize the structure */
- show_msg(MSGDEBUG, "New server structure from line %d in configuration file going "
- "to 0x%08x\n", lineno, newserver);
- memset(newserver, 0x0, sizeof(*newserver));
- newserver->next = config->paths;
- newserver->lineno = lineno;
- config->paths = newserver;
- currentcontext = newserver;
- }
-
- return(0);
-}
-
-static int handle_endpath(struct parsedfile *config, int lineno, int nowords) {
-
- if (nowords != 1) {
- show_msg(MSGERR, "Badly formed path close statement on line "
- "%d in configuration file (should look like "
- "\"}\")\n", lineno);
- } else {
- currentcontext = &(config->defaultserver);
- }
-
- /* We could perform some checking on the validty of data in */
- /* the completed path here, but thats what verifyconf is */
- /* designed to do, no point in weighing down libtorsocks */
-
- return(0);
-}
-
-static int handle_reaches(int lineno, char *value) {
- int rc;
- struct netent *ent;
-
- rc = make_netent(value, &ent);
- switch(rc) {
- case 1:
- show_msg(MSGERR, "Local network specification (%s) is not validly "
- "constructed in reach statement on line "
- "%d in configuration "
- "file\n", value, lineno);
- return(0);
- break;
- case 2:
- show_msg(MSGERR, "IP in reach statement "
- "network specification (%s) is not valid on line "
- "%d in configuration file\n", value, lineno);
- return(0);
- break;
- case 3:
- show_msg(MSGERR, "SUBNET in reach statement "
- "network specification (%s) is not valid on "
- "line %d in configuration file\n", value,
- lineno);
- return(0);
- break;
- case 4:
- show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
- show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
- "configuration file, ignored\n",
- inet_ntoa(ent->localnet), lineno);
- return(0);
- break;
- case 5:
- show_msg(MSGERR, "Start port in reach statement "
- "network specification (%s) is not valid on line "
- "%d in configuration file\n", value, lineno);
- return(0);
- break;
- case 6:
- show_msg(MSGERR, "End port in reach statement "
- "network specification (%s) is not valid on line "
- "%d in configuration file\n", value, lineno);
- return(0);
- break;
- case 7:
- show_msg(MSGERR, "End port in reach statement "
- "network specification (%s) is less than the start "
- "port on line %d in configuration file\n", value,
- lineno);
- return(0);
- break;
- }
-
- /* The entry is valid so add it to linked list */
- ent -> next = currentcontext -> reachnets;
- currentcontext -> reachnets = ent;
-
- return(0);
-}
-
-static int handle_server(struct parsedfile *config, int lineno, char *value) {
- char *ip;
-
- ip = strsplit(NULL, &value, " ");
-
- /* We don't verify this ip/hostname at this stage, */
- /* its resolved immediately before use in torsocks.c */
- if (currentcontext->address == NULL)
- currentcontext->address = strdup(ip);
- else {
- if (currentcontext == &(config->defaultserver))
- show_msg(MSGERR, "Only one default SOCKS server "
- "may be specified at line %d in "
- "configuration file\n", lineno);
- else
- show_msg(MSGERR, "Only one SOCKS server may be specified "
- "per path on line %d in configuration "
- "file. (Path begins on line %d)\n",
- lineno, currentcontext->lineno);
- }
-
- return(0);
-}
-
-static int handle_port(struct parsedfile *config, int lineno, char *value) {
-
- if (currentcontext->port != 0) {
- if (currentcontext == &(config->defaultserver))
- show_msg(MSGERR, "Server port may only be specified "
- "once for default server, at line %d "
- "in configuration file\n", lineno);
- else
- show_msg(MSGERR, "Server port may only be specified "
- "once per path on line %d in configuration "
- "file. (Path begins on line %d)\n",
- lineno, currentcontext->lineno);
- } else {
- errno = 0;
- currentcontext->port = (unsigned short int)
- (strtol(value, (char **)NULL, 10));
- if ((errno != 0) || (currentcontext->port == 0)) {
- show_msg(MSGERR, "Invalid server port number "
- "specified in configuration file "
- "(%s) on line %d\n", value, lineno);
- currentcontext->port = 0;
- }
- }
-
- return(0);
-}
-
-static int handle_defuser(struct parsedfile *config, int lineno, char *value) {
-
- if (currentcontext->defuser != NULL) {
- if (currentcontext == &(config->defaultserver))
- show_msg(MSGERR, "Default username may only be specified "
- "once for default server, at line %d "
- "in configuration file\n", lineno);
- else
- show_msg(MSGERR, "Default username may only be specified "
- "once per path on line %d in configuration "
- "file. (Path begins on line %d)\n",
- lineno, currentcontext->lineno);
- } else {
- currentcontext->defuser = strdup(value);
- }
-
- return(0);
-}
-
-static int handle_defpass(struct parsedfile *config, int lineno, char *value) {
-
- if (currentcontext->defpass != NULL) {
- if (currentcontext == &(config->defaultserver))
- show_msg(MSGERR, "Default password may only be specified "
- "once for default server, at line %d "
- "in configuration file\n", lineno);
- else
- show_msg(MSGERR, "Default password may only be specified "
- "once per path on line %d in configuration "
- "file. (Path begins on line %d)\n",
- lineno, currentcontext->lineno);
- } else {
- currentcontext->defpass = strdup(value);
- }
-
- return(0);
-}
-
-static int handle_type(struct parsedfile *config, int lineno, char *value) {
-
- if (currentcontext->type != 0) {
- if (currentcontext == &(config->defaultserver))
- show_msg(MSGERR, "Server type may only be specified "
- "once for default server, at line %d "
- "in configuration file\n", lineno);
- else
- show_msg(MSGERR, "Server type may only be specified "
- "once per path on line %d in configuration "
- "file. (Path begins on line %d)\n",
- lineno, currentcontext->lineno);
- } else {
- errno = 0;
- currentcontext->type = (int) strtol(value, (char **)NULL, 10);
- if ((errno != 0) || (currentcontext->type == 0) ||
- ((currentcontext->type != 4) && (currentcontext->type != 5))) {
- show_msg(MSGERR, "Invalid server type (%s) "
- "specified in configuration file "
- "on line %d, only 4 or 5 may be "
- "specified\n", value, lineno);
- currentcontext->type = 0;
- }
- }
-
- return(0);
-}
-
-static int handle_flag(char *value)
-{
- if(!strcasecmp(value, "true") || !strcasecmp(value, "yes")
- || !strcmp(value, "1")) {
- return 1;
- } else if (!strcasecmp(value, "false") || !strcasecmp(value, "no")
- || !strcmp(value, "0")) {
- return 0;
- } else {
- return -1;
- }
-}
-
-static int handle_tordns_enabled(struct parsedfile *config, int lineno,
- char *value)
-{
- int val = handle_flag(value);
- if(val == -1) {
- show_msg(MSGERR, "Invalid value %s supplied for tordns_enabled at "
- "line %d in config file, IGNORED\n", value, lineno);
- } else {
- config->tordns_enabled = val;
- }
- return 0;
-}
-
-static int handle_tordns_cache_size(struct parsedfile *config,
- char *value)
-{
- char *endptr;
- long size = strtol(value, &endptr, 10);
- if(*endptr != '\0') {
- show_msg(MSGERR, "Error parsing integer value for "
- "tordns_cache_size (%s), using default %d\n",
- value, config->tordns_cache_size);
- } else if(size < 128) {
- show_msg(MSGERR, "The value supplied for tordns_cache_size (%d) "
- "is too small (<128), using default %d\n", size,
- config->tordns_cache_size);
- } else if(size > 4096) {
- show_msg(MSGERR, "The value supplied for tordns_cache_range (%d) "
- "is too large (>4096), using default %d\n", size,
- config->tordns_cache_size);
- } else {
- config->tordns_cache_size = size;
- }
- return 0;
-}
-
-static int handle_tordns_deadpool_range(struct parsedfile *config, int lineno,
- const char *value)
-{
- int rc;
- struct netent *ent;
-
- if (config->tordns_deadpool_range != NULL) {
- show_msg(MSGERR, "Only one 'deadpool' entry permitted, found a "
- "second at line %d in configuration file.\n");
- return(0);
- }
-
- if (currentcontext != &(config->defaultserver)) {
- show_msg(MSGERR, "Deadpool cannot be specified in path "
- "block at line %d in configuration file. "
- "(Path block started at line %d)\n",
- lineno, currentcontext->lineno);
- return(0);
- }
-
- rc = make_netent((char *)value, &ent);
- /* This is copied from handle_local and should probably be folded into
- a generic whinge() function or something */
- switch(rc) {
- case 1:
- show_msg(MSGERR, "The deadpool specification (%s) is not validly "
- "constructed on line %d in configuration "
- "file\n", value, lineno);
- return(0);
- break;
- case 2:
- show_msg(MSGERR, "IP for deadpool "
- "network specification (%s) is not valid on line "
- "%d in configuration file\n", value, lineno);
- return(0);
- break;
- case 3:
- show_msg(MSGERR, "SUBNET for "
- "deadpool network specification (%s) is not valid on "
- "line %d in configuration file\n", value,
- lineno);
- return(0);
- break;
- case 4:
- show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
- show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
- "configuration file, ignored\n",
- inet_ntoa(ent->localnet), lineno);
- return(0);
- case 5:
- case 6:
- case 7:
- show_msg(MSGERR, "Port specification is invalid and "
- "not allowed in deadpool specification "
- "(%s) on line %d in configuration file\n",
- value, lineno);
- return(0);
- break;
- }
- if (ent->startport || ent->endport) {
- show_msg(MSGERR, "Port specification is "
- "not allowed in deadpool specification "
- "(%s) on line %d in configuration file\n",
- value, lineno);
- return(0);
- }
-
- config->tordns_deadpool_range = ent;
- return 0;
-}
-
-static int handle_local(struct parsedfile *config, int lineno, const char *value) {
- int rc;
- struct netent *ent;
-
- if (currentcontext != &(config->defaultserver)) {
- show_msg(MSGERR, "Local networks cannot be specified in path "
- "block at line %d in configuration file. "
- "(Path block started at line %d)\n",
- lineno, currentcontext->lineno);
- return(0);
- }
-
- rc = make_netent((char *)value, &ent);
- switch(rc) {
- case 1:
- show_msg(MSGERR, "Local network specification (%s) is not validly "
- "constructed on line %d in configuration "
- "file\n", value, lineno);
- return(0);
- break;
- case 2:
- show_msg(MSGERR, "IP for local "
- "network specification (%s) is not valid on line "
- "%d in configuration file\n", value, lineno);
- return(0);
- break;
- case 3:
- show_msg(MSGERR, "SUBNET for "
- "local network specification (%s) is not valid on "
- "line %d in configuration file\n", value,
- lineno);
- return(0);
- break;
- case 4:
- show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
- show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
- "configuration file, ignored\n",
- inet_ntoa(ent->localnet), lineno);
- return(0);
- case 5:
- case 6:
- case 7:
- show_msg(MSGERR, "Port specification is invalid and "
- "not allowed in local network specification "
- "(%s) on line %d in configuration file\n",
- value, lineno);
- return(0);
- break;
- }
-
- if (ent->startport || ent->endport) {
- show_msg(MSGERR, "Port specification is "
- "not allowed in local network specification "
- "(%s) on line %d in configuration file\n",
- value, lineno);
- return(0);
- }
-
- /* The entry is valid so add it to linked list */
- ent -> next = config->localnets;
- (config->localnets) = ent;
-
- return(0);
-}
-
-/* Construct a netent given a string like */
-/* "198.126.0.1[:portno[-portno]]/255.255.255.0" */
-int make_netent(char *value, struct netent **ent) {
- char *ip;
- char *subnet;
- char *startport = NULL;
- char *endport = NULL;
- char *badchar;
- char separator;
- static char buf[200];
- char *split;
-
- /* Get a copy of the string so we can modify it */
- strncpy(buf, value, sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = (char) 0;
- split = buf;
-
- /* Now rip it up */
- ip = strsplit(&separator, &split, "/:");
- if (separator == ':') {
- /* We have a start port */
- startport = strsplit(&separator, &split, "-/");
- if (separator == '-')
- /* We have an end port */
- endport = strsplit(&separator, &split, "/");
- }
- subnet = strsplit(NULL, &split, " \n");
-
- if ((ip == NULL) || (subnet == NULL)) {
- /* Network specification not validly constructed */
- return(1);
- }
-
- /* Allocate the new entry */
- if ((*ent = (struct netent *) malloc(sizeof(struct netent)))
- == NULL) {
- /* If we couldn't malloc some storage, leave */
- exit(1);
- }
-
- show_msg(MSGDEBUG, "New network entry for %s going to 0x%08x\n", ip, *ent);
-
- if (!startport)
- (*ent)->startport = 0;
- if (!endport)
- (*ent)->endport = 0;
-
-#ifdef HAVE_INET_ADDR
- if (((*ent)->localip.s_addr = inet_addr(ip)) == -1) {
-#elif defined(HAVE_INET_ATON)
- if (!(inet_aton(ip, &((*ent)->localip)))) {
-#endif
- /* Badly constructed IP */
- free(*ent);
- return(2);
- }
-#ifdef HAVE_INET_ADDR
- else if (((*ent)->localnet.s_addr = inet_addr(subnet)) == -1) {
-#elif defined(HAVE_INET_ATON)
- else if (!(inet_aton(subnet, &((*ent)->localnet)))) {
-#endif
- /* Badly constructed subnet */
- free(*ent);
- return(3);
- } else if (((*ent)->localip.s_addr &
- (*ent)->localnet.s_addr) !=
- (*ent)->localip.s_addr) {
- /* Subnet and Ip != Ip */
- free(*ent);
- return(4);
- } else if (startport &&
- (!((*ent)->startport = strtol(startport, &badchar, 10)) ||
- (*badchar != 0) || ((*ent)->startport > 65535))) {
- /* Bad start port */
- free(*ent);
- return(5);
- } else if (endport &&
- (!((*ent)->endport = strtol(endport, &badchar, 10)) ||
- (*badchar != 0) || ((*ent)->endport > 65535))) {
- /* Bad end port */
- free(*ent);
- return(6);
- } else if (((*ent)->startport > (*ent)->endport) && !(startport && !endport)) {
- /* End port is less than start port */
- free(*ent);
- return(7);
- }
-
- if (startport && !endport)
- (*ent)->endport = (*ent)->startport;
-
- return(0);
-}
-
-int is_local(struct parsedfile *config, struct in_addr *testip) {
- struct netent *ent;
- char buf[16];
- inet_ntop(AF_INET, testip, buf, sizeof(buf));
- show_msg(MSGDEBUG, "checking if address: %s is local"
- "\n",
- buf);
-
- for (ent = (config->localnets); ent != NULL; ent = ent -> next) {
- inet_ntop(AF_INET, &ent->localnet, buf, sizeof(buf));
- show_msg(MSGDEBUG, "localnet addr: %s"
- "\n",
- buf);
- inet_ntop(AF_INET, &ent->localip, buf, sizeof(buf));
- show_msg(MSGDEBUG, "localip addr: %s"
- "\n",
- buf);
- show_msg(MSGDEBUG, "result testip->s_addr & ent->localnet.s_addr : %i"
- "\n",
- testip->s_addr & ent->localnet.s_addr);
- show_msg(MSGDEBUG, "result ent->localip.s_addr & ent->localnet.s_addr : %i"
- "\n",
- ent->localip.s_addr & ent->localnet.s_addr);
- show_msg(MSGDEBUG, "result ent->localip.s_addr : %i"
- "\n",
- ent->localip.s_addr);
- if ((testip->s_addr & ent->localnet.s_addr) ==
- (ent->localip.s_addr & ent->localnet.s_addr)) {
- show_msg(MSGDEBUG, "address: %s is local"
- "\n",
- buf);
- return(0);
- }
- }
-
- inet_ntop(AF_INET, testip, buf, sizeof(buf));
- show_msg(MSGDEBUG, "address: %s is not local"
- "\n",
- buf);
- return(1);
-}
-
-/* Find the appropriate server to reach an ip */
-int pick_server(struct parsedfile *config, struct serverent **ent,
- struct in_addr *ip, unsigned int port) {
- struct netent *net;
- char ipbuf[64];
-
- show_msg(MSGDEBUG, "Picking appropriate server for %s\n", inet_ntoa(*ip));
- *ent = (config->paths);
- while (*ent != NULL) {
- /* Go through all the servers looking for one */
- /* with a path to this network */
- show_msg(MSGDEBUG, "Checking SOCKS server %s\n",
- ((*ent)->address ? (*ent)->address : "(No Address)"));
- net = (*ent)->reachnets;
- while (net != NULL) {
- strcpy(ipbuf, inet_ntoa(net->localip));
- show_msg(MSGDEBUG, "Server can reach %s/%s\n",
- ipbuf, inet_ntoa(net->localnet));
- if (((ip->s_addr & net->localnet.s_addr) ==
- (net->localip.s_addr & net->localnet.s_addr)) &&
- (!net->startport ||
- ((net->startport <= port) && (net->endport >= port))))
- {
- show_msg(MSGDEBUG, "This server can reach target\n");
- /* Found the net, return */
- return(0);
- }
- net = net->next;
- }
- (*ent) = (*ent)->next;
- }
-
- *ent = &(config->defaultserver);
-
- return(0);
-}
-
-/* This function is very much like strsep, it looks in a string for */
-/* a character from a list of characters, when it finds one it */
-/* replaces it with a \0 and returns the start of the string */
-/* (basically spitting out tokens with arbitrary separators). If no */
-/* match is found the remainder of the string is returned and */
-/* the start pointer is set to be NULL. The difference between */
-/* standard strsep and this function is that this one will */
-/* set *separator to the character separator found if it isn't null */
-char *strsplit(char *separator, char **text, const char *search) {
- unsigned int len;
- char *ret;
-
- ret = *text;
-
- if (*text == NULL) {
- if (separator)
- *separator = '\0';
- return(NULL);
- } else {
- len = strcspn(*text, search);
- if (len == strlen(*text)) {
- if (separator)
- *separator = '\0';
- *text = NULL;
- } else {
- *text = *text + len;
- if (separator)
- *separator = **text;
- **text = '\0';
- *text = *text + 1;
- }
- }
-
- return(ret);
-}
diff --git a/src.old/parser.h b/src.old/parser.h
deleted file mode 100644
index 91e6d04..0000000
--- a/src.old/parser.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-
-/* parser.h - Structures, functions and global variables for the
- torsocks parsing routines */
-
-#ifndef _PARSER_H
-
-#define _PARSER_H 1
-
-/* Structure definitions */
-
-/* Structure representing one server specified in the config */
-struct serverent {
- int lineno; /* Line number in conf file this path started on */
- char *address; /* Address/hostname of server */
- int port; /* Port number of server */
- int type; /* Type of server (4/5) */
- char *defuser; /* Default username for this socks server */
- char *defpass; /* Default password for this socks server */
- struct netent *reachnets; /* Linked list of nets from this server */
- struct serverent *next; /* Pointer to next server entry */
-};
-
-/* Structure representing a network */
-struct netent {
- struct in_addr localip; /* Base IP of the network */
- struct in_addr localnet; /* Mask for the network */
- unsigned long startport; /* Range of ports for the */
- unsigned long endport; /* network */
- struct netent *next; /* Pointer to next network entry */
-};
-
-/* Structure representing a complete parsed file */
-struct parsedfile {
- struct netent *localnets;
- struct serverent defaultserver;
- struct serverent *paths;
- int tordns_enabled;
- int tordns_failopen;
- unsigned int tordns_cache_size;
- struct netent *tordns_deadpool_range;
-};
-
-/* Functions provided by parser module */
-int read_config(char *, struct parsedfile *);
-int is_local(struct parsedfile *, struct in_addr *);
-int pick_server(struct parsedfile *, struct serverent **, struct in_addr *, unsigned int port);
-char *strsplit(char *separator, char **text, const char *search);
-
-#endif
diff --git a/src.old/socks.c b/src.old/socks.c
deleted file mode 100644
index 8497728..0000000
--- a/src.old/socks.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-/* PreProcessor Defines */
-#include <config.h>
-
-/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
-to Mac OS X 10.3's library and kernel calls as possible.*/
-#if defined(__APPLE__) || defined(__darwin__)
-/*
-From 'man compat' in OSX:
-64-BIT COMPILATION
- When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
- is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
- level). Defining _NONSTD_SOURCE will cause a compilation error.
-*/
-#if !defined(__LP64__)
-#define _NONSTD_SOURCE 1
-#endif
-#include <sys/socket.h>
-#endif
-
-
-#ifdef USE_GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-/* Header Files */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <string.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <pwd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#if !defined(__APPLE__) && !defined(__darwin__)
-#include <sys/socket.h>
-#endif
-#include <resolv.h>
-
-#include "common.h"
-#include "dead_pool.h"
-#include "parser.h"
-#include "socks.h"
-
-static int connect_server(struct connreq *conn);
-static int send_socks_request(struct connreq *conn);
-static int send_socksv4_request(struct connreq *conn);
-static int send_socksv5_method(struct connreq *conn);
-static int send_socksv5_connect(struct connreq *conn);
-static int send_buffer(struct connreq *conn);
-static int recv_buffer(struct connreq *conn);
-static int read_socksv5_method(struct connreq *conn);
-static int read_socksv4_req(struct connreq *conn);
-static int read_socksv5_connect(struct connreq *conn);
-static int read_socksv5_auth(struct connreq *conn);
-static int send_socksv4a_request(struct connreq *conn, const char *onion_host);
-
-
-dead_pool *pool = NULL;
-struct connreq *requests = NULL;
-
-struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
- struct sockaddr_in *serveraddr,
- struct serverent *path)
-{
- struct connreq *newconn;
-
- if ((newconn = malloc(sizeof(*newconn))) == NULL) {
- /* Could not malloc, we're stuffed */
- show_msg(MSGERR, "Could not allocate memory for new socks request\n");
- return(NULL);
- }
-
- /* Add this connection to be proxied to the list */
- memset(newconn, 0x0, sizeof(*newconn));
- newconn->sockid = sockid;
- newconn->state = UNSTARTED;
- newconn->path = path;
- memcpy(&(newconn->connaddr), connaddr, sizeof(newconn->connaddr));
- memcpy(&(newconn->serveraddr), serveraddr, sizeof(newconn->serveraddr));
- newconn->next = requests;
- requests = newconn;
-
- return(newconn);
-}
-
-void kill_socks_request(struct connreq *conn)
-{
- struct connreq *connnode;
-
- if (requests == conn)
- requests = conn->next;
- else {
- for (connnode = requests; connnode != NULL; connnode = connnode->next) {
- if (connnode->next == conn) {
- connnode->next = conn->next;
- break;
- }
- }
- }
-
- free(conn);
-}
-
-struct connreq *find_socks_request(int sockid, int includefinished)
-{
- struct connreq *connnode;
-
- for (connnode = requests; connnode != NULL; connnode = connnode->next) {
- if (connnode->sockid == sockid) {
- if (((connnode->state == FAILED) || (connnode->state == DONE)) &&
- !includefinished)
- break;
- else
- return(connnode);
- }
- }
-
- return(NULL);
-}
-
-int handle_request(struct connreq *conn)
-{
- int rc = 0;
- int i = 0;
-
- show_msg(MSGDEBUG, "Beginning handle loop for socket %d\n", conn->sockid);
-
- while ((rc == 0) &&
- (conn->state != FAILED) &&
- (conn->state != DONE) &&
- (i++ < 20)) {
- show_msg(MSGDEBUG, "In request handle loop for socket %d, "
- "current state of request is %d\n", conn->sockid,
- conn->state);
- switch(conn->state) {
- case UNSTARTED:
- case CONNECTING:
- rc = connect_server(conn);
- break;
- case CONNECTED:
- rc = send_socks_request(conn);
- break;
- case SENDING:
- rc = send_buffer(conn);
- break;
- case RECEIVING:
- rc = recv_buffer(conn);
- break;
- case SENTV4REQ:
- show_msg(MSGDEBUG, "Receiving reply to SOCKS V4 connect request\n");
- conn->datalen = sizeof(struct sockrep);
- conn->datadone = 0;
- conn->state = RECEIVING;
- conn->nextstate = GOTV4REQ;
- break;
- case GOTV4REQ:
- rc = read_socksv4_req(conn);
- break;
- case SENTV5METHOD:
- show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 method negotiation\n");
- conn->datalen = 2;
- conn->datadone = 0;
- conn->state = RECEIVING;
- conn->nextstate = GOTV5METHOD;
- break;
- case GOTV5METHOD:
- rc = read_socksv5_method(conn);
- break;
- case SENTV5AUTH:
- show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 authentication negotiation\n");
- conn->datalen = 2;
- conn->datadone = 0;
- conn->state = RECEIVING;
- conn->nextstate = GOTV5AUTH;
- break;
- case GOTV5AUTH:
- rc = read_socksv5_auth(conn);
- break;
- case SENTV5CONNECT:
- show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 connect request\n");
- conn->datalen = 10;
- conn->datadone = 0;
- conn->state = RECEIVING;
- conn->nextstate = GOTV5CONNECT;
- break;
- case GOTV5CONNECT:
- rc = read_socksv5_connect(conn);
- break;
- }
- conn->err = errno;
- }
-
- if (i == 20)
- show_msg(MSGERR, "Ooops, state loop while handling request %d\n",
- conn->sockid);
-
- show_msg(MSGDEBUG, "Handle loop completed for socket %d in state %d, "
- "returning %d\n", conn->sockid, conn->state, rc);
- return(rc);
-}
-
-static int connect_server(struct connreq *conn)
-{
- int rc;
-
- /* Connect this socket to the socks server */
- show_msg(MSGDEBUG, "Connecting to %s port %d\n",
- inet_ntoa(conn->serveraddr.sin_addr), ntohs(conn->serveraddr.sin_port));
-
- rc = realconnect(conn->sockid, (CONNECT_SOCKARG) &(conn->serveraddr),
- sizeof(conn->serveraddr));
-
- show_msg(MSGDEBUG, "Connect returned %d, errno is %d\n", rc, errno);
- if (rc && errno == EISCONN) {
- rc = 0;
- show_msg(MSGDEBUG, "Socket %d already connected to SOCKS server\n", conn->sockid);
- conn->state = CONNECTED;
- } else if (rc) {
- if (errno != EINPROGRESS) {
- show_msg(MSGERR, "Error %d attempting to connect to SOCKS "
- "server (%s)\n", errno, strerror(errno));
- conn->state = FAILED;
- } else {
- show_msg(MSGDEBUG, "Connection in progress\n");
- conn->state = CONNECTING;
- }
- } else {
- show_msg(MSGDEBUG, "Socket %d connected to SOCKS server\n", conn->sockid);
- conn->state = CONNECTED;
- }
-
- return((rc ? errno : 0));
-}
-
-static int send_socks_request(struct connreq *conn)
-{
- int rc = 0;
-
- if (conn->path->type == 4) {
- char *name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
- if(name != NULL)
- rc = send_socksv4a_request(conn,name);
- else
- rc = send_socksv4_request(conn);
- } else
- rc = send_socksv5_method(conn);
- return(rc);
-}
-
-static int send_socksv4a_request(struct connreq *conn,const char *onion_host)
-{
- struct passwd *user;
- struct sockreq *thisreq;
- int endOfUser;
- /* Determine the current username */
- user = getpwuid(getuid());
-
- thisreq = (struct sockreq *) conn->buffer;
- endOfUser=sizeof(struct sockreq) +
- (user == NULL ? 0 : strlen(user->pw_name)) + 1;
-
- /* Check the buffer has enough space for the request */
- /* and the user name */
- conn->datalen = endOfUser+
- (onion_host == NULL ? 0 : strlen(onion_host)) + 1;
- if (sizeof(conn->buffer) < conn->datalen) {
- show_msg(MSGERR, "The SOCKS username is too long");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- /* Create the request */
- thisreq->version = 4;
- thisreq->command = 1;
- thisreq->dstport = conn->connaddr.sin_port;
- thisreq->dstip = htonl(1);
-
- /* Copy the username */
- strcpy((char *) thisreq + sizeof(struct sockreq),
- (user == NULL ? "" : user->pw_name));
-
- /* Copy the onion host */
- strcpy((char *) thisreq + endOfUser,
- (onion_host == NULL ? "" : onion_host));
-
- conn->datadone = 0;
- conn->state = SENDING;
- conn->nextstate = SENTV4REQ;
-
- return(0);
-}
-
-static int send_socksv4_request(struct connreq *conn)
-{
- struct passwd *user;
- struct sockreq *thisreq;
-
- /* Determine the current username */
- user = getpwuid(getuid());
-
- thisreq = (struct sockreq *) conn->buffer;
-
- /* Check the buffer has enough space for the request */
- /* and the user name */
- conn->datalen = sizeof(struct sockreq) +
- (user == NULL ? 0 : strlen(user->pw_name)) + 1;
- if (sizeof(conn->buffer) < conn->datalen) {
- show_msg(MSGERR, "The SOCKS username is too long");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- /* Create the request */
- thisreq->version = 4;
- thisreq->command = 1;
- thisreq->dstport = conn->connaddr.sin_port;
- thisreq->dstip = conn->connaddr.sin_addr.s_addr;
-
- /* Copy the username */
- strcpy((char *) thisreq + sizeof(struct sockreq),
- (user == NULL ? "" : user->pw_name));
-
- conn->datadone = 0;
- conn->state = SENDING;
- conn->nextstate = SENTV4REQ;
-
- return(0);
-}
-
-static int send_socksv5_method(struct connreq *conn)
-{
- char verstring[] = { 0x05, /* Version 5 SOCKS */
- 0x02, /* No. Methods */
- 0x00, /* Null Auth */
- 0x02 }; /* User/Pass Auth */
-
- show_msg(MSGDEBUG, "Constructing V5 method negotiation\n");
- conn->state = SENDING;
- conn->nextstate = SENTV5METHOD;
- memcpy(conn->buffer, verstring, sizeof(verstring));
- conn->datalen = sizeof(verstring);
- conn->datadone = 0;
-
- return(0);
-}
-
-static int send_socksv5_connect(struct connreq *conn)
-{
- int namelen = 0;
- char *name = NULL;
- char constring[] = { 0x05, /* Version 5 SOCKS */
- 0x01, /* Connect request */
- 0x00, /* Reserved */
- 0x01 }; /* IP Version 4 */
-
- show_msg(MSGDEBUG, "Constructing V5 connect request\n");
- conn->datadone = 0;
- conn->state = SENDING;
- conn->nextstate = SENTV5CONNECT;
- memcpy(conn->buffer, constring, sizeof(constring));
- conn->datalen = sizeof(constring);
-
- show_msg(MSGDEBUG, "send_socksv5_connect: looking for: %s\n",
- inet_ntoa(conn->connaddr.sin_addr));
-
- name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
- if(name != NULL) {
- namelen = strlen(name);
- if(namelen > 255) /* "Can't happen" */
- name = NULL;
- }
- if(name != NULL) {
- show_msg(MSGDEBUG, "send_socksv5_connect: found it!\n");
- /* Substitute the domain name from the pool into the SOCKS request. */
- conn->buffer[3] = 0x03; /* Change the ATYP field */
- conn->buffer[4] = namelen; /* Length of name */
- conn->datalen++;
- memcpy(&conn->buffer[conn->datalen], name, namelen);
- conn->datalen += namelen;
- } else {
- show_msg(MSGDEBUG, "send_socksv5_connect: ip address not found\n");
- /* Use the raw IP address */
- memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_addr.s_addr),
- sizeof(conn->connaddr.sin_addr.s_addr));
- conn->datalen += sizeof(conn->connaddr.sin_addr.s_addr);
- }
- memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_port),
- sizeof(conn->connaddr.sin_port));
- conn->datalen += sizeof(conn->connaddr.sin_port);
-
- return(0);
-}
-
-static int send_buffer(struct connreq *conn)
-{
- int rc = 0;
-
- show_msg(MSGDEBUG, "Writing to server (sending %d bytes)\n", conn->datalen);
- while ((rc == 0) && (conn->datadone != conn->datalen)) {
- rc = send(conn->sockid, conn->buffer + conn->datadone,
- conn->datalen - conn->datadone, 0);
- if (rc > 0) {
- conn->datadone += rc;
- rc = 0;
- } else {
- if (errno != EWOULDBLOCK)
- show_msg(MSGDEBUG, "Write failed, %s\n", strerror(errno));
- rc = errno;
- }
- }
-
- if (conn->datadone == conn->datalen)
- conn->state = conn->nextstate;
-
- show_msg(MSGDEBUG, "Sent %d bytes of %d bytes in buffer, return code is %d\n",
- conn->datadone, conn->datalen, rc);
- return(rc);
-}
-
-static int recv_buffer(struct connreq *conn)
-{
- int rc = 0;
-
- show_msg(MSGDEBUG, "Reading from server (expecting %d bytes)\n", conn->datalen);
- while ((rc == 0) && (conn->datadone != conn->datalen)) {
- rc = recv(conn->sockid, conn->buffer + conn->datadone,
- conn->datalen - conn->datadone, 0);
- if (rc > 0) {
- conn->datadone += rc;
- rc = 0;
- } else if (rc == 0) {
- show_msg(MSGDEBUG, "Peer has shutdown but we only read %d of %d bytes.\n",
- conn->datadone, conn->datalen);
- rc = ENOTCONN; /* ENOTCONN seems like the most fitting error message */
- } else {
- if (errno != EWOULDBLOCK)
- show_msg(MSGDEBUG, "Read failed, %s\n", strerror(errno));
- rc = errno;
- }
- }
-
- if (conn->datadone == conn->datalen)
- conn->state = conn->nextstate;
-
- show_msg(MSGDEBUG, "Received %d bytes of %d bytes expected, return code is %d\n",
- conn->datadone, conn->datalen, rc);
- return(rc);
-}
-
-static int read_socksv5_method(struct connreq *conn)
-{
- struct passwd *nixuser;
- char *uname, *upass;
-
- /* See if we offered an acceptable method */
- if (conn->buffer[1] == '\xff') {
- show_msg(MSGERR, "SOCKS V5 server refused authentication methods\n");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- /* If the socks server chose username/password authentication */
- /* (method 2) then do that */
- if ((unsigned short int) conn->buffer[1] == 2) {
- show_msg(MSGDEBUG, "SOCKS V5 server chose username/password authentication\n");
-
- /* Determine the current *nix username */
- nixuser = getpwuid(getuid());
-
- if (((uname = conn->path->defuser) == NULL) &&
- ((uname = getenv("TORSOCKS_USERNAME")) == NULL) &&
- ((uname = (nixuser == NULL ? NULL : nixuser->pw_name)) == NULL)) {
- show_msg(MSGERR, "Could not get SOCKS username from "
- "local passwd file, torsocks.conf "
- "or $TORSOCKS_USERNAME to authenticate "
- "with");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- if (((upass = getenv("TORSOCKS_PASSWORD")) == NULL) &&
- ((upass = conn->path->defpass) == NULL)) {
- show_msg(MSGERR, "Need a password in torsocks.conf or "
- "$TORSOCKS_PASSWORD to authenticate with");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- /* Check that the username / pass specified will */
- /* fit into the buffer */
- if ((3 + strlen(uname) + strlen(upass)) >= sizeof(conn->buffer)) {
- show_msg(MSGERR, "The supplied socks username or "
- "password is too long");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- conn->datalen = 0;
- conn->buffer[conn->datalen] = '\x01';
- conn->datalen++;
- conn->buffer[conn->datalen] = (int8_t) strlen(uname);
- conn->datalen++;
- memcpy(&(conn->buffer[conn->datalen]), uname, strlen(uname));
- conn->datalen = conn->datalen + strlen(uname);
- conn->buffer[conn->datalen] = (int8_t) strlen(upass);
- conn->datalen++;
- memcpy(&(conn->buffer[conn->datalen]), upass, strlen(upass));
- conn->datalen = conn->datalen + strlen(upass);
-
- conn->state = SENDING;
- conn->nextstate = SENTV5AUTH;
- conn->datadone = 0;
- } else
- return(send_socksv5_connect(conn));
-
- return(0);
-}
-
-static int read_socksv5_auth(struct connreq *conn)
-{
-
- if (conn->buffer[1] != '\x00') {
- show_msg(MSGERR, "SOCKS authentication failed, check username and password\n");
- conn->state = FAILED;
- return(ECONNREFUSED);
- }
-
- /* Ok, we authenticated ok, send the connection request */
- return(send_socksv5_connect(conn));
-}
-
-static int read_socksv5_connect(struct connreq *conn)
-{
-
- /* See if the connection succeeded */
- if (conn->buffer[1] != '\x00') {
- show_msg(MSGERR, "SOCKS V5 connect failed: ");
- conn->state = FAILED;
- switch ((int8_t) conn->buffer[1]) {
- case 1:
- show_msg(MSGERR, "General SOCKS server failure\n");
- return(ECONNABORTED);
- case 2:
- show_msg(MSGERR, "Connection denied by rule\n");
- return(ECONNABORTED);
- case 3:
- show_msg(MSGERR, "Network unreachable\n");
- return(ENETUNREACH);
- case 4:
- show_msg(MSGERR, "Host unreachable\n");
- return(EHOSTUNREACH);
- case 5:
- show_msg(MSGERR, "Connection refused\n");
- return(ECONNREFUSED);
- case 6:
- show_msg(MSGERR, "TTL Expired\n");
- return(ETIMEDOUT);
- case 7:
- show_msg(MSGERR, "Command not supported\n");
- return(ECONNABORTED);
- case 8:
- show_msg(MSGERR, "Address type not supported\n");
- return(ECONNABORTED);
- default:
- show_msg(MSGERR, "Unknown error\n");
- return(ECONNABORTED);
- }
- }
- conn->state = DONE;
-
- return(0);
-}
-
-static int read_socksv4_req(struct connreq *conn)
-{
- struct sockrep *thisrep;
-
- thisrep = (struct sockrep *) conn->buffer;
-
- if (thisrep->result != 90) {
- show_msg(MSGERR, "SOCKS V4 connect rejected:\n");
- conn->state = FAILED;
- switch(thisrep->result) {
- case 91:
- show_msg(MSGERR, "SOCKS server refused connection\n");
- return(ECONNREFUSED);
- case 92:
- show_msg(MSGERR, "SOCKS server refused connection "
- "because of failed connect to identd "
- "on this machine\n");
- return(ECONNREFUSED);
- case 93:
- show_msg(MSGERR, "SOCKS server refused connection "
- "because identd and this library "
- "reported different user-ids\n");
- return(ECONNREFUSED);
- default:
- show_msg(MSGERR, "Unknown reason\n");
- return(ECONNREFUSED);
- }
- }
- conn->state = DONE;
-
- return(0);
-}
diff --git a/src.old/socks.h b/src.old/socks.h
deleted file mode 100644
index 6dd497f..0000000
--- a/src.old/socks.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/***************************************************************************
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-/* socks.h - Structures used by torsocks to form SOCKS requests */
-
-#ifndef _SOCKS_H
-
-#define _SOCKS_H 1
-
-#include "parser.h"
-#include "dead_pool.h"
-
-/* Structure representing a socks connection request */
-struct sockreq {
- int8_t version;
- int8_t command;
- int16_t dstport;
- int32_t dstip;
- /* A null terminated username goes here */
-};
-
-/* Structure representing a socks connection request response */
-struct sockrep {
- int8_t version;
- int8_t result;
- int16_t ignore1;
- int32_t ignore2;
-};
-
-/* Structure representing a socket which we are currently proxying */
-struct connreq {
- /* Information about the socket and target */
- int sockid;
- struct sockaddr_in connaddr;
- struct sockaddr_in serveraddr;
-
- /* Pointer to the config entry for the socks server */
- struct serverent *path;
-
- /* Current state of this proxied socket */
- int state;
-
- /* Next state to go to when the send or receive is finished */
- int nextstate;
-
- /* When connections fail but an error number cannot be reported
- * because the socket is non blocking we keep the connreq struct until
- * the status is queried with connect() again, we then return
- * this value */
- int err;
-
- /* Events that were set for this socket upon call to select() or
- * poll() */
- int selectevents;
-
- /* Buffer for sending and receiving on the socket */
- unsigned int datalen;
- unsigned int datadone;
- char buffer[2048];
-
- struct connreq *next;
-};
-
-/* Connection statuses */
-#define UNSTARTED 0
-#define CONNECTING 1
-#define CONNECTED 2
-#define SENDING 3
-#define RECEIVING 4
-#define SENTV4REQ 5
-#define GOTV4REQ 6
-#define SENTV5METHOD 7
-#define GOTV5METHOD 8
-#define SENTV5AUTH 9
-#define GOTV5AUTH 10
-#define SENTV5CONNECT 11
-#define GOTV5CONNECT 12
-#define DONE 13
-#define FAILED 14
-
-/* Flags to indicate what events a socket was select()ed for */
-#define READ (1<<0)
-#define WRITE (1<<1)
-#define EXCEPT (1<<2)
-#define READWRITE (READ|WRITE)
-#define READWRITEEXCEPT (READ|WRITE|EXCEPT)
-
-/* Global Declarations */
-extern dead_pool *pool;
-extern struct connreq *requests;
-
-struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
- struct sockaddr_in *serveraddr,
- struct serverent *path);
-void kill_socks_request(struct connreq *conn);
-struct connreq *find_socks_request(int sockid, int includefailed);
-int handle_request(struct connreq *conn);
-
-#endif
diff --git a/src.old/torsocks.c b/src.old/torsocks.c
deleted file mode 100644
index 597c107..0000000
--- a/src.old/torsocks.c
+++ /dev/null
@@ -1,1108 +0,0 @@
-/***************************************************************************
- * *
- * *
- * Copyright (C) 2000-2008 Shaun Clowes <delius(a)progsoc.org> *
- * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
- ***************************************************************************/
-
-/* PreProcessor Defines */
-#include <config.h>
-
-/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
-to Mac OS X 10.3's library and kernel calls as possible.*/
-#if defined(__APPLE__) || defined(__darwin__)
-/*
-From 'man compat' in OSX:
-64-BIT COMPILATION
- When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
- is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
- level). Defining _NONSTD_SOURCE will cause a compilation error.
-*/
-#if !defined(__LP64__)
-#define _NONSTD_SOURCE 1
-#endif
-#include <sys/socket.h>
-#endif
-
-
-#ifdef USE_GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-/* Global configuration variables */
-const char *torsocks_progname = "libtorsocks"; /* Name used in err msgs */
-
-/* Header Files */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <string.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <pwd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#if !defined(__APPLE__) && !defined(__darwin__)
-#include <sys/socket.h>
-#endif
-#include <resolv.h>
-
-#include "common.h"
-#include "dead_pool.h"
-#include "parser.h"
-#include "socks.h"
-
-/* Some function names are macroized on Darwin. Allow those names
- to expand accordingly. */
-#define EXPAND_GUTS(x) torsocks_##x##_guts
-#define EXPAND_GUTS_NAME(x) EXPAND_GUTS(x)
-
-/* Function prototypes for original functions that we patch */
-#ifdef SUPPORT_RES_API
-int (*realres_init)(void);
-#endif
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r (*real##n)(s##SIGNATURE);
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-#undef DARWIN_EXPANSION
-
-static struct parsedfile config;
-static int suid = 0;
-static char *conffile = NULL;
-
-/* Exported Function Prototypes */
-void __attribute__ ((constructor)) torsocks_init(void);
-
-/* Function prototypes for our patches */
-#ifdef SUPPORT_RES_API
-int res_init(void);
-#endif
-
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE);
-#define DARWIN_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE) __asm("_" m);
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-#undef DARWIN_EXPANSION
-
-/* Private Function Prototypes */
-/* no torsocks_res_init_guts */
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r torsocks_##b##_guts(s##SIGNATURE, r (*original_##b)(s##SIGNATURE));
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-
-static int get_config();
-static int get_environment();
-static int deadpool_init(void);
-
-static pthread_mutex_t torsocks_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void torsocks_init(void)
-{
- pthread_mutex_lock(&torsocks_init_mutex);
-
- show_msg(MSGDEBUG, "In torsocks_init \n");
-
- get_environment();
- get_config();
-
-#ifdef USE_OLD_DLSYM
- void *lib;
-#endif
-
- /* We could do all our initialization here, but to be honest */
- /* most programs that are run won't use our services, so */
- /* we do our general initialization on first call */
-
- /* Determine the logging level */
- suid = (getuid() != geteuid());
-
- dlerror();
-#ifndef USE_OLD_DLSYM
- #ifdef SUPPORT_RES_API
- torsocks_find_library("res_init", MSGERR, realres_init);
- #endif
- #define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) torsocks_find_library(m, MSG##e, real##n);
- #include "expansion_table.h"
- #undef PATCH_TABLE_EXPANSION
-#else
- lib = dlopen(LIBCONNECT, RTLD_LAZY);
- realconnect = dlsym(lib, "connect");
- realselect = dlsym(lib, "select");
- realpoll = dlsym(lib, "poll");
- realgethostbyname = dlsym(lib, "gethostbyname");
- realgethostbyaddr = dlsym(lib, "gethostbyaddr");
- realgetaddrinfo = dlsym(lib, "getaddrinfo");
- realgetipnodebyname = dlsym(lib, "getipnodebyname");
- realsendto = dlsym(lib, "sendto");
- realsendmsg = dlsym(lib, "sendmsg");
- dlclose(lib);
- lib = dlopen(LIBC, RTLD_LAZY);
- realclose = dlsym(lib, "close");
- dlclose(lib);
- #ifdef SUPPORT_RES_API
- lib = dlopen(LIBRESOLV, RTLD_LAZY);
- realres_init = dlsym(lib, "res_init");
- realresquery = dlsym(lib, "res_query");
- realressend = dlsym(lib, "res_send");
- realresquerydomain = dlsym(lib, "res_querydomain");
- realressearch = dlsym(lib, "res_search");
- dlclose(lib);
- #endif
-#endif
- /* Unfortunately, we can't do this lazily because otherwise our mmap'd
- area won't be shared across fork()s. */
- if (!deadpool_init()) {
- show_msg(MSGERR, "Fatal error: exiting\n");
- exit(1);
- }
-
- pthread_mutex_unlock(&torsocks_init_mutex);
-
- show_msg(MSGDEBUG, "Exit torsocks_init \n");
-}
-
-static int get_environment()
-{
- static int done = 0;
- int loglevel = MSGERR;
- char *logfile = NULL;
- char *env;
-
- if (done)
- return(0);
-
- /* Determine the logging level */
- if ((env = getenv("TORSOCKS_DEBUG")))
- loglevel = atoi(env);
- if (((env = getenv("TORSOCKS_DEBUG_FILE"))) && !suid)
- logfile = env;
- set_log_options(loglevel, logfile, (loglevel == MSGTEST) ? 0 : 1);
-
- done = 1;
-
- return(0);
-}
-
-static int get_config ()
-{
- static int done = 0;
-
- if (done)
- return(0);
-
- /* Determine the location of the config file */
-#ifdef ALLOW_ENV_CONFIG
- if (!suid)
- conffile = getenv("TORSOCKS_CONF_FILE");
-#endif
-
- /* Read in the config file */
- read_config(conffile, &config);
- if (config.paths)
- show_msg(MSGDEBUG, "First lineno for first path is %d\n", config.paths->lineno);
-
- done = 1;
-
- return(0);
-}
-
-/* Patch trampoline functions */
-/* no torsocks_res_init_guts */
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) \
- r n(s##SIGNATURE) { \
- if (!real##n) { \
- torsocks_find_library(m, MSG##e, real##n);\
- } \
- return torsocks_##b##_guts(s##ARGNAMES, real##n); \
- }
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-
-int torsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNATURE))
-{
- struct sockaddr_in *connaddr;
- struct sockaddr_in peer_address;
- struct sockaddr_in server_address;
- int gotvalidserver = 0, rc;
- socklen_t namelen = sizeof(peer_address);
- int sock_type = -1;
- socklen_t sock_type_len = sizeof(sock_type);
- int res = -1;
- struct serverent *path;
- struct connreq *newconn;
-
- /* If the real connect doesn't exist, we're stuffed */
- if (original_connect == NULL) {
- show_msg(MSGERR, "Unresolved symbol: connect\n");
- return(-1);
- }
-
- show_msg(MSGTEST, "Got connection request\n");
-
- connaddr = (struct sockaddr_in *) __addr;
-
- /* Get the type of the socket */
- getsockopt(__fd, SOL_SOCKET, SO_TYPE,
- (void *) &sock_type, &sock_type_len);
-
- show_msg(MSGDEBUG, "sin_family: %i\n", connaddr->sin_family);
-
- show_msg(MSGDEBUG, "sockopt: %i \n", sock_type);
-
- /* If the address is local refuse it. We do this because it could
- be a TCP DNS request to a local DNS server.*/
- if (!(is_local(&config, &(connaddr->sin_addr))) &&
- !is_dead_address(pool, connaddr->sin_addr.s_addr)) {
- char buf[16];
- inet_ntop(AF_INET, &(connaddr->sin_addr), buf, sizeof(buf));
- show_msg(MSGERR, "connect: Connection is to a local address (%s), 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.\n", buf);
- return -1;
- }
-
- /* If this is an INET6, we'll refuse it. */
- if ((connaddr->sin_family == AF_INET6)) {
- show_msg(MSGERR, "connect: Connection is IPv6: rejecting.\n");
- errno = EAFNOSUPPORT;
- return -1;
- }
-
- /* If this isn't an INET socket we can't */
- /* handle it, just call the real connect now */
- if ((connaddr->sin_family != AF_INET)) {
- show_msg(MSGDEBUG, "connect: Connection isn't IPv4, ignoring\n");
- return(original_connect(__fd, __addr, __len));
- }
-
- /* If this a UDP socket */
- /* then we refuse it, since it is probably a DNS request */
- if ((sock_type != SOCK_STREAM)) {
- show_msg(MSGERR, "connect: Connection is a UDP or ICMP stream, may be a "
- "DNS request or other form of leak: rejecting.\n");
- return -1;
- }
-
- /* If we haven't initialized yet, do it now */
- get_config();
-
- /* Are we already handling this connect? */
- if ((newconn = find_socks_request(__fd, 1))) {
- if (memcmp(&newconn->connaddr, connaddr, sizeof(*connaddr))) {
- /* Ok, they're calling connect on a socket that is in our
- * queue but this connect() isn't to the same destination,
- * they're obviously not trying to check the status of
- * they're non blocking connect, they must have close()d
- * the other socket and created a new one which happens
- * to have the same fd as a request we haven't had the chance
- * to delete yet, so we delete it here. */
- show_msg(MSGDEBUG, "Call to connect received on old "
- "torsocks request for socket %d but to "
- "new destination, deleting old request\n",
- newconn->sockid);
- kill_socks_request(newconn);
- } else {
- /* Ok, this call to connect() is to check the status of
- * a current non blocking connect(). */
- if (newconn->state == FAILED) {
- show_msg(MSGDEBUG, "Call to connect received on failed "
- "request %d, returning %d\n",
- newconn->sockid, newconn->err);
- errno = newconn->err;
- rc = -1;
- } else if (newconn->state == DONE) {
- show_msg(MSGERR, "Call to connect received on completed "
- "request %d\n",
- newconn->sockid, newconn->err);
- rc = 0;
- } else {
- show_msg(MSGDEBUG, "Call to connect received on current request %d\n",
- newconn->sockid);
- rc = handle_request(newconn);
- errno = rc;
- }
- if ((newconn->state == FAILED) || (newconn->state == DONE))
- kill_socks_request(newconn);
- return((rc ? -1 : 0));
- }
- }
-
- /* If the socket is already connected, just call connect */
- /* and get its standard reply */
- if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
- show_msg(MSGDEBUG, "Socket is already connected, defering to "
- "real connect\n");
- return(original_connect(__fd, __addr, __len));
- }
-
- show_msg(MSGDEBUG, "Got connection request for socket %d to "
- "%s\n", __fd, inet_ntoa(connaddr->sin_addr));
-
- /* Ok, so its not local, we need a path to the net */
- pick_server(&config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));
-
- show_msg(MSGDEBUG, "Picked server %s for connection\n",
- (path->address ? path->address : "(Not Provided)"));
- if (path->address == NULL) {
- if (path == &(config.defaultserver))
- show_msg(MSGERR, "Connection needs to be made "
- "via default server but "
- "the default server has not "
- "been specified\n");
- else
- show_msg(MSGERR, "Connection needs to be made "
- "via path specified at line "
- "%d in configuration file but "
- "the server has not been "
- "specified for this path\n",
- path->lineno);
- } else if ((res = resolve_ip(path->address, 0, 0)) == -1) {
- show_msg(MSGERR, "The SOCKS server (%s) listed in the configuration "
- "file which needs to be used for this connection "
- "is invalid\n", path->address);
- } else {
- /* Construct the addr for the socks server */
- server_address.sin_family = AF_INET; /* host byte order */
- server_address.sin_addr.s_addr = res;
- server_address.sin_port = htons(path->port);
- bzero(&(server_address.sin_zero), 8);
-
- /* Complain if this server isn't on a localnet */
- if (is_local(&config, &server_address.sin_addr)) {
- show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n",
- path->address, inet_ntoa(server_address.sin_addr));
- } else
- gotvalidserver = 1;
- }
-
- /* If we haven't found a valid server we return connection refused */
- if (!gotvalidserver ||
- !(newconn = new_socks_request(__fd, connaddr, &server_address, path))) {
- errno = ECONNREFUSED;
- return(-1);
- } else {
- /* Now we call the main function to handle the connect. */
- rc = handle_request(newconn);
- /* If the request completed immediately it mustn't have been
- * a non blocking socket, in this case we don't need to know
- * about this socket anymore. */
- if ((newconn->state == FAILED) || (newconn->state == DONE))
- kill_socks_request(newconn);
- errno = rc;
- /* We may get either of these if there are no bytes to read from
- the non-blocking connection in handle_request(). Since we are
- wrapping connect() here we can't return EWOULDBLOCK/EAGAIN
- so override it with something the client will accept.*/
- if (errno == EWOULDBLOCK || errno == EAGAIN)
- errno = EINPROGRESS;
- return((rc ? -1 : 0));
- }
-}
-
-int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE))
-{
- int nevents = 0;
- int rc = 0;
- int setevents = 0;
- int monitoring = 0;
- struct connreq *conn, *nextconn;
- fd_set mywritefds, myreadfds, myexceptfds;
-
- /* If we're not currently managing any requests we can just
- * leave here */
- if (!requests) {
- show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
- return(original_select(n, readfds, writefds, exceptfds, timeout));
- }
-
- 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);
-
- for (conn = requests; conn != NULL; conn = conn->next) {
- if ((conn->state == FAILED) || (conn->state == DONE))
- continue;
- conn->selectevents = 0;
- show_msg(MSGDEBUG, "Checking requests for socks enabled socket %d\n",
- conn->sockid);
- conn->selectevents |= (writefds ? (FD_ISSET(conn->sockid, writefds) ? WRITE : 0) : 0);
- conn->selectevents |= (readfds ? (FD_ISSET(conn->sockid, readfds) ? READ : 0) : 0);
- conn->selectevents |= (exceptfds ? (FD_ISSET(conn->sockid, exceptfds) ? EXCEPT : 0) : 0);
- if (conn->selectevents) {
- show_msg(MSGDEBUG, "Socket %d was set for events\n", conn->sockid);
- monitoring = 1;
- }
- }
-
- if (!monitoring)
- return(original_select(n, readfds, writefds, exceptfds, timeout));
-
- /* This is our select loop. In it we repeatedly call select(). We
- * pass select the same fdsets as provided by the caller except we
- * modify the fdsets for the sockets we're managing to get events
- * we're interested in (while negotiating with the socks server). When
- * events we're interested in happen we go off and process the result
- * ourselves, without returning the events to the caller. The loop
- * ends when an event which isn't one we need to handle occurs or
- * the select times out */
- do {
- /* Copy the clients fd events, we'll change them as we wish */
- if (readfds)
- memcpy(&myreadfds, readfds, sizeof(myreadfds));
- else
- FD_ZERO(&myreadfds);
- if (writefds)
- memcpy(&mywritefds, writefds, sizeof(mywritefds));
- else
- FD_ZERO(&mywritefds);
- if (exceptfds)
- memcpy(&myexceptfds, exceptfds, sizeof(myexceptfds));
- else
- FD_ZERO(&myexceptfds);
-
- /* Now enable our sockets for the events WE want to hear about */
- for (conn = requests; conn != NULL; conn = conn->next) {
- if ((conn->state == FAILED) || (conn->state == DONE) ||
- (conn->selectevents == 0))
- continue;
- /* We always want to know about socket exceptions */
- FD_SET(conn->sockid, &myexceptfds);
- /* If we're waiting for a connect or to be able to send
- * on a socket we want to get write events */
- if ((conn->state == SENDING) || (conn->state == CONNECTING))
- FD_SET(conn->sockid,&mywritefds);
- else
- FD_CLR(conn->sockid,&mywritefds);
- /* If we're waiting to receive data we want to get
- * read events */
- if (conn->state == RECEIVING)
- FD_SET(conn->sockid,&myreadfds);
- else
- FD_CLR(conn->sockid,&myreadfds);
- }
-
- nevents = original_select(n, &myreadfds, &mywritefds, &myexceptfds, timeout);
- /* If there were no events we must have timed out or had an error */
- if (nevents <= 0)
- break;
-
- /* Loop through all the sockets we're monitoring and see if
- * any of them have had events */
- for (conn = requests; conn != NULL; conn = nextconn) {
- nextconn = conn->next;
- if ((conn->state == FAILED) || (conn->state == DONE))
- continue;
- show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
- /* Clear all the events on the socket (if any), we'll reset
- * any that are necessary later. */
- setevents = 0;
- if (FD_ISSET(conn->sockid, &mywritefds)) {
- nevents--;
- setevents |= WRITE;
- show_msg(MSGDEBUG, "Socket had write event\n");
- FD_CLR(conn->sockid, &mywritefds);
- }
- if (FD_ISSET(conn->sockid, &myreadfds)) {
- nevents--;
- setevents |= READ;
- show_msg(MSGDEBUG, "Socket had write event\n");
- FD_CLR(conn->sockid, &myreadfds);
- }
- if (FD_ISSET(conn->sockid, &myexceptfds)) {
- nevents--;
- setevents |= EXCEPT;
- show_msg(MSGDEBUG, "Socket had except event\n");
- FD_CLR(conn->sockid, &myexceptfds);
- }
-
- if (!setevents) {
- show_msg(MSGDEBUG, "No events on socket %d\n", conn->sockid);
- continue;
- }
-
- if (setevents & EXCEPT)
- conn->state = FAILED;
- else
- rc = handle_request(conn);
-
- /* If the connection hasn't failed or completed there is nothing
- * to report to the client */
- if ((conn->state != FAILED) &&
- (conn->state != DONE))
- continue;
-
- /* Ok, the connection is completed, for good or for bad. We now
- * hand back the relevant events to the caller. We don't delete the
- * connection though since the caller should call connect() to
- * check the status, we delete it then */
-
- if (conn->state == FAILED) {
- /* Damn, the connection failed. Whatever the events the socket
- * was selected for we flag */
- if (conn->selectevents & EXCEPT) {
- FD_SET(conn->sockid, &myexceptfds);
- nevents++;
- }
- if (conn->selectevents & READ) {
- FD_SET(conn->sockid, &myreadfds);
- nevents++;
- }
- if (conn->selectevents & WRITE) {
- FD_SET(conn->sockid, &mywritefds);
- nevents++;
- }
- /* We should use setsockopt to set the SO_ERROR errno for this
- * socket, but this isn't allowed for some silly reason which
- * leaves us a bit hamstrung.
- * We don't delete the request so that hopefully we can
- * return the error on the socket if they call connect() on it */
- } else {
- /* The connection is done, if the client selected for
- * writing we can go ahead and signal that now (since the socket must
- * be ready for writing), otherwise we'll just let the select loop
- * come around again (since we can't flag it for read, we don't know
- * if there is any data to be read and can't be bothered checking) */
- if (conn->selectevents & WRITE) {
- FD_SET(conn->sockid, &mywritefds);
- nevents++;
- }
- }
- }
- } while (nevents == 0);
-
- show_msg(MSGDEBUG, "Finished intercepting select(), %d events\n", nevents);
-
- /* Now copy our event blocks back to the client blocks */
- if (readfds)
- memcpy(readfds, &myreadfds, sizeof(myreadfds));
- if (writefds)
- memcpy(writefds, &mywritefds, sizeof(mywritefds));
- if (exceptfds)
- memcpy(exceptfds, &myexceptfds, sizeof(myexceptfds));
-
- return(nevents);
-}
-
-int torsocks_poll_guts(POLL_SIGNATURE, int (*original_poll)(POLL_SIGNATURE))
-{
- int nevents = 0;
- int rc = 0;
- unsigned int i;
- int setevents = 0;
- int monitoring = 0;
- struct connreq *conn, *nextconn;
-
- /* If we're not currently managing any requests we can just
- * leave here */
- if (!requests)
- return(original_poll(ufds, nfds, timeout));
-
- 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);
-
- for (conn = requests; conn != NULL; conn = conn->next)
- conn->selectevents = 0;
-
- /* Record what events on our sockets the caller was interested
- * in */
- for (i = 0; i < nfds; i++) {
- if (!(conn = find_socks_request(ufds[i].fd, 0)))
- continue;
- show_msg(MSGDEBUG, "Have event checks for socks enabled socket %d\n",
- conn->sockid);
- conn->selectevents = ufds[i].events;
- monitoring = 1;
- }
-
- if (!monitoring)
- return(original_poll(ufds, nfds, timeout));
-
- /* This is our poll loop. In it we repeatedly call poll(). We
- * pass select the same event list as provided by the caller except we
- * modify the events for the sockets we're managing to get events
- * we're interested in (while negotiating with the socks server). When
- * events we're interested in happen we go off and process the result
- * ourselves, without returning the events to the caller. The loop
- * ends when an event which isn't one we need to handle occurs or
- * the poll times out */
- do {
- /* Enable our sockets for the events WE want to hear about */
- for (i = 0; i < nfds; i++) {
- if (!(conn = find_socks_request(ufds[i].fd, 0)))
- continue;
-
- /* We always want to know about socket exceptions but they're
- * always returned (i.e they don't need to be in the list of
- * wanted events to be returned by the kernel */
- ufds[i].events = 0;
-
- /* If we're waiting for a connect or to be able to send
- * on a socket we want to get write events */
- if ((conn->state == SENDING) || (conn->state == CONNECTING))
- ufds[i].events |= POLLOUT;
- /* If we're waiting to receive data we want to get
- * read events */
- if (conn->state == RECEIVING)
- ufds[i].events |= POLLIN;
- }
-
- nevents = original_poll(ufds, nfds, timeout);
- /* If there were no events we must have timed out or had an error */
- if (nevents <= 0)
- break;
-
- /* Loop through all the sockets we're monitoring and see if
- * any of them have had events */
- for (conn = requests; conn != NULL; conn = nextconn) {
- nextconn = conn->next;
- if ((conn->state == FAILED) || (conn->state == DONE))
- continue;
-
- /* Find the socket in the poll list */
- for (i = 0; ((i < nfds) && (ufds[i].fd != conn->sockid)); i++)
- /* Empty Loop */;
- if (i == nfds)
- continue;
-
- show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
-
- if (!ufds[i].revents) {
- show_msg(MSGDEBUG, "No events on socket\n");
- continue;
- }
-
- /* Clear any read or write events on the socket, we'll reset
- * any that are necessary later. */
- setevents = ufds[i].revents;
- if (setevents & POLLIN) {
- show_msg(MSGDEBUG, "Socket had read event\n");
- ufds[i].revents &= ~POLLIN;
- nevents--;
- }
- if (setevents & POLLOUT) {
- show_msg(MSGDEBUG, "Socket had write event\n");
- ufds[i].revents &= ~POLLOUT;
- nevents--;
- }
- if (setevents & (POLLERR | POLLNVAL | POLLHUP))
- show_msg(MSGDEBUG, "Socket had error event\n");
-
- /* Now handle this event */
- if (setevents & (POLLERR | POLLNVAL | POLLHUP)) {
- conn->state = FAILED;
- } else {
- rc = handle_request(conn);
- }
- /* If the connection hasn't failed or completed there is nothing
- * to report to the client */
- if ((conn->state != FAILED) &&
- (conn->state != DONE))
- continue;
-
- /* Ok, the connection is completed, for good or for bad. We now
- * hand back the relevant events to the caller. We don't delete the
- * connection though since the caller should call connect() to
- * check the status, we delete it then */
-
- if (conn->state == FAILED) {
- /* Damn, the connection failed. Just copy back the error events
- * from the poll call, error events are always valid even if not
- * requested by the client */
- /* We should use setsockopt to set the SO_ERROR errno for this
- * socket, but this isn't allowed for some silly reason which
- * leaves us a bit hamstrung.
- * We don't delete the request so that hopefully we can
- * return the error on the socket if they call connect() on it */
- } else {
- /* The connection is done, if the client polled for
- * writing we can go ahead and signal that now (since the socket must
- * be ready for writing), otherwise we'll just let the select loop
- * come around again (since we can't flag it for read, we don't know
- * if there is any data to be read and can't be bothered checking) */
- if (conn->selectevents & POLLOUT) {
- setevents |= POLLOUT;
- nevents++;
- }
- }
- }
- } while (nevents == 0);
-
- show_msg(MSGDEBUG, "Finished intercepting poll(), %d events\n", nevents);
-
- /* Now restore the events polled in each of the blocks */
- for (i = 0; i < nfds; i++) {
- if (!(conn = find_socks_request(ufds[i].fd, 1)))
- continue;
- ufds[i].events = conn->selectevents;
- }
-
- return(nevents);
-}
-
-int torsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE))
-{
- int rc;
- struct connreq *conn;
-
- /* If we're not currently managing any requests we can just
- * leave here */
- if (!requests) {
- show_msg(MSGDEBUG, "No requests waiting, calling real close\n");
- return(original_close(fd));
- }
-
- if (original_close == NULL) {
- show_msg(MSGERR, "Unresolved symbol: close\n");
- return(-1);
- }
-
- show_msg(MSGTEST, "Got call to close()\n");
- show_msg(MSGDEBUG, "Call to close(%d)\n", fd);
-
- rc = original_close(fd);
-
- /* If we have this fd in our request handling list we
- * remove it now */
- if ((conn = find_socks_request(fd, 1))) {
- show_msg(MSGDEBUG, "Call to close() received on file descriptor "
- "%d which is a connection request of status %d\n",
- conn->sockid, conn->state);
- kill_socks_request(conn);
- }
-
- return(rc);
-}
-
-/* If we are not done setting up the connection yet, return
- * -1 and ENOTCONN, otherwise call getpeername
- *
- * This is necessary since some applications, when using non-blocking connect,
- * (like ircII) use getpeername() to find out if they are connected already.
- *
- * This results in races sometimes, where the client sends data to the socket
- * before we are done with the socks connection setup. Another solution would
- * be to intercept send().
- *
- * This could be extended to actually set the peername to the peer the
- * client application has requested, but not for now.
- *
- * PP, Sat, 27 Mar 2004 11:30:23 +0100
- */
-
-int torsocks_getpeername_guts(GETPEERNAME_SIGNATURE,
- int (*original_getpeername)(GETPEERNAME_SIGNATURE))
-{
- struct connreq *conn;
- int rc;
-
- if (original_getpeername == NULL) {
- show_msg(MSGERR, "Unresolved symbol: getpeername\n");
- return(-1);
- }
-
- show_msg(MSGTEST, "Intercepted call to getpeername\n");
- show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
-
-
- rc = original_getpeername(__fd, __name, __namelen);
- if (rc == -1)
- return rc;
-
- /* Are we handling this connect? */
- if ((conn = find_socks_request(__fd, 1))) {
- /* While we are at it, we might was well try to do something useful */
- handle_request(conn);
-
- if (conn->state != DONE) {
- errno = ENOTCONN;
- return(-1);
- }
- }
- return rc;
-}
-
-#ifdef SUPPORT_RES_API
-int res_init(void)
-{
- int rc;
-
- if (!realres_init) {
- torsocks_find_library("res_init", MSGERR, realres_init);
- }
-
- show_msg(MSGTEST, "Got res_init request\n");
-
- if (realres_init == NULL) {
- show_msg(MSGERR, "Unresolved symbol: res_init\n");
- return(-1);
- }
- /* Call normal res_init */
- rc = realres_init();
-
- /* Force using TCP protocol for DNS queries */
- _res.options |= RES_USEVC;
- return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_query)(RES_QUERY_SIGNATURE, int (*original_res_query)(RES_QUERY_SIGNATURE))
-{
- int rc;
-
- if (!original_res_query) {
- torsocks_find_library("res_query", MSGERR, original_res_query);
- }
-
- show_msg(MSGTEST, "Got res_query request\n");
-
- if (original_res_query == NULL) {
- show_msg(MSGERR, "Unresolved symbol: res_query\n");
- return(-1);
- }
-
- /* Ensure we force using TCP for DNS queries by calling res_init
- above if it has not already been called.*/
- if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
- res_init();
-
- /* Call normal res_query */
- rc = original_res_query(dname, class, type, answer, anslen);
-
- return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_querydomain)(RES_QUERYDOMAIN_SIGNATURE, int (*original_res_querydomain)(RES_QUERYDOMAIN_SIGNATURE))
-{
- int rc;
-
- if (!original_res_querydomain) {
- torsocks_find_library("res_querydomain", MSGERR, original_res_querydomain);
- }
-
- show_msg(MSGDEBUG, "Got res_querydomain request\n");
-
- if (original_res_querydomain == NULL) {
- show_msg(MSGERR, "Unresolved symbol: res_querydomain\n");
- return(-1);
- }
-
- /* Ensure we force using TCP for DNS queries by calling res_init
- above if it has not already been called.*/
- if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
- res_init();
-
- /* Call normal res_querydomain */
- rc = original_res_querydomain(name, domain, class, type, answer, anslen);
-
- return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_search)(RES_SEARCH_SIGNATURE, int (*original_res_search)(RES_SEARCH_SIGNATURE))
-{
- int rc;
-
- if (!original_res_search) {
- torsocks_find_library("res_search", MSGERR, original_res_search);
- }
-
- show_msg(MSGTEST, "Got res_search request\n");
-
- if (original_res_search == NULL) {
- show_msg(MSGERR, "Unresolved symbol: res_search\n");
- return(-1);
- }
-
- /* Ensure we force using TCP for DNS queries by calling res_init
- above if it has not already been called.*/
- if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
- res_init();
-
- /* Call normal res_search */
- rc = original_res_search(dname, class, type, answer, anslen);
-
- return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_send)(RES_SEND_SIGNATURE, int (*original_res_send)(RES_SEND_SIGNATURE))
-{
- int rc;
-
- if (!original_res_send) {
- torsocks_find_library("res_send", MSGERR, original_res_send);
- }
-
- show_msg(MSGTEST, "Got res_send request\n");
-
- if (original_res_send == NULL) {
- show_msg(MSGERR, "Unresolved symbol: res_send\n");
- return(-1);
- }
-
- /* Ensure we force using TCP for DNS queries by calling res_init
- above if it has not already been called.*/
- if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
- res_init();
-
- /* Call normal res_send */
- rc = original_res_send(msg, msglen, answer, anslen);
-
- return(rc);
-}
-#endif
-
-static int deadpool_init(void)
-{
- if (pool)
- return 1;
-
- if (!config.tordns_enabled) {
- show_msg(MSGERR, "Tor DNS is disabled. Check your configuration.\n");
- return 0;
- }
-
- get_environment();
- get_config();
- pool = init_pool(config.tordns_cache_size,
- config.tordns_deadpool_range->localip,
- config.tordns_deadpool_range->localnet,
- config.defaultserver.address,
- config.defaultserver.port);
-
- if (!pool) {
- show_msg(MSGERR, "Could not initialize reserved addresses for "
- ".onion addresses. Torsocks will not work properly.\n");
- return 0;
- }
- return 1;
-}
-
-struct hostent *torsocks_gethostbyname_guts(GETHOSTBYNAME_SIGNATURE, struct hostent *(*original_gethostbyname)(GETHOSTBYNAME_SIGNATURE))
-{
- if (pool)
- return our_gethostbyname(pool, name);
- return original_gethostbyname(name);
-}
-
-struct hostent *torsocks_gethostbyaddr_guts(GETHOSTBYADDR_SIGNATURE, struct hostent *(*original_gethostbyaddr)(GETHOSTBYADDR_SIGNATURE))
-{
- if (pool)
- return our_gethostbyaddr(pool, addr, len, type);
- return original_gethostbyaddr(addr, len, type);
-}
-
-int torsocks_getaddrinfo_guts(GETADDRINFO_SIGNATURE, int (*original_getaddrinfo)(GETADDRINFO_SIGNATURE))
-{
- if (pool)
- return our_getaddrinfo(pool, node, service, hints, res);
- return original_getaddrinfo(node, service, hints, res);
-}
-
-struct hostent *torsocks_getipnodebyname_guts(GETIPNODEBYNAME_SIGNATURE, struct hostent *(*original_getipnodebyname)(GETIPNODEBYNAME_SIGNATURE))
-{
- if (pool)
- return our_getipnodebyname(pool, name, af, flags, error_num);
- return original_getipnodebyname(name, af, flags, error_num);
-}
-
-ssize_t torsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_SIGNATURE))
-{
- int sock_type = -1;
- unsigned int sock_type_len = sizeof(sock_type);
- struct sockaddr_in *connaddr;
-
- /* If the real sendto doesn't exist, we're stuffed */
- if (original_sendto == NULL) {
- show_msg(MSGERR, "Unresolved symbol: sendto\n");
- return(-1);
- }
-
- show_msg(MSGTEST, "Got sendto request\n");
-
- /* Get the type of the socket */
- getsockopt(s, SOL_SOCKET, SO_TYPE,
- (void *) &sock_type, &sock_type_len);
-
- show_msg(MSGDEBUG, "sockopt: %i\n", sock_type);
-
- /* If this a UDP socket then we refuse it, since it is probably a DNS
- request */
- if ((sock_type != SOCK_STREAM)) {
- show_msg(MSGERR, "sendto: Connection is a UDP or ICMP stream, may be a "
- "DNS request or other form of leak: rejecting.\n");
- return -1;
- }
-
- connaddr = (struct sockaddr_in *) to;
-
- /* If there is no address in 'to', sendto will only work if we
- already allowed the socket to connect(), so we let it through.
- Likewise if the socket is not an Internet connection. */
- if (connaddr && (connaddr->sin_family != AF_INET)) {
- show_msg(MSGDEBUG, "Connection isn't an Internet socket ignoring\n");
- }
-
- return (ssize_t) original_sendto(s, buf, len, flags, to, tolen);
-}
-
-ssize_t torsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDMSG_SIGNATURE))
-{
- int sock_type = -1;
- unsigned int sock_type_len = sizeof(sock_type);
- struct sockaddr_in *connaddr;
-
- /* If the real sendmsg doesn't exist, we're stuffed */
- if (original_sendmsg == NULL) {
- show_msg(MSGERR, "Unresolved symbol: sendmsg\n");
- return(-1);
- }
-
- show_msg(MSGTEST, "Got sendmsg request\n");
-
- /* Get the type of the socket */
- getsockopt(s, SOL_SOCKET, SO_TYPE,
- (void *) &sock_type, &sock_type_len);
-
- show_msg(MSGDEBUG, "sockopt: %i\n", sock_type);
-
- if ((sock_type != SOCK_STREAM)) {
- show_msg(MSGERR, "sendmsg: Connection is a UDP or ICMP stream, may be a "
- "DNS request or other form of leak: rejecting.\n");
- return -1;
- }
-
- connaddr = (struct sockaddr_in *) msg->msg_name;
-
- /* If there is no address in msg_name, sendmsg will only work if we
- already allowed the socket to connect(), so we let it through.
- Likewise if the socket is not an Internet connection. */
- if (connaddr && (connaddr->sin_family != AF_INET)) {
- show_msg(MSGDEBUG, "Connection isn't an Internet socket\n");
- }
-
- return (ssize_t) original_sendmsg(s, msg, flags);
-}
-
diff --git a/src.old/torsocks.in b/src.old/torsocks.in
deleted file mode 100755
index 4eaed8f..0000000
--- a/src.old/torsocks.in
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/bin/sh
-# ***************************************************************************
-# * *
-# * *
-# * Copyright (C) 2008 by Robert Hogan *
-# * robert(a)roberthogan.net *
-# * Copyright (C) 2012 by Jacob Appelbaum <jacob(a)torproject.org> *
-# * *
-# * 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. *
-# ***************************************************************************
-# * *
-# * This is a modified version of a source file from the Tor project. *
-# * Original copyright information follows: *
-# ***************************************************************************
-# Wrapper script for use of the torsocks(8) transparent socksification library
-#
-# There are three forms of usage for this script:
-#
-# @prefix@/bin/torsocks program [program arguments...]
-#
-# This form sets the users @LDPRELOAD@ environment variable so that torsocks(8)
-# will be loaded to socksify the application then executes the specified
-# program (with the provided arguments). The following simple example might
-# be used to telnet to www.foo.org via a torsocks.conf(5) configured socks server:
-#
-# @prefix@/bin/torsocks telnet www.foo.org
-#
-# The second form allows for torsocks(8) to be switched on and off for a
-# session (that is, it adds and removes torsocks from the @LDPRELOAD@ environment
-# variable). This form must be _sourced_ into the user's existing session
-# (and will only work with bourne shell users):
-#
-# . @prefix@/bin/torsocks on
-# telnet www.foo.org
-# . @prefix@/bin/torsocks off
-#
-# Or
-#
-# source @prefix@/bin/torsocks on
-# telnet www.foo.org
-# source @prefix@/bin/torsocks off
-#
-# The third form creates a new shell with @LDPRELOAD@ set and is achieved
-# simply by running the script with no arguments
-#
-# @prefix@/bin/torsocks
-#
-# When finished the user can simply terminate the shell with 'exit'
-#
-# This script is originally from the debian torsocks package by
-# Tamas Szerb <toma(a)rulez.org>
-# Modified by Robert Hogan <robert(a)roberthogan.net> April 16th 2006
-
-not_found () {
- echo "ERROR: $1 cannot be found in PATH." >&2
- exit 1
-}
-
-set_id () {
- echo "ERROR: $1 is set${2}id. torsocks will not work on a set${2}id executable." >&2
- exit 1
-}
-
-if [ $# = 0 ] ; then
- echo "$0: insufficient arguments"
- exit
-fi
-
-LIBDIR="@prefix@/lib/torsocks"
-LIB_NAME="libtorsocks"
-SHLIB_EXT="@SHLIB_EXT@"
-SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
-
-# Check for libtorsocks and if set the 64bit variant
-if [ ! -f $SHLIB ]; then
- LIBDIR="@prefix@/lib64/torsocks"
- SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
-fi
-
-# Ensure libtorsocks exists,
-if [ ! -f $SHLIB ]; then
- echo "$0: $SHLIB does not exist! Try re-installing torsocks."
- exit
-fi
-
-case "$1" in
- on)
- if [ -z "$@LDPRELOAD@" ]
- then
- export @LDPRELOAD@="${SHLIB}"
- else
- echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
- export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
- fi
- # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
- # not to set it at all on other platforms.
- export DYLD_FORCE_FLAT_NAMESPACE=1
- ;;
- off)
- #replace '/' with '\/' in @prefix@
- # escprefix=`echo '@prefix@' |sed 's/\\//\\\\\//g'`
- # export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s/$escprefix\/lib\/torsocks\/libtorsocks.so \?//"`
- export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s#@prefix@/lib/torsocks/libtorsocks\.@SHLIB_EXT@ *##"`
- if [ -z "$@LDPRELOAD@" ]
- then
- unset @LDPRELOAD@
- # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
- # not to set it at all on other platforms.
- unset DYLD_FORCE_FLAT_NAMESPACE=1
- fi
- ;;
- show|sh)
- echo "@LDPRELOAD@=\"$@LDPRELOAD@\""
- ;;
- -h|-?)
- echo "$0: Please see torsocks(1) or read comment at top of $0"
- ;;
- --shell)
- if [ -z "$@LDPRELOAD@" ]
- then
- export @LDPRELOAD@="${SHLIB}"
- else
- echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
- export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
- fi
- export DYLD_FORCE_FLAT_NAMESPACE=1
- echo "torsocks: new torified shell coming right up..."
- ${SHELL:-/bin/sh}
- ;;
- *)
- if [ -z "$@LDPRELOAD@" ]
- then
- export @LDPRELOAD@="${SHLIB}"
- else
- echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
- export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
- fi
- export DYLD_FORCE_FLAT_NAMESPACE=1
-
- if [ $# -gt 0 ]
- then
- if ! which "$1" >/dev/null 2>&1; then
- not_found $1
- elif [ -u `which "$1"` ]; then
- set_id $1 u
- elif [ -g `which "$1"` ]; then
- set_id $1 g
- fi
- exec "$@"
- fi
- ;;
-esac
-
-#EOF
diff --git a/src.old/usewithtor.in b/src.old/usewithtor.in
deleted file mode 100644
index e606760..0000000
--- a/src.old/usewithtor.in
+++ /dev/null
@@ -1,113 +0,0 @@
-#! /bin/sh
-# ***************************************************************************
-# * *
-# * Copyright (C) 2008-2011 Robert Hogan <robert(a)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. *
-# ***************************************************************************
-# * *
-# * This is a modified version of a source file from the Tor project. *
-# * Original copyright notice from tsocks source file follows: *
-# ***************************************************************************
-
-# Wrapper script for use of the tsocks(8) transparent socksification library
-# See the tsocks(1) and torify(1) manpages.
-
-# Copyright (c) 2004, 2006 Peter Palfrader
-# Modified by Jacob Appelbaum <jacob(a)appelbaum.net> April 16th 2006
-# Modified by Marcus Griep <marcus(a)griep.us> June 16 2009
-# May be distributed under the same terms as Tor itself
-
-
-# Define and ensure we have tsocks
-# XXX: what if we don't have which?
-TORSOCKS="`which torsocks`"
-PROG=
-VERBOSE=
-
-usage () {
- echo "Usage: $0 [-hv] <command> [<options>...]"
-}
-
-not_found () {
- echo "ERROR: $1 cannot be found in PATH." >&2
- exit 1
-}
-
-set_id () {
- echo "ERROR: $1 is set${2}id. usewithtor will not work on a set${2}id executable." >&2
- exit 1
-}
-
-# Check for any argument list
-if [ "$#" = 0 ]; then
- usage >&2
- exit 1
-fi
-
-while [ "$1" ]; do
- case "$1" in
- -h|--h*)
- usage
- exit 0
- ;;
- -v|--v*)
- VERBOSE=YesPlease
- shift
- ;;
- *)
- break;
- esac
-done
-
-if ! which "$1" >/dev/null 2>&1; then
- not_found $1
-elif [ -u `which "$1"` ]; then
- set_id $1 u
-elif [ -g `which "$1"` ]; then
- set_id $1 g
-fi
-
-if [ -x "$TORSOCKS" ]; then
- PROG=torsocks
-else
- echo "$0: Unable to find torsocks in PATH." >&2
- echo " Perhaps you haven't installed it?" >&2
- exit 1
-fi
-
-if [ "$VERBOSE" ]; then
- echo "We're armed with the following torsocks: $TORSOCKS"
- echo "We're attempting to use $PROG for all tor action."
-fi
-
-if [ "$PROG" = "torsocks" ]; then
- # Define our torsocks config file
- TORSOCKS_CONF_FILE="@CONFDIR@/torsocks.conf"
- export TORSOCKS_CONF_FILE
-
- # Check that we've got a torsocks config file
- if [ -r "$TORSOCKS_CONF_FILE" ]; then
- exec torsocks "$@"
- else
- echo "$0: Missing torsocks configuration file \"$TORSOCKS_CONF_FILE\" - torsocks will use defaults sensible for Tor." >&2
- exec torsocks "$@"
- fi
-fi
-
-# We should have hit an exec. If we get here, we didn't exec
-echo "$0: failed to exec $PROG $@" >&2
-exit 1
1
0
commit 91c148690e4c8bd1e5e948f0c758570891f49ddd
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Fri Apr 4 18:12:46 2014 -0400
Update version to v2.0.0-rc7
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
ChangeLog | 14 ++++++++++++++
configure.ac | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index c88f270..41a93b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2014-04-04 torsocks 2.0.0-rc7
+ * Fix: fix NULL dereference on error
+ * Fix: memory leak in connect error path
+ * Delete old source directory
+ * Fix: nullify constant that might be undefined
+ * Refactor the connect() code flow for clarity
+ * Tests: add connect() test
+ * Tests: add socket() test
+ * Fix: socketpair() denied for INET[6] socket
+ * Fix: socket() type check SOCK_STREAM
+ * Fix: add autogen.sh to installation procedures
+ * Fix: change TSOCKS_LOOPBACK bitness
+ * Fix: support kfreebsd for mmap()
+
2014-03-17 torsocks 2.0.0-rc6
* Fix: set addr len for getsockname in accept
* Fix: use socket fd and NOT sockaddr in accept
diff --git a/configure.ac b/configure.ac
index 1444cc7..1e8982e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@
##############################################################################
# Process this file with autoconf to produce a configure script.
-AC_INIT([torsocks], [2.0.0-rc6],[dgoulet@ev0ke.net],[],[https://torproject.org])
+AC_INIT([torsocks], [2.0.0-rc7],[dgoulet@ev0ke.net],[],[https://torproject.org])
AC_CONFIG_AUX_DIR([config])
AC_CANONICAL_TARGET
# Get hostname and other information.
1
0
commit 6adfba809267d9c217906d6974468db22293ab9b
Author: Thomas Klausner <wiz(a)NetBSD.org>
Date: Wed Nov 6 18:26:39 2013 -0500
Add NetBSD support
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/common/compat.c | 4 ++--
src/common/compat.h | 12 ++++++++----
src/common/ref.h | 2 +-
src/lib/torsocks.h | 8 ++++----
tests/utils/tap/tap.c | 2 +-
5 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/common/compat.c b/src/common/compat.c
index b4cdd1d..7d8431d 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -19,7 +19,7 @@
#include "compat.h"
-#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__))
+#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__) || defined(__NetBSD__))
/*
* Initialize a pthread mutex. This never fails.
@@ -71,4 +71,4 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m)
assert(!ret);
}
-#endif /* __GLIBC__, __darwin__, __FreeBSD__ */
+#endif /* __GLIBC__, __darwin__, __FreeBSD__, __NetBSD__ */
diff --git a/src/common/compat.h b/src/common/compat.h
index 2eacb35..9173caf 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -22,7 +22,7 @@
#define __darwin__ 1
#endif
-#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__))
+#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__) || defined(__NetBSD__))
#define RTLD_NEXT ((void *) -1)
@@ -43,7 +43,7 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#else
#error "OS not supported."
-#endif /* __GLIBC__, __darwin__, __FreeBSD__ */
+#endif /* __GLIBC__, __darwin__, __FreeBSD__, __NetBSD__ */
#if defined(__linux__)
@@ -84,17 +84,21 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#endif /* __linux__ */
-#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__darwin__))
+#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__darwin__) || defined(__NetBSD__))
#include <sys/syscall.h>
#include <unistd.h>
+#if defined(__NetBSD__)
+#define SYS_socket SYS___socket30
+#endif
+
#define TSOCKS_NR_SOCKET SYS_socket
#define TSOCKS_NR_CONNECT SYS_connect
#define TSOCKS_NR_CLOSE SYS_close
#define TSOCKS_NR_MMAP SYS_mmap
#define TSOCKS_NR_MUNMAP SYS_munmap
-#endif /* __FreeBSD__, __FreeBSD_kernel__, __darwin__ */
+#endif /* __FreeBSD__, __FreeBSD_kernel__, __darwin__, __NetBSD__ */
#endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/ref.h b/src/common/ref.h
index f80fd19..88aec2e 100644
--- a/src/common/ref.h
+++ b/src/common/ref.h
@@ -26,7 +26,7 @@ struct ref {
long count;
};
-#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__))
+#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__) || defined(__NetBSD__))
/*
* Get a reference by incrementing the refcount.
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index a931d2a..78dc3ec 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -33,7 +33,7 @@
#define TSOCKS_DECL(name, type, sig) \
extern type tsocks_##name(sig);
-#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__))
+#if (defined(__GLIBC__) || defined(__FreeBSD__) || defined(__darwin__) || defined(__NetBSD__))
/* connect(2) */
#include <sys/types.h>
@@ -171,7 +171,7 @@ struct hostent **__result, int *__h_errnop
#else
#error "OS not supported."
-#endif /* __GLIBC__ , __FreeBSD__, __darwin__ */
+#endif /* __GLIBC__ , __FreeBSD__, __darwin__, __NetBSD__ */
#if (defined(__linux__))
@@ -186,7 +186,7 @@ struct hostent **__result, int *__h_errnop
#endif /* __linux__ */
-#if (defined(__FreeBSD__) || defined(__darwin__))
+#if (defined(__FreeBSD__) || defined(__darwin__) || defined(__NetBSD__))
/* syscall(2) */
#define LIBC_SYSCALL_NAME syscall
@@ -195,7 +195,7 @@ struct hostent **__result, int *__h_errnop
#define LIBC_SYSCALL_SIG int __number, ...
#define LIBC_SYSCALL_ARGS __number
-#endif /* __FreeBSD__, __darwin__ */
+#endif /* __FreeBSD__, __darwin__, __NetBSD__ */
#if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
diff --git a/tests/utils/tap/tap.c b/tests/utils/tap/tap.c
index 8bf72f6..d52cb03 100644
--- a/tests/utils/tap/tap.c
+++ b/tests/utils/tap/tap.c
@@ -94,7 +94,7 @@ _gen_result(int ok, const char *func, char *file, unsigned int line,
if(local_test_name) {
name_is_digits = 1;
for(c = local_test_name; *c != '\0'; c++) {
- if(!isdigit(*c) && !isspace(*c)) {
+ if(!isdigit((unsigned char)*c) && !isspace((unsigned char)*c)) {
name_is_digits = 0;
break;
}
1
0