From 318840c449ae74bd4899173ce4e2bc30ad6c4947 Mon Sep 17 00:00:00 2001 From: basil00 Date: Wed, 17 Sep 2014 17:59:00 +0800 Subject: [PATCH] - Add a "traffic.deny" file that specifies what traffic to block via Tor. --- README.md | 2 +- build.sh | 4 +++ install.nsi | 4 +++ redirect.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++--- traffic.deny | 13 ++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 traffic.deny diff --git a/README.md b/README.md index 76dd1b2..d9bfbac 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ To build Tallow you need the MinGW cross-compiler for Linux. You also need to download and place the following external dependencies and place them in the contrib/ directory: -* [WinDivert-1.1.5-MINGW.zip](http://reqrypt.org/windivert.html). +* [WinDivert-1.1.6-MINGW.zip](http://reqrypt.org/windivert.html). * The following files extracted from the [Tor Expert Bundle](https://www.torproject.org/): - tor.exe diff --git a/build.sh b/build.sh index 4a38ee8..cb2ecb7 100644 --- a/build.sh +++ b/build.sh @@ -53,6 +53,10 @@ echo "Copying \"tallow.exe\"..." cp tallow.exe install/. echo "Copying \"hosts.deny\"..." cp hosts.deny install/. +echo "Copying \"traffic.deny\"..." +cp traffic.deny install/. +echo "Copying \"LICENSE\"..." +cp LICENSE install/. for FILE in "$TOR.exe" \ "$WINDIVERT/amd64/WinDivert64.sys" \ diff --git a/install.nsi b/install.nsi index bc14efa..f903cf0 100644 --- a/install.nsi +++ b/install.nsi @@ -41,6 +41,8 @@ Section "" File "WinDivert64.sys" File "WinDivert.dll" File "hosts.deny" + File "traffic.deny" + File "LICENSE" WriteUninstaller "TallowBundle-uninstall.exe" WriteRegStr HKLM \ "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tallow" \ @@ -58,6 +60,8 @@ Section "Uninstall" Delete "$INSTDIR\WinDivert64.sys" Delete "$INSTDIR\WinDivert.dll" Delete "$INSTDIR\hosts.deny" + Delete "$INSTDIR\traffic.deny" + Delete "$INSTDIR\LICENSE" Delete "$INSTDIR\TallowBundle-uninstall.exe" RMDir "$INSTDIR\" DeleteRegKey HKCU "Software\Tallow" diff --git a/redirect.c b/redirect.c index 3bdb05c..9ae6487 100644 --- a/redirect.c +++ b/redirect.c @@ -29,6 +29,7 @@ #define MAX_PACKET 0xFFFF #define NUM_WORKERS 4 +#define MAX_FILTER (1024-1) // SOCKS4a headers #define SOCKS_USERID_SIZE (256 + 8) @@ -111,10 +112,12 @@ static void socks4a_connect_1_of_2(struct conn *conn, HANDLE handle, static void socks4a_connect_2_of_2(struct conn *conn, HANDLE handle, PWINDIVERT_ADDRESS addr, PWINDIVERT_IPHDR iphdr, PWINDIVERT_TCPHDR tcphdr, struct socks4a_rep *sockshdr); +extern bool filter_read(char *filter, size_t len); static void queue_cleanup(uint32_t addr, uint16_t port); static void debug_addr(uint32_t addr, uint16_t port); // State: +static char filter[MAX_FILTER+1]; static bool redirect_on = false; static HANDLE handle = INVALID_HANDLE_VALUE; static HANDLE handle_drop = INVALID_HANDLE_VALUE; @@ -181,6 +184,21 @@ extern void redirect_init(void) warning("failed to open WinDivert filter"); exit(EXIT_FAILURE); } + + // Read the filter: + if (!filter_read(filter, sizeof(filter))) + { + // Use the default filter: + const char *default_filter = "ipv6 or (not tcp and udp.DstPort != 53)"; + size_t len = strlen(default_filter); + if (len+1 > sizeof(filter)) + { + warning("failed to create default filter"); + exit(EXIT_FAILURE); + } + memcpy(filter, default_filter, len+1); + } + debug("Filter is \"%s\"\n", filter); } // Start traffic redirect through Tor: @@ -191,10 +209,9 @@ extern void redirect_start(void) if (handle != INVALID_HANDLE_VALUE) return; - // Drop traffic we cannot handle: - handle_drop = WinDivertOpen( - "ip.DstAddr != 127.0.0.1 and (ipv6 or (not tcp and udp.DstPort != 53))", - WINDIVERT_LAYER_NETWORK, -753, WINDIVERT_FLAG_DROP); + // Drop traffic from the loaded filter: + handle_drop = WinDivertOpen(filter, WINDIVERT_LAYER_NETWORK, -753, + WINDIVERT_FLAG_DROP); if (handle_drop == INVALID_HANDLE_VALUE) { redirect_start_error: @@ -774,6 +791,53 @@ extern void redirect_cleanup(size_t count) } } +// Read traffic filter. +extern bool filter_read(char *filter, size_t len) +{ + const char *filename = "traffic.deny"; + FILE *stream = fopen(filename, "r"); + if (stream == NULL) + { + warning("failed to read \"%s\" for reading", filename); + return false; + } + + int c; + size_t i = 0; + while (true) + { + c = getc(stream); + switch (c) + { + case EOF: + { + if (i >= len) + goto length_error; + filter[i++] = '\0'; + fclose(stream); + return true; + } + case '#': + while ((c = getc(stream)) != '\n' && c != EOF) + ; + continue; + case '\n': + continue; + default: + break; + } + if (i >= len) + goto length_error; + filter[i++] = c; + } + +length_error: + + warning("failed to read \"%s\"; filter length is too long (max=%u)", + filename, len); + return false; +} + // Debug address: static void debug_addr(uint32_t addr, uint16_t port) { diff --git a/traffic.deny b/traffic.deny new file mode 100644 index 0000000..2193c34 --- /dev/null +++ b/traffic.deny @@ -0,0 +1,13 @@ +# This file specifies what traffic is *dropped* when Tor diversion is enabled. + +# Notes: +# - This file uses the WinDivert filter language, see: +# (reqrypt.org/windivert-doc.html) for more information. +# - This is filter in addition to "web-only" mode; the two filters operate +# independently. +# - ipv6 and non-tcp (except port 53 UDP) will be dropped regardless of what +# this file specifies. However, it is more efficient to filter such +# traffic here. + +ipv6 or (not tcp and udp.DstPort != 53) +