From b079b0eda52abe666471d999bd7304e0003652b1 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 29 May 2014 16:18:41 +0200 Subject: [PATCH 01/64] Fix build error and a warning on OpenBSD --- src/common.c | 4 ++-- src/tun.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common.c b/src/common.c index 5f202da..6b74c64 100644 --- a/src/common.c +++ b/src/common.c @@ -149,8 +149,8 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora memset(&hints, 0, sizeof(hints)); hints.ai_family = addr_family; -#ifdef WINDOWS32 - /* AI_ADDRCONFIG misbehaves on windows */ +#if defined(WINDOWS32) || defined(OPENBSD) + /* AI_ADDRCONFIG misbehaves on windows, and does not exist in OpenBSD */ hints.ai_flags = flags; #else hints.ai_flags = AI_ADDRCONFIG | flags; diff --git a/src/tun.c b/src/tun.c index bc5c153..53f52dc 100644 --- a/src/tun.c +++ b/src/tun.c @@ -440,6 +440,7 @@ tun_setip(const char *ip, const char *other_ip, int netbits) int i; #ifndef LINUX int r; + struct in_addr netip; #endif #ifdef WINDOWS32 DWORD status; @@ -475,7 +476,6 @@ tun_setip(const char *ip, const char *other_ip, int netbits) fprintf(stderr, "Setting IP of %s to %s\n", if_name, ip); #ifndef LINUX - struct in_addr netip; netip.s_addr = inet_addr(ip); netip.s_addr = netip.s_addr & net.s_addr; r = system(cmdline); From b3f8e7118ac1ab8e2a188cce3a2c038834508323 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 29 May 2014 17:41:43 +0200 Subject: [PATCH 02/64] Do not set CC in tests --- tests/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index d40f4c7..07210dc 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,3 @@ -CC = gcc TEST = test OBJS = test.o base32.o base64.o common.o read.o dns.o encoding.o login.o user.o fw_query.o SRCOBJS = ../src/base32.o ../src/base64.o ../src/common.o ../src/read.o ../src/dns.o ../src/encoding.o ../src/login.o ../src/md5.o ../src/user.o ../src/fw_query.o From d6c3426b84dd74c093987b3dc5b3a2cd4f97111d Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 29 May 2014 18:37:40 +0200 Subject: [PATCH 03/64] Set C standard to C99 Also include strings.h where strcasecmp() is used --- src/Makefile | 2 +- src/client.c | 1 + src/dns.c | 1 + src/iodined.c | 1 + src/osflags | 2 +- tests/Makefile | 2 +- 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 5fbfbbd..83c00e5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,7 +10,7 @@ HEAD_COMMIT = `git rev-parse --short HEAD` LIBPATH = -L. LDFLAGS += -lz `sh osflags $(TARGETOS) link` $(LIBPATH) -CFLAGS += -c -g -Wall -D$(OS) -pedantic `sh osflags $(TARGETOS) cflags` -DGITREVISION=\"$(HEAD_COMMIT)\" +CFLAGS += -std=c99 -c -g -Wall -D$(OS) -pedantic `sh osflags $(TARGETOS) cflags` -DGITREVISION=\"$(HEAD_COMMIT)\" all: stateos $(CLIENT) $(SERVER) diff --git a/src/client.c b/src/client.c index efb0f51..e3a1479 100644 --- a/src/client.c +++ b/src/client.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/src/dns.c b/src/dns.c index bd1257f..2bd4a2c 100644 --- a/src/dns.c +++ b/src/dns.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #ifdef WINDOWS32 diff --git a/src/iodined.c b/src/iodined.c index 75979d9..6ebf3a6 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/src/osflags b/src/osflags index 2d8a03b..9eda8f0 100755 --- a/src/osflags +++ b/src/osflags @@ -33,7 +33,7 @@ cflags) echo '-Dsocklen_t=int'; ;; Linux) - FLAGS=""; + FLAGS="-D_GNU_SOURCE" [ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -DHAVE_SETCON"; [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS -DHAVE_SYSTEMD"; echo $FLAGS; diff --git a/tests/Makefile b/tests/Makefile index 07210dc..43310eb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -6,7 +6,7 @@ OS = `uname | tr "a-z" "A-Z"` CHECK_PATH = /usr/local LDFLAGS = -L$(CHECK_PATH)/lib `pkg-config check --libs` -lpthread `sh ../src/osflags $(TARGETOS) link` -CFLAGS = -g -Wall -D$(OS) `pkg-config check --cflags` -I../src -I$(CHECK_PATH)/include -pedantic `sh ../src/osflags $(TARGETOS) cflags` +CFLAGS = -std=c99 -g -Wall -D$(OS) `pkg-config check --cflags` -I../src -I$(CHECK_PATH)/include -pedantic `sh ../src/osflags $(TARGETOS) cflags` all: $(TEST) @LD_LIBRARY_PATH=${CHECK_PATH}/lib ./$(TEST) From c1b24abf3a949f5dc0044341efdfbd2218b3625e Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 29 May 2014 19:08:20 +0200 Subject: [PATCH 04/64] Update changelog --- CHANGELOG | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6d5c4d0..ad85947 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,9 +6,9 @@ iodine - http://code.kryo.se/iodine CHANGES: master: - - IPv6 support (in progress, #107) - Client can connect to iodined through an IPv6 nameserver. - Server only supports IPv4 for now. + - Partial IPv6 support (#107) + Client can connect to iodined through an relaying IPv6 + nameserver. Server only supports IPv4 for now. Traffic inside tunnel is IPv4. - Add socket activation for systemd, by Michael Scherer. - Add automated lookup of external ip (via -n auto). @@ -20,6 +20,9 @@ master: Patch by laurent at gouloum fr, fixes #95. - Add android patches and makefile, from Marcel Bokhorst, fixes #105. - Added missing break in iodine.c, by Pavel Pergamenshchik, #108. + - A number of minor patches from Frank Denis, Gregor Herrmann and + Barak A. Pearlmutter. + - Testcase compilation fixes for OS X and FreeBSD 2010-02-06: 0.6.0-rc1 "Hotspotify" - Fixed tunnel not working on Windows. From bacb69e4f0c544d74993f573de74a4ab0bd35082 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 29 May 2014 23:21:55 +0200 Subject: [PATCH 05/64] Mark usage() method as noreturn to avoid warning on BSD Warning from OpenBSD/NetBSD: CC iodine.c iodine.c: In function 'main': iodine.c:141:6: warning: 'nameservaddr_len' may be used uninitialized in this function --- src/iodine.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/iodine.c b/src/iodine.c index 519eac3..0975739 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -57,6 +57,12 @@ sighandler(int sig) client_stop(); } +#if defined(__GNUC__) || defined(__clang__) +/* mark as no return to help some compilers to avoid warnings + * about use of uninitialized variables */ +static void usage() __attribute__((noreturn)); +#endif + static void usage() { extern char *__progname; From 9bb2323f844e0dd8e72c141c8da454e604bf9584 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Fri, 30 May 2014 00:18:45 +0200 Subject: [PATCH 06/64] Improve check of topdomain to use Add more checks and unit tests --- src/common.c | 36 +++++++++++++++++++++-------- tests/common.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/src/common.c b/src/common.c index 6b74c64..b4772bb 100644 --- a/src/common.c +++ b/src/common.c @@ -326,18 +326,34 @@ read_password(char *buf, size_t len) int check_topdomain(char *str) { - int i; + int i; + int dots = 0; + int chunklen = 0; - if(str[0] == '.') /* special case */ - return 1; + if (strlen(str) < 3) + return 1; + if (strlen(str) > 128) + return 1; - for( i = 0; i < strlen(str); i++) { - if( isalpha(str[i]) || isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) - continue; - else - return 1; - } - return 0; + for( i = 0; i < strlen(str); i++) { + if(str[i] == '.') { + dots++; + /* This will also catch the case where topdomain starts with a dot */ + if (chunklen == 0 || chunklen > 63) + return 1; + chunklen = 0; + } else + chunklen++; + if( isalpha(str[i]) || isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) + continue; + else + return 1; + } + + if (chunklen == 0 || chunklen > 63 || dots == 0) + return 1; + + return 0; } #if defined(WINDOWS32) || defined(ANDROID) diff --git a/tests/common.c b/tests/common.c index 92f2d4c..9c84e4a 100644 --- a/tests/common.c +++ b/tests/common.c @@ -4,6 +4,65 @@ #include #include +START_TEST(test_topdomain_ok) +{ + fail_if(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com")); + + /* Not allowed to start with dot */ + fail_unless(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com")); +} +END_TEST + +START_TEST(test_topdomain_length) +{ + /* Test empty and too short */ + fail_unless(check_topdomain("")); + fail_unless(check_topdomain("a")); + fail_unless(check_topdomain(".a")); + fail_unless(check_topdomain("a.")); + fail_unless(check_topdomain("ab")); + fail_if(check_topdomain("a.b")); + + /* Test too long (over 128, need rest of space for data) */ + fail_unless(check_topdomain( + "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." + "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." + "abcd12345.abcd12345.foo129xxx")); + fail_if(check_topdomain( + "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." + "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." + "abcd12345.abcd12345.foo128xx")); +} +END_TEST + +START_TEST(test_topdomain_chunks) +{ + /* Must have at least one dot */ + fail_if(check_topdomain("abcde.gh")); + fail_unless(check_topdomain("abcdefgh")); + + /* Not two consecutive dots */ + fail_unless(check_topdomain("abc..defgh")); + + /* Not end with a dots */ + fail_unless(check_topdomain("abc.defgh.")); + + /* No chunk longer than 63 chars */ + fail_unless(check_topdomain("123456789012345678901234567890" + "1234567890123456789012345678904444.com")); + fail_if(check_topdomain("123456789012345678901234567890" + "123456789012345678901234567890333.com")); + fail_unless(check_topdomain("abc.123456789012345678901234567890" + "1234567890123456789012345678904444.com")); + fail_if(check_topdomain("abc.123456789012345678901234567890" + "123456789012345678901234567890333.com")); + fail_unless(check_topdomain("abc.123456789012345678901234567890" + "1234567890123456789012345678904444")); + fail_if(check_topdomain("abc.123456789012345678901234567890" + "123456789012345678901234567890333")); +} +END_TEST + START_TEST(test_parse_format_ipv4) { char *host = "192.168.2.10"; @@ -102,6 +161,9 @@ test_common_create_tests() int sock; tc = tcase_create("Common"); + tcase_add_test(tc, test_topdomain_ok); + tcase_add_test(tc, test_topdomain_length); + tcase_add_test(tc, test_topdomain_chunks); tcase_add_test(tc, test_parse_format_ipv4); tcase_add_test(tc, test_parse_format_ipv4_listen_all); From 3914d37c993159feda1d6d7831632017f8ed2820 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 10:06:44 +0200 Subject: [PATCH 07/64] Move error message generation into topdomain check method Change isalpha() to a-z check to avoid locale issues --- src/common.c | 46 ++++++++++++++++++++++++++------- src/common.h | 2 +- src/iodine.c | 12 +++------ src/iodined.c | 12 ++++----- tests/common.c | 69 ++++++++++++++++++++++++++++++++++---------------- 5 files changed, 94 insertions(+), 47 deletions(-) diff --git a/src/common.c b/src/common.c index b4772bb..b15fb7a 100644 --- a/src/common.c +++ b/src/common.c @@ -324,34 +324,62 @@ read_password(char *buf, size_t len) } int -check_topdomain(char *str) +check_topdomain(char *str, char **errormsg) { int i; int dots = 0; int chunklen = 0; - if (strlen(str) < 3) + if (strlen(str) < 3) { + if (errormsg) *errormsg = "Too short (< 3)"; return 1; - if (strlen(str) > 128) + } + if (strlen(str) > 128) { + if (errormsg) *errormsg = "Too long (> 128)"; return 1; + } + + if (str[0] == '.') { + if (errormsg) *errormsg = "Starts with a dot"; + return 1; + } for( i = 0; i < strlen(str); i++) { if(str[i] == '.') { dots++; - /* This will also catch the case where topdomain starts with a dot */ - if (chunklen == 0 || chunklen > 63) + if (chunklen == 0) { + if (errormsg) *errormsg = "Consecutive dots"; return 1; + } + if (chunklen > 63) { + if (errormsg) *errormsg = "Too long domain part (> 63)"; + return 1; + } chunklen = 0; - } else + } else { chunklen++; - if( isalpha(str[i]) || isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) + } + if( (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || + isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) { continue; - else + } else { + if (errormsg) *errormsg = "Contains illegal character (allowed: [a-zA-Z0-9-.])"; return 1; + } } - if (chunklen == 0 || chunklen > 63 || dots == 0) + if (dots == 0) { + if (errormsg) *errormsg = "No dots"; return 1; + } + if (chunklen == 0) { + if (errormsg) *errormsg = "Ends with a dot"; + return 1; + } + if (chunklen > 63) { + if (errormsg) *errormsg = "Too long domain part (> 63)"; + return 1; + } return 0; } diff --git a/src/common.h b/src/common.h index bbadc9f..534996c 100644 --- a/src/common.h +++ b/src/common.h @@ -120,7 +120,7 @@ void do_pidfile(char *); void read_password(char*, size_t); -int check_topdomain(char *); +int check_topdomain(char *, char **); #if defined(WINDOWS32) || defined(ANDROID) #ifndef ANDROID diff --git a/src/iodine.c b/src/iodine.c index 0975739..e53ae37 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -120,6 +120,7 @@ main(int argc, char **argv) { char *nameserv_host; char *topdomain; + char *errormsg; #ifndef WINDOWS32 struct passwd *pw; #endif @@ -149,6 +150,7 @@ main(int argc, char **argv) nameserv_host = NULL; topdomain = NULL; + errormsg = NULL; #ifndef WINDOWS32 pw = NULL; #endif @@ -309,14 +311,8 @@ main(int argc, char **argv) /* NOTREACHED */ } - if (strlen(topdomain) <= 128) { - if(check_topdomain(topdomain)) { - warnx("Topdomain contains invalid characters.\n"); - usage(); - /* NOTREACHED */ - } - } else { - warnx("Use a topdomain max 128 chars long.\n"); + if(check_topdomain(topdomain, &errormsg)) { + warnx("Invalid topdomain: %s", errormsg); usage(); /* NOTREACHED */ } diff --git a/src/iodined.c b/src/iodined.c index 6ebf3a6..ef6c163 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2233,6 +2233,7 @@ main(int argc, char **argv) { extern char *__progname; char *listen_ip; + char *errormsg; #ifndef WINDOWS32 struct passwd *pw; #endif @@ -2267,6 +2268,7 @@ main(int argc, char **argv) #ifndef WINDOWS32 pw = NULL; #endif + errormsg = NULL; username = NULL; newroot = NULL; context = NULL; @@ -2403,14 +2405,10 @@ main(int argc, char **argv) } topdomain = strdup(argv[1]); - if (strlen(topdomain) <= 128) { - if(check_topdomain(topdomain)) { - warnx("Topdomain contains invalid characters."); - usage(); - } - } else { - warnx("Use a topdomain max 128 chars long."); + if(check_topdomain(topdomain, &errormsg)) { + warnx("Invalid topdomain: %s", errormsg); usage(); + /* NOTREACHED */ } if (username != NULL) { diff --git a/tests/common.c b/tests/common.c index 9c84e4a..c1bc73f 100644 --- a/tests/common.c +++ b/tests/common.c @@ -6,60 +6,85 @@ START_TEST(test_topdomain_ok) { - fail_if(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com")); + char *error; + + fail_if(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error)); /* Not allowed to start with dot */ - fail_unless(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com")); + fail_unless(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", &error)); + fail_if(strcmp("Starts with a dot", error)); + + /* Test missing error msg ptr */ + fail_unless(check_topdomain(".foo", NULL)); } END_TEST START_TEST(test_topdomain_length) { + char *error; + /* Test empty and too short */ - fail_unless(check_topdomain("")); - fail_unless(check_topdomain("a")); - fail_unless(check_topdomain(".a")); - fail_unless(check_topdomain("a.")); - fail_unless(check_topdomain("ab")); - fail_if(check_topdomain("a.b")); + fail_unless(check_topdomain("", &error)); + fail_if(strcmp("Too short (< 3)", error)); + fail_unless(check_topdomain("a", &error)); + fail_if(strcmp("Too short (< 3)", error)); + fail_unless(check_topdomain(".a", &error)); + fail_if(strcmp("Too short (< 3)", error)); + fail_unless(check_topdomain("a.", &error)); + fail_if(strcmp("Too short (< 3)", error)); + fail_unless(check_topdomain("ab", &error)); + fail_if(strcmp("Too short (< 3)", error)); + fail_if(check_topdomain("a.b", &error)); + fail_if(strcmp("Too short (< 3)", error)); /* Test too long (over 128, need rest of space for data) */ fail_unless(check_topdomain( "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." - "abcd12345.abcd12345.foo129xxx")); + "abcd12345.abcd12345.foo129xxx", &error)); + fail_if(strcmp("Too long (> 128)", error)); fail_if(check_topdomain( "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." "abcd12345.abcd12345.abcd12345.abcd12345.abcd12345." - "abcd12345.abcd12345.foo128xx")); + "abcd12345.abcd12345.foo128xx", &error)); } END_TEST START_TEST(test_topdomain_chunks) { + char *error; + /* Must have at least one dot */ - fail_if(check_topdomain("abcde.gh")); - fail_unless(check_topdomain("abcdefgh")); + fail_if(check_topdomain("abcde.gh", &error)); + fail_unless(check_topdomain("abcdefgh", &error)); + fail_if(strcmp("No dots", error)); /* Not two consecutive dots */ - fail_unless(check_topdomain("abc..defgh")); + fail_unless(check_topdomain("abc..defgh", &error)); + fail_if(strcmp("Consecutive dots", error)); /* Not end with a dots */ - fail_unless(check_topdomain("abc.defgh.")); + fail_unless(check_topdomain("abc.defgh.", &error)); + fail_if(strcmp("Ends with a dot", error)); /* No chunk longer than 63 chars */ - fail_unless(check_topdomain("123456789012345678901234567890" - "1234567890123456789012345678904444.com")); fail_if(check_topdomain("123456789012345678901234567890" - "123456789012345678901234567890333.com")); - fail_unless(check_topdomain("abc.123456789012345678901234567890" - "1234567890123456789012345678904444.com")); + "123456789012345678901234567890333.com", &error)); + fail_unless(check_topdomain("123456789012345678901234567890" + "1234567890123456789012345678904444.com", &error)); + fail_if(strcmp("Too long domain part (> 63)", error)); + fail_if(check_topdomain("abc.123456789012345678901234567890" - "123456789012345678901234567890333.com")); + "123456789012345678901234567890333.com", &error)); fail_unless(check_topdomain("abc.123456789012345678901234567890" - "1234567890123456789012345678904444")); + "1234567890123456789012345678904444.com", &error)); + fail_if(strcmp("Too long domain part (> 63)", error)); + fail_if(check_topdomain("abc.123456789012345678901234567890" - "123456789012345678901234567890333")); + "123456789012345678901234567890333", &error)); + fail_unless(check_topdomain("abc.123456789012345678901234567890" + "1234567890123456789012345678904444", &error)); + fail_if(strcmp("Too long domain part (> 63)", error)); } END_TEST From 00268bc1606aca95385181da6d1148cd31e24dc7 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 10:19:46 +0200 Subject: [PATCH 08/64] Fix two unused variables for windows build --- src/tun.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tun.c b/src/tun.c index 53f52dc..5a9017d 100644 --- a/src/tun.c +++ b/src/tun.c @@ -440,15 +440,18 @@ tun_setip(const char *ip, const char *other_ip, int netbits) int i; #ifndef LINUX int r; - struct in_addr netip; #endif #ifdef WINDOWS32 DWORD status; DWORD ipdata[3]; struct in_addr addr; DWORD len; -#endif +#else const char *display_ip; +#ifndef LINUX + struct in_addr netip; +#endif +#endif netmask = 0; for (i = 0; i < netbits; i++) { From c52ba7f60673a15c8df6964ae3745b6357e1ebbc Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 12:03:33 +0200 Subject: [PATCH 09/64] Refactor targets to build crosscompiled zipfiles Move common things into new target Add 32/64 bit windows version with MinGW-w64 Serve textfiles with CRLF and .txt suffix Strip windows binaries --- Makefile | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index c378892..33438ae 100644 --- a/Makefile +++ b/Makefile @@ -19,37 +19,61 @@ TARGETOS = `uname` all: @(cd src; $(MAKE) TARGETOS=$(TARGETOS) all) +#Helper target for windows/android zipfiles +iodine-latest: + @rm -rf iodine-latest* + @mkdir -p iodine-latest + @echo "Create date: " > iodine-latest/VERSION.txt + @date >> iodine-latest/VERSION.txt + @echo "Git version: " >> iodine-latest/VERSION.txt + @git rev-parse HEAD >> iodine-latest/VERSION.txt + @for i in README CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done + @unix2dos iodine-latest/* + cross-android: @(cd src; $(MAKE) base64u.c base64u.h) @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk) -cross-android-dist: - @rm -rf iodine-latest-android* +iodine-latest-android.zip: iodine-latest + @mv iodine-latest iodine-latest-android @mkdir -p iodine-latest-android/armeabi iodine-latest-android/x86 @$(MAKE) cross-android TARGET_ARCH_ABI=armeabi @cp src/libs/armeabi/* iodine-latest-android/armeabi @$(MAKE) cross-android TARGET_ARCH_ABI=x86 @cp src/libs/x86/* iodine-latest-android/x86 - @cp README README-android.txt CH* TO* iodine-latest-android - @echo "Create date: " > iodine-latest-android/VERSION - @date >> iodine-latest-android/VERSION - @echo "Git version: " >> iodine-latest-android/VERSION - @git rev-parse HEAD >> iodine-latest-android/VERSION + @cp README-android.txt iodine-latest-android @zip -r iodine-latest-android.zip iodine-latest-android +cross-mingw32: + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc all) + +cross-mingw64: + @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all) + +iodine-latest-windows.zip: iodine-latest + @mv iodine-latest iodine-latest-windows + @mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all) + @i686-w64-mingw32-strip bin/iodine* + @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done + @cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit + @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all) + @x86_64-w64-mingw32-strip bin/iodine* + @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done + @cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit + @cp README-win32.txt iodine-latest-windows + @zip -r iodine-latest-windows.zip iodine-latest-windows + cross-mingw: @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all) -cross-mingw-dist: cross-mingw - @rm -rf iodine-latest-win32* +iodine-latest-win32.zip: cross-mingw iodine-latest + @mv iodine-latest iodine-latest-win32 @mkdir -p iodine-latest-win32/bin + @i686-mingw32-strip bin/iodine* @for i in `ls bin`; do cp bin/$$i iodine-latest-win32/bin/$$i.exe; done @cp /usr/i686-mingw32/usr/bin/zlib1.dll iodine-latest-win32/bin - @cp README README-win32.txt CH* TO* iodine-latest-win32 - @echo "Create date: " > iodine-latest-win32/VERSION - @date >> iodine-latest-win32/VERSION - @echo "Git version: " >> iodine-latest-win32/VERSION - @git rev-parse HEAD >> iodine-latest-win32/VERSION + @cp README-win32.txt iodine-latest-win32 @zip -r iodine-latest-win32.zip iodine-latest-win32 install: all @@ -76,5 +100,5 @@ clean: @echo "Cleaning..." @(cd src; $(MAKE) clean) @(cd tests; $(MAKE) clean) - @rm -rf bin iodine-latest-win32* iodine-latest-android* + @rm -rf bin iodine-latest* From 5b71224def3ce9447829cb4eee4015031bb90b79 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 19:29:22 +0200 Subject: [PATCH 10/64] Fix segfault in windows tun reader thread The arguments to open_dns() needs to be updated after API change. Called with 0, INADDR_ANY used to mean port, IP address but now means pointer to sockadddr and its length. Thanks to C for not giving any warnings or errors.. --- src/tun.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tun.c b/src/tun.c index 5a9017d..880f7ef 100644 --- a/src/tun.c +++ b/src/tun.c @@ -285,9 +285,12 @@ DWORD WINAPI tun_reader(LPVOID arg) int len; int res; OVERLAPPED olpd; + struct sockaddr_storage addr; + int addr_len; int sock; - sock = open_dns(0, INADDR_ANY); + addr_len = get_addr("127.0.0.1", 0, AF_INET, 0, &addr); + sock = open_dns(&addr, addr_len); olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); From d0fb85e8cfba13047787c724f323cc9b8d745fd3 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 21:20:04 +0200 Subject: [PATCH 11/64] Do not use 53 as source port for DNS/raw traffic. For some reason this makes raw traffic get dropped. --- src/iodine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/iodine.c b/src/iodine.c index e53ae37..2884da8 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -345,7 +345,7 @@ main(int argc, char **argv) retval = 1; goto cleanup1; } - if ((dns_fd = open_dns_from_host(NULL, 53, nameservaddr.ss_family, AI_PASSIVE)) < 0) { + if ((dns_fd = open_dns_from_host(NULL, 0, nameservaddr.ss_family, AI_PASSIVE)) < 0) { retval = 1; goto cleanup2; } From 95dedf51db48eaed583c9f311f12cec13fe0522e Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 21:22:03 +0200 Subject: [PATCH 12/64] Simplify opening UDP socket in win32 tun reader --- src/tun.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tun.c b/src/tun.c index 880f7ef..adb6c10 100644 --- a/src/tun.c +++ b/src/tun.c @@ -285,12 +285,9 @@ DWORD WINAPI tun_reader(LPVOID arg) int len; int res; OVERLAPPED olpd; - struct sockaddr_storage addr; - int addr_len; int sock; - addr_len = get_addr("127.0.0.1", 0, AF_INET, 0, &addr); - sock = open_dns(&addr, addr_len); + sock = open_dns_from_host("127.0.0.1", 0, AF_INET, 0); olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); From ac931e65e79e52e5f49228131e3fd8af8a1a002b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 22:55:14 +0200 Subject: [PATCH 13/64] Use -C in submake calls instead of cd Reorder more common install/uninstall/clean before specialized targets. --- Makefile | 122 +++++++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/Makefile b/Makefile index 33438ae..eca56da 100644 --- a/Makefile +++ b/Makefile @@ -17,64 +17,7 @@ RM_FLAGS=-f TARGETOS = `uname` all: - @(cd src; $(MAKE) TARGETOS=$(TARGETOS) all) - -#Helper target for windows/android zipfiles -iodine-latest: - @rm -rf iodine-latest* - @mkdir -p iodine-latest - @echo "Create date: " > iodine-latest/VERSION.txt - @date >> iodine-latest/VERSION.txt - @echo "Git version: " >> iodine-latest/VERSION.txt - @git rev-parse HEAD >> iodine-latest/VERSION.txt - @for i in README CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done - @unix2dos iodine-latest/* - -cross-android: - @(cd src; $(MAKE) base64u.c base64u.h) - @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk) - -iodine-latest-android.zip: iodine-latest - @mv iodine-latest iodine-latest-android - @mkdir -p iodine-latest-android/armeabi iodine-latest-android/x86 - @$(MAKE) cross-android TARGET_ARCH_ABI=armeabi - @cp src/libs/armeabi/* iodine-latest-android/armeabi - @$(MAKE) cross-android TARGET_ARCH_ABI=x86 - @cp src/libs/x86/* iodine-latest-android/x86 - @cp README-android.txt iodine-latest-android - @zip -r iodine-latest-android.zip iodine-latest-android - -cross-mingw32: - @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc all) - -cross-mingw64: - @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all) - -iodine-latest-windows.zip: iodine-latest - @mv iodine-latest iodine-latest-windows - @mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit - @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all) - @i686-w64-mingw32-strip bin/iodine* - @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done - @cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit - @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all) - @x86_64-w64-mingw32-strip bin/iodine* - @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done - @cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit - @cp README-win32.txt iodine-latest-windows - @zip -r iodine-latest-windows.zip iodine-latest-windows - -cross-mingw: - @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all) - -iodine-latest-win32.zip: cross-mingw iodine-latest - @mv iodine-latest iodine-latest-win32 - @mkdir -p iodine-latest-win32/bin - @i686-mingw32-strip bin/iodine* - @for i in `ls bin`; do cp bin/$$i iodine-latest-win32/bin/$$i.exe; done - @cp /usr/i686-mingw32/usr/bin/zlib1.dll iodine-latest-win32/bin - @cp README-win32.txt iodine-latest-win32 - @zip -r iodine-latest-win32.zip iodine-latest-win32 + @$(MAKE) -C src/ TARGETOS=$(TARGETOS) all install: all $(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(sbindir) @@ -94,11 +37,68 @@ uninstall: test: all @echo "!! The check library is required for compiling and running the tests" @echo "!! Get it at http://check.sf.net" - @(cd tests; $(MAKE) TARGETOS=$(TARGETOS) all) + @$(MAKE) -C tests/ TARGETOS=$(TARGETOS) all clean: @echo "Cleaning..." - @(cd src; $(MAKE) clean) - @(cd tests; $(MAKE) clean) + @$(MAKE) -C src/ clean + @$(MAKE) -C tests/ clean @rm -rf bin iodine-latest* +#Helper target for windows/android zipfiles +iodine-latest: + @rm -rf iodine-latest* + @mkdir -p iodine-latest + @echo "Create date: " > iodine-latest/VERSION.txt + @date >> iodine-latest/VERSION.txt + @echo "Git version: " >> iodine-latest/VERSION.txt + @git rev-parse HEAD >> iodine-latest/VERSION.txt + @for i in README CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done + @unix2dos iodine-latest/* + +cross-android: + @$(MAKE) -C src/ base64u.c base64u.h + @ndk-build -C src/ NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk + +iodine-latest-android.zip: iodine-latest + @mv iodine-latest iodine-latest-android + @mkdir -p iodine-latest-android/armeabi iodine-latest-android/x86 + @$(MAKE) cross-android TARGET_ARCH_ABI=armeabi + @cp src/libs/armeabi/* iodine-latest-android/armeabi + @$(MAKE) cross-android TARGET_ARCH_ABI=x86 + @cp src/libs/x86/* iodine-latest-android/x86 + @cp README-android.txt iodine-latest-android + @zip -r iodine-latest-android.zip iodine-latest-android + +cross-mingw32: + @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-w64-mingw32-gcc all + +cross-mingw64: + @$(MAKE) -C src/ TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all + +iodine-latest-windows.zip: iodine-latest + @mv iodine-latest iodine-latest-windows + @mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit + @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all + @i686-w64-mingw32-strip bin/iodine* + @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done + @cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit + @$(MAKE) -C src/ TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all + @x86_64-w64-mingw32-strip bin/iodine* + @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done + @cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit + @cp README-win32.txt iodine-latest-windows + @zip -r iodine-latest-windows.zip iodine-latest-windows + +cross-mingw: + @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-mingw32-gcc all + +iodine-latest-win32.zip: cross-mingw iodine-latest + @mv iodine-latest iodine-latest-win32 + @mkdir -p iodine-latest-win32/bin + @i686-mingw32-strip bin/iodine* + @for i in `ls bin`; do cp bin/$$i iodine-latest-win32/bin/$$i.exe; done + @cp /usr/i686-mingw32/usr/bin/zlib1.dll iodine-latest-win32/bin + @cp README-win32.txt iodine-latest-win32 + @zip -r iodine-latest-win32.zip iodine-latest-win32 + From b7e05e0b9a7253dcd006c3b63548426c39493ac2 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 31 May 2014 22:58:51 +0200 Subject: [PATCH 14/64] Revert submake -C call Not supported by OpenBSD make. --- Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index eca56da..30e6650 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ RM_FLAGS=-f TARGETOS = `uname` all: - @$(MAKE) -C src/ TARGETOS=$(TARGETOS) all + @(cd src; $(MAKE) TARGETOS=$(TARGETOS) all) install: all $(MKDIR) $(MKDIR_FLAGS) $(DESTDIR)$(sbindir) @@ -37,12 +37,12 @@ uninstall: test: all @echo "!! The check library is required for compiling and running the tests" @echo "!! Get it at http://check.sf.net" - @$(MAKE) -C tests/ TARGETOS=$(TARGETOS) all + @(cd tests; $(MAKE) TARGETOS=$(TARGETOS) all) clean: @echo "Cleaning..." - @$(MAKE) -C src/ clean - @$(MAKE) -C tests/ clean + @(cd src; $(MAKE) clean) + @(cd tests; $(MAKE) clean) @rm -rf bin iodine-latest* #Helper target for windows/android zipfiles @@ -57,8 +57,8 @@ iodine-latest: @unix2dos iodine-latest/* cross-android: - @$(MAKE) -C src/ base64u.c base64u.h - @ndk-build -C src/ NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk + @(cd src; $(MAKE) base64u.c base64u.h) + @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk) iodine-latest-android.zip: iodine-latest @mv iodine-latest iodine-latest-android @@ -71,19 +71,19 @@ iodine-latest-android.zip: iodine-latest @zip -r iodine-latest-android.zip iodine-latest-android cross-mingw32: - @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-w64-mingw32-gcc all + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc all) cross-mingw64: - @$(MAKE) -C src/ TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all + @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc all) iodine-latest-windows.zip: iodine-latest @mv iodine-latest iodine-latest-windows @mkdir -p iodine-latest-windows/64bit iodine-latest-windows/32bit - @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-w64-mingw32-gcc clean all) @i686-w64-mingw32-strip bin/iodine* @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/32bit/$$i.exe; done @cp /usr/i686-w64-mingw32/bin/zlib1.dll iodine-latest-windows/32bit - @$(MAKE) -C src/ TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all + @(cd src; $(MAKE) TARGETOS=windows32 CC=x86_64-w64-mingw32-gcc clean all) @x86_64-w64-mingw32-strip bin/iodine* @for i in `ls bin`; do cp bin/$$i iodine-latest-windows/64bit/$$i.exe; done @cp /usr/x86_64-w64-mingw32/bin/zlib1.dll iodine-latest-windows/64bit @@ -91,7 +91,7 @@ iodine-latest-windows.zip: iodine-latest @zip -r iodine-latest-windows.zip iodine-latest-windows cross-mingw: - @$(MAKE) -C src/ TARGETOS=windows32 CC=i686-mingw32-gcc all + @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all) iodine-latest-win32.zip: cross-mingw iodine-latest @mv iodine-latest iodine-latest-win32 From 388afe38454e4bf58918938eb90c48c4b907b8be Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 1 Jun 2014 08:46:42 +0200 Subject: [PATCH 15/64] Update copyright --- README | 4 ++-- src/base32.c | 3 ++- src/base32.h | 3 ++- src/base64.c | 3 ++- src/base64.h | 3 ++- src/client.c | 3 ++- src/client.h | 3 ++- src/common.c | 3 ++- src/common.h | 3 ++- src/dns.c | 3 ++- src/dns.h | 3 ++- src/encoding.c | 3 ++- src/encoding.h | 3 ++- src/fw_query.c | 2 +- src/fw_query.h | 2 +- src/iodine.c | 3 ++- src/iodined.c | 3 ++- src/login.c | 3 ++- src/login.h | 3 ++- src/read.c | 3 ++- src/read.h | 3 ++- src/tun.c | 3 ++- src/tun.h | 3 ++- src/user.c | 3 ++- src/user.h | 3 ++- src/util.c | 3 ++- src/version.h | 3 ++- src/windows.h | 3 ++- tests/base32.c | 3 ++- tests/base64.c | 3 ++- tests/dns.c | 3 ++- tests/encoding.c | 3 ++- tests/fw_query.c | 2 +- tests/login.c | 3 ++- tests/read.c | 3 ++- tests/test.c | 3 ++- tests/test.h | 3 ++- tests/user.c | 3 ++- 38 files changed, 73 insertions(+), 39 deletions(-) diff --git a/README b/README index e3f6a38..257680f 100644 --- a/README +++ b/README @@ -358,8 +358,8 @@ THANKS: AUTHORS & LICENSE: -Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman -Also major contributions by Anne Bezemer. +Copyright (c) 2006-2014 Erik Ekman , 2006-2009 Bjorn +Andersson . Also major contributions by Anne Bezemer. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice diff --git a/src/base32.c b/src/base32.c index 8731a92..6ddbde6 100644 --- a/src/base32.c +++ b/src/base32.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl * * Permission to use, copy, modify, and distribute this software for any diff --git a/src/base32.h b/src/base32.h index 497ca33..53975c5 100644 --- a/src/base32.h +++ b/src/base32.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/base64.c b/src/base64.c index 5218c09..d74e5c3 100644 --- a/src/base64.c +++ b/src/base64.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl * * Permission to use, copy, modify, and distribute this software for any diff --git a/src/base64.h b/src/base64.h index d550cf3..662175e 100644 --- a/src/base64.h +++ b/src/base64.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/client.c b/src/client.c index e3a1479..080db74 100644 --- a/src/client.c +++ b/src/client.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/client.h b/src/client.h index fc5625d..874dd6c 100644 --- a/src/client.h +++ b/src/client.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/common.c b/src/common.c index b15fb7a..85ca16f 100644 --- a/src/common.c +++ b/src/common.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman +/* Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * Copyright (c) 2007 Albert Lee . * * Permission to use, copy, modify, and distribute this software for any diff --git a/src/common.h b/src/common.h index 534996c..f886fcb 100644 --- a/src/common.h +++ b/src/common.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/dns.c b/src/dns.c index 2bd4a2c..9a94164 100644 --- a/src/dns.c +++ b/src/dns.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/dns.h b/src/dns.h index 72d4fe9..7c1faff 100644 --- a/src/dns.h +++ b/src/dns.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/encoding.c b/src/encoding.c index 4b5fb08..02079d6 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/encoding.h b/src/encoding.h index 7ddf6e0..ab22279 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/fw_query.c b/src/fw_query.c index 3727f08..6e5f7df 100644 --- a/src/fw_query.c +++ b/src/fw_query.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Erik Ekman + * Copyright (c) 2008-2014 Erik Ekman * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/fw_query.h b/src/fw_query.h index f274a5a..f8f0de6 100644 --- a/src/fw_query.h +++ b/src/fw_query.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Erik Ekman + * Copyright (c) 2008-2014 Erik Ekman * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/iodine.c b/src/iodine.c index 2884da8..cf46829 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/iodined.c b/src/iodined.c index ef6c163..a6b75d0 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/login.c b/src/login.c index c562050..2c84a5a 100644 --- a/src/login.c +++ b/src/login.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/login.h b/src/login.h index 840c920..ebea25c 100644 --- a/src/login.h +++ b/src/login.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/read.c b/src/read.c index f4ad4a8..eed833f 100644 --- a/src/read.c +++ b/src/read.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/read.h b/src/read.h index b33f3bb..3ce429d 100644 --- a/src/read.h +++ b/src/read.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/tun.c b/src/tun.c index adb6c10..39b763e 100644 --- a/src/tun.c +++ b/src/tun.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/tun.h b/src/tun.h index 89ffcfa..230484c 100644 --- a/src/tun.h +++ b/src/tun.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/user.c b/src/user.c index f5ad924..cb8dfb1 100644 --- a/src/user.c +++ b/src/user.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/user.h b/src/user.h index 7d02b65..00d883b 100644 --- a/src/user.h +++ b/src/user.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/util.c b/src/util.c index 7a365ac..83e9e3c 100644 --- a/src/util.c +++ b/src/util.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/version.h b/src/version.h index 1561b9e..2ab00ff 100644 --- a/src/version.h +++ b/src/version.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/src/windows.h b/src/windows.h index db26995..c665a60 100644 --- a/src/windows.h +++ b/src/windows.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/base32.c b/tests/base32.c index f007798..51e6c7d 100644 --- a/tests/base32.c +++ b/tests/base32.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/base64.c b/tests/base64.c index a259b23..cd96d21 100644 --- a/tests/base64.c +++ b/tests/base64.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/dns.c b/tests/dns.c index 9e89027..cdd3378 100644 --- a/tests/dns.c +++ b/tests/dns.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/encoding.c b/tests/encoding.c index ac22452..fa74c69 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/fw_query.c b/tests/fw_query.c index 6d23924..bffcd7a 100644 --- a/tests/fw_query.c +++ b/tests/fw_query.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2009 Erik Ekman + * Copyright (c) 2009-2014 Erik Ekman * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/login.c b/tests/login.c index 1ef23f4..e154ee2 100644 --- a/tests/login.c +++ b/tests/login.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/read.c b/tests/read.c index f51d0aa..a961fe2 100644 --- a/tests/read.c +++ b/tests/read.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/test.c b/tests/test.c index e897cc2..cc753d4 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/test.h b/tests/test.h index 0701886..b36cd46 100644 --- a/tests/test.h +++ b/tests/test.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/tests/user.c b/tests/user.c index 00a3a8e..112aa2f 100644 --- a/tests/user.c +++ b/tests/user.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2009 Bjorn Andersson , Erik Ekman + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above From a23899513db54fe7d771f7124000fc099ae143b8 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 1 Jun 2014 08:34:18 +0200 Subject: [PATCH 16/64] Remove trailing whitespace --- Makefile | 2 +- src/Makefile | 2 +- src/base128.c | 12 ++-- src/base32.c | 18 +++--- src/base64.c | 14 ++--- src/client.c | 74 ++++++++++++------------ src/common.c | 18 +++--- src/common.h | 14 ++--- src/dns.c | 48 +++++++-------- src/encoding.c | 14 ++--- src/fw_query.c | 4 +- src/iodine.c | 28 ++++----- src/iodined.c | 148 +++++++++++++++++++++++------------------------ src/login.c | 10 ++-- src/md5.h | 2 +- src/read.c | 10 ++-- src/tun.c | 58 +++++++++---------- src/user.c | 16 ++--- src/util.c | 8 +-- tests/Makefile | 4 +- tests/base32.c | 4 +- tests/encoding.c | 2 +- tests/fw_query.c | 6 +- tests/test.h | 4 +- tests/user.c | 30 +++++----- 25 files changed, 275 insertions(+), 275 deletions(-) diff --git a/Makefile b/Makefile index 30e6650..a75eaa8 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ RM_FLAGS=-f TARGETOS = `uname` -all: +all: @(cd src; $(MAKE) TARGETOS=$(TARGETOS) all) install: all diff --git a/src/Makefile b/src/Makefile index 83c00e5..04cef2e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,7 +27,7 @@ $(SERVER): $(COMMONOBJS) $(SERVEROBJS) @mkdir -p ../bin @$(CC) $(COMMONOBJS) $(SERVEROBJS) -o $(SERVER) $(LDFLAGS) -.c.o: +.c.o: @echo CC $< @$(CC) $(CFLAGS) $< -o $@ diff --git a/src/base128.c b/src/base128.c index 32a29f8..7ddc38c 100644 --- a/src/base128.c +++ b/src/base128.c @@ -42,7 +42,7 @@ * accent chars since they might readily be entered in normal use, * don't use 254-255 because of possible function overloading in DNS systems. */ -static const unsigned char cb128[] = +static const unsigned char cb128[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" "\274\275\276\277" "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" @@ -75,19 +75,19 @@ struct encoder return &base128_encoder; } -static int +static int base128_handles_dots() { return 0; } -static int +static int base128_blksize_raw() { return BLKSIZE_RAW; } -static int +static int base128_blksize_enc() { return BLKSIZE_ENC; @@ -109,7 +109,7 @@ base128_reverse_init() } } -static int +static int base128_encode(char *buf, size_t *buflen, const void *data, size_t size) /* * Fills *buf with max. *buflen characters, encoding size bytes of *data. @@ -231,7 +231,7 @@ base128_decode(void *buf, size_t *buflen, const char *str, size_t slen) if (iout >= *buflen || iin + 1 >= slen || str[iin] == '\0' || str[iin + 1] == '\0') break; - ubuf[iout] = ((REV128(ustr[iin]) & 0x7f) << 1) | + ubuf[iout] = ((REV128(ustr[iin]) & 0x7f) << 1) | ((REV128(ustr[iin + 1]) & 0x40) >> 6); iin++; /* 0 used up, iin=1 */ iout++; diff --git a/src/base32.c b/src/base32.c index 6ddbde6..d971ce2 100644 --- a/src/base32.c +++ b/src/base32.c @@ -26,9 +26,9 @@ #define BLKSIZE_RAW 5 #define BLKSIZE_ENC 8 -static const char cb32[] = +static const char cb32[] = "abcdefghijklmnopqrstuvwxyz012345"; -static const char cb32_ucase[] = +static const char cb32_ucase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; static unsigned char rev32[256]; static int reverse_init = 0; @@ -56,19 +56,19 @@ struct encoder return &base32_encoder; } -static int +static int base32_handles_dots() { return 0; } -static int +static int base32_blksize_raw() { return BLKSIZE_RAW; } -static int +static int base32_blksize_enc() { return BLKSIZE_ENC; @@ -105,7 +105,7 @@ b32_8to5(int in) return rev32[in]; } -static int +static int base32_encode(char *buf, size_t *buflen, const void *data, size_t size) /* * Fills *buf with max. *buflen characters, encoding size bytes of *data. @@ -223,7 +223,7 @@ base32_decode(void *buf, size_t *buflen, const char *str, size_t slen) if (iout >= *buflen || iin + 1 >= slen || str[iin] == '\0' || str[iin + 1] == '\0') break; - ubuf[iout] = ((REV32(str[iin]) & 0x1f) << 3) | + ubuf[iout] = ((REV32(str[iin]) & 0x1f) << 3) | ((REV32(str[iin + 1]) & 0x1c) >> 2); iin++; /* 0 used up, iin=1 */ iout++; @@ -232,8 +232,8 @@ base32_decode(void *buf, size_t *buflen, const char *str, size_t slen) str[iin] == '\0' || str[iin + 1] == '\0' || str[iin + 2] == '\0') break; - ubuf[iout] = ((REV32(str[iin]) & 0x03) << 6) | - ((REV32(str[iin + 1]) & 0x1f) << 1) | + ubuf[iout] = ((REV32(str[iin]) & 0x03) << 6) | + ((REV32(str[iin + 1]) & 0x1f) << 1) | ((REV32(str[iin + 2]) & 0x10) >> 4); iin += 2; /* 1,2 used up, iin=3 */ iout++; diff --git a/src/base64.c b/src/base64.c index d74e5c3..71bbcf1 100644 --- a/src/base64.c +++ b/src/base64.c @@ -28,7 +28,7 @@ /* Note: the "unofficial" char is last here, which means that the \377 pattern in DOWNCODECCHECK1 ('Y' request) will properly test it. */ -static const char cb64[] = +static const char cb64[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789+"; static unsigned char rev64[256]; static int reverse_init = 0; @@ -56,19 +56,19 @@ struct encoder return &base64_encoder; } -static int +static int base64_handles_dots() { return 0; } -static int +static int base64_blksize_raw() { return BLKSIZE_RAW; } -static int +static int base64_blksize_enc() { return BLKSIZE_ENC; @@ -90,7 +90,7 @@ base64_reverse_init() } } -static int +static int base64_encode(char *buf, size_t *buflen, const void *data, size_t size) /* * Fills *buf with max. *buflen characters, encoding size bytes of *data. @@ -178,7 +178,7 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen) if (iout >= *buflen || iin + 1 >= slen || str[iin] == '\0' || str[iin + 1] == '\0') break; - ubuf[iout] = ((REV64(str[iin]) & 0x3f) << 2) | + ubuf[iout] = ((REV64(str[iin]) & 0x3f) << 2) | ((REV64(str[iin + 1]) & 0x30) >> 4); iin++; /* 0 used up, iin=1 */ iout++; @@ -186,7 +186,7 @@ base64_decode(void *buf, size_t *buflen, const char *str, size_t slen) if (iout >= *buflen || iin + 1 >= slen || str[iin] == '\0' || str[iin + 1] == '\0') break; - ubuf[iout] = ((REV64(str[iin]) & 0x0f) << 4) | + ubuf[iout] = ((REV64(str[iin]) & 0x0f) << 4) | ((REV64(str[iin + 1]) & 0x3c) >> 2); iin++; /* 1 used up, iin=2 */ iout++; diff --git a/src/client.c b/src/client.c index 080db74..557d811 100644 --- a/src/client.c +++ b/src/client.c @@ -93,10 +93,10 @@ static struct encoder *b128; /* The encoder used for data packets * Defaults to Base32, can be changed after handshake */ static struct encoder *dataenc; - + /* The encoder to use for downstream data */ static char downenc = ' '; - + /* set query type to send */ static unsigned short do_qtype = T_UNSET; @@ -214,7 +214,7 @@ set_downenc(char *encoding) downenc = 'R'; } -void +void client_set_selecttimeout(int select_timeout) { selecttimeout = select_timeout; @@ -333,7 +333,7 @@ send_packet(int fd, char cmd, const char *data, const size_t datalen) char buf[4096]; buf[0] = cmd; - + build_hostname(buf + 1, sizeof(buf) - 1, data, datalen, topdomain, b32, hostname_maxlen); send_query(fd, buf); @@ -366,7 +366,7 @@ send_chunk(int fd) /* Build upstream data header (see doc/proto_xxxxxxxx.txt) */ buf[0] = userid_char; /* First byte is hex userid */ - + code = ((outpkt.seqno & 7) << 2) | ((outpkt.fragment & 15) >> 2); buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */ @@ -380,7 +380,7 @@ send_chunk(int fd) datacmc++; if (datacmc >= 36) datacmc = 0; - + #if 0 fprintf(stderr, " Send: down %d/%d up %d/%d, %d bytes\n", inpkt.seqno, inpkt.fragment, outpkt.seqno, outpkt.fragment, @@ -395,12 +395,12 @@ send_ping(int fd) { if (conn == CONN_DNS_NULL) { char data[4]; - + data[0] = userid; data[1] = ((inpkt.seqno & 7) << 4) | (inpkt.fragment & 15); data[2] = (rand_seed >> 8) & 0xff; data[3] = (rand_seed >> 0) & 0xff; - + rand_seed++; #if 0 @@ -566,7 +566,7 @@ read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q) int r; addrlen = sizeof(from); - if ((r = recvfrom(dns_fd, data, sizeof(data), 0, + if ((r = recvfrom(dns_fd, data, sizeof(data), 0, (struct sockaddr*)&from, &addrlen)) < 0) { warn("recvfrom"); return -1; @@ -588,9 +588,9 @@ read_dns_withq(int dns_fd, int tun_fd, char *buf, int buflen, struct query *q) /* * buf is a hostname or txt stream that we still need to * decode to binary - * + * * also update rv with the number of valid bytes - * + * * data is unused here, and will certainly hold the smaller binary */ @@ -1131,11 +1131,11 @@ client_tunnel(int tun_fd, int dns_fd) warnx("No downstream data received in 60 seconds, shutting down."); running = 0; } - + if (running == 0) break; - if (i < 0) + if (i < 0) err(1, "select"); if (i == 0) { @@ -1178,7 +1178,7 @@ client_tunnel(int tun_fd, int dns_fd) if (FD_ISSET(dns_fd, &fds)) { if (tunnel_dns(tun_fd, dns_fd) <= 0) continue; - } + } } } @@ -1196,7 +1196,7 @@ send_login(int fd, char *login, int len) data[17] = (rand_seed >> 8) & 0xff; data[18] = (rand_seed >> 0) & 0xff; - + rand_seed++; send_packet(fd, 'l', data, sizeof(data)); @@ -1235,23 +1235,23 @@ static void send_set_downstream_fragsize(int fd, int fragsize) { char data[5]; - + data[0] = userid; data[1] = (fragsize & 0xff00) >> 8; data[2] = (fragsize & 0x00ff); data[3] = (rand_seed >> 8) & 0xff; data[4] = (rand_seed >> 0) & 0xff; - + rand_seed++; send_packet(fd, 'n', data, sizeof(data)); } -static void +static void send_version(int fd, uint32_t version) { char data[6]; - + data[0] = (version >> 24) & 0xff; data[1] = (version >> 16) & 0xff; data[2] = (version >> 8) & 0xff; @@ -1259,7 +1259,7 @@ send_version(int fd, uint32_t version) data[4] = (rand_seed >> 8) & 0xff; data[5] = (rand_seed >> 0) & 0xff; - + rand_seed++; send_packet(fd, 'v', data, sizeof(data)); @@ -1270,7 +1270,7 @@ send_ip_request(int fd, int userid) { char buf[512] = "i____."; buf[1] = b32_5to8(userid); - + buf[2] = b32_5to8((rand_seed >> 10) & 0x1f); buf[3] = b32_5to8((rand_seed >> 5) & 0x1f); buf[4] = b32_5to8((rand_seed ) & 0x1f); @@ -1294,7 +1294,7 @@ send_upenctest(int fd, char *s) /* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */ { char buf[512] = "z___"; - + buf[1] = b32_5to8((rand_seed >> 10) & 0x1f); buf[2] = b32_5to8((rand_seed >> 5) & 0x1f); buf[3] = b32_5to8((rand_seed ) & 0x1f); @@ -1330,7 +1330,7 @@ send_codec_switch(int fd, int userid, int bits) char buf[512] = "s_____."; buf[1] = b32_5to8(userid); buf[2] = b32_5to8(bits); - + buf[3] = b32_5to8((rand_seed >> 10) & 0x1f); buf[4] = b32_5to8((rand_seed >> 5) & 0x1f); buf[5] = b32_5to8((rand_seed ) & 0x1f); @@ -1408,7 +1408,7 @@ handshake_version(int dns_fd, int *seed) fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid); return 0; } else if (strncmp("VNAK", in, 4) == 0) { - warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up", + warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up", VERSION, payload); return 1; } else if (strncmp("VFUL", in, 4) == 0) { @@ -1417,7 +1417,7 @@ handshake_version(int dns_fd, int *seed) } } else if (read > 0) warnx("did not receive proper login challenge"); - + fprintf(stderr, "Retrying version check...\n"); } warnx("couldn't connect to server (maybe other -T options will work)"); @@ -1436,7 +1436,7 @@ handshake_login(int dns_fd, int seed) int read; login_calculate(login, 16, password, seed); - + for (i=0; running && i<5 ;i++) { send_login(dns_fd, login, 16); @@ -1510,7 +1510,7 @@ handshake_raw_udp(int dns_fd, int seed) fprintf(stderr, "\n"); if (!running) return 0; - + if (!remoteaddr) { fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n"); return 0; @@ -1524,7 +1524,7 @@ handshake_raw_udp(int dns_fd, int seed) raw_serv.sin_port = htons(53); raw_serv.sin_addr = server; - /* do login against port 53 on remote server + /* do login against port 53 on remote server * based on the old seed. If reply received, * switch to raw udp mode */ for (i=0; running && i<4 ;i++) { @@ -1532,7 +1532,7 @@ handshake_raw_udp(int dns_fd, int seed) tv.tv_usec = 0; send_raw_udp_login(dns_fd, userid, seed); - + FD_ZERO(&fds); FD_SET(dns_fd, &fds); @@ -1545,7 +1545,7 @@ handshake_raw_udp(int dns_fd, int seed) char hash[16]; login_calculate(hash, 16, password, seed - 1); if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0 - && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN + && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) { fprintf(stderr, "OK\n"); @@ -1556,7 +1556,7 @@ handshake_raw_udp(int dns_fd, int seed) fprintf(stderr, "."); fflush(stderr); } - + fprintf(stderr, "failed\n"); return 0; } @@ -2024,7 +2024,7 @@ handshake_switch_codec(int dns_fd, int bits) for (i=0; running && i<5 ;i++) { send_codec_switch(dns_fd, userid, bits); - + read = handshake_waitdns(dns_fd, in, sizeof(in), 's', 'S', i+1); if (read > 0) { @@ -2051,7 +2051,7 @@ handshake_switch_codec(int dns_fd, int bits) fprintf(stderr, "No reply from server on codec switch. "); -codec_revert: +codec_revert: fprintf(stderr, "Falling back to upstream codec %s\n", dataenc->name); } @@ -2103,7 +2103,7 @@ handshake_switch_downenc(int dns_fd) fprintf(stderr, "No reply from server on codec switch. "); -codec_revert: +codec_revert: fprintf(stderr, "Falling back to downstream codec Base32\n"); } @@ -2145,7 +2145,7 @@ handshake_try_lazy(int dns_fd) fprintf(stderr, "No reply from server on lazy switch. "); -codec_revert: +codec_revert: fprintf(stderr, "Falling back to legacy mode\n"); lazymode = 0; selecttimeout = 1; @@ -2262,7 +2262,7 @@ handshake_autoprobe_fragsize(int dns_fd) int max_fragsize; max_fragsize = 0; - fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n"); + fprintf(stderr, "Autoprobing max downstream fragment size... (skip with -m fragsize)\n"); while (running && range > 0 && (range >= 8 || max_fragsize < 300)) { /* stop the slow probing early when we have enough bytes anyway */ for (i=0; running && i<3 ;i++) { @@ -2270,7 +2270,7 @@ handshake_autoprobe_fragsize(int dns_fd) send_fragsize_probe(dns_fd, proposed_fragsize); read = handshake_waitdns(dns_fd, in, sizeof(in), 'r', 'R', 1); - + if (read > 0) { /* We got a reply */ if (fragsize_check(in, read, proposed_fragsize, &max_fragsize) == 1) diff --git a/src/common.c b/src/common.c index 85ca16f..cfdcb56 100644 --- a/src/common.c +++ b/src/common.c @@ -61,7 +61,7 @@ const unsigned char raw_header[RAW_HDR_LEN] = { 0x10, 0xd1, 0x9e, 0x00 }; static int daemon(int nochdir, int noclose) { int fd, i; - + switch (fork()) { case 0: break; @@ -70,15 +70,15 @@ static int daemon(int nochdir, int noclose) default: _exit(0); } - + if (!nochdir) { chdir("/"); } - + if (setsid() < 0) { return -1; } - + if (!noclose) { if ((fd = open("/dev/null", O_RDWR)) >= 0) { for (i = 0; i < 3; i++) { @@ -170,7 +170,7 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora return res; } -int +int open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) { int flag = 1; @@ -291,7 +291,7 @@ read_password(char *buf, size_t len) tcgetattr(0, &tp); old = tp; - + tp.c_lflag &= (~ECHO); tcsetattr(0, TCSANOW, &tp); #else @@ -317,7 +317,7 @@ read_password(char *buf, size_t len) fprintf(stderr, "\n"); #ifndef WINDOWS32 - tcsetattr(0, TCSANOW, &old); + tcsetattr(0, TCSANOW, &old); #endif strncpy(buf, pwd, len); @@ -360,7 +360,7 @@ check_topdomain(char *str, char **errormsg) } else { chunklen++; } - if( (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || + if( (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || isdigit(str[i]) || str[i] == '-' || str[i] == '.' ) { continue; } else { @@ -404,7 +404,7 @@ warn(const char *fmt, ...) if (fmt) fprintf(stderr, fmt, list); #ifndef ANDROID if (errno == 0) { - fprintf(stderr, ": WSA error %d\n", WSAGetLastError()); + fprintf(stderr, ": WSA error %d\n", WSAGetLastError()); } else { fprintf(stderr, ": %s\n", strerror(errno)); } diff --git a/src/common.h b/src/common.h index f886fcb..8df77f8 100644 --- a/src/common.h +++ b/src/common.h @@ -53,12 +53,12 @@ extern const unsigned char raw_header[RAW_HDR_LEN]; #define QUERY_NAME_SIZE 256 -#if defined IP_RECVDSTADDR -# define DSTADDR_SOCKOPT IP_RECVDSTADDR -# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x)) -#elif defined IP_PKTINFO -# define DSTADDR_SOCKOPT IP_PKTINFO -# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr)) +#if defined IP_RECVDSTADDR +# define DSTADDR_SOCKOPT IP_RECVDSTADDR +# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x)) +#elif defined IP_PKTINFO +# define DSTADDR_SOCKOPT IP_PKTINFO +# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr)) #endif #if defined IP_MTU_DISCOVER @@ -78,7 +78,7 @@ extern const unsigned char raw_header[RAW_HDR_LEN]; #define T_UNSET 65432 /* Unused RR type; "private use" range, see http://www.bind9.net/dns-parameters */ -struct packet +struct packet { int len; /* Total packet length */ int sentlen; /* Length of chunk currently transmitted */ diff --git a/src/dns.c b/src/dns.c index 9a94164..9cea926 100644 --- a/src/dns.c +++ b/src/dns.c @@ -62,9 +62,9 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ return 0; memset(buf, 0, buflen); - + header = (HEADER*)buf; - + header->id = htons(q->id); header->qr = (qr == QR_ANSWER); header->opcode = 0; @@ -78,7 +78,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ switch (qr) { case QR_ANSWER: header->qdcount = htons(1); - + name = 0xc000 | ((p - buf) & 0x3fff); /* Question section */ @@ -97,7 +97,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ int namelen; CHECKLEN(10); - putshort(&p, name); + putshort(&p, name); if (q->type == T_A) /* answer CNAME to A question */ putshort(&p, T_CNAME); @@ -127,7 +127,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ ancnt = 1; while (1) { CHECKLEN(10); - putshort(&p, name); + putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ @@ -162,7 +162,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ int txtlen; CHECKLEN(10); - putshort(&p, name); + putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ @@ -179,7 +179,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ /* NULL has raw binary data */ CHECKLEN(10); - putshort(&p, name); + putshort(&p, name); putshort(&p, q->type); putshort(&p, C_IN); putlong(&p, 0); /* TTL */ @@ -198,7 +198,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ /* Note that iodined also uses this for forward queries */ header->qdcount = htons(1); - + datalen = MIN(datalen, buflen - (p - buf)); putname(&p, datalen, data); @@ -221,7 +221,7 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_ break; } - + len = p - buf; return len; @@ -245,9 +245,9 @@ dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomai return 0; memset(buf, 0, buflen); - + header = (HEADER*)buf; - + header->id = htons(q->id); header->qr = 1; header->opcode = 0; @@ -334,9 +334,9 @@ dns_encode_a_response(char *buf, size_t buflen, struct query *q) return 0; memset(buf, 0, buflen); - + header = (HEADER*)buf; - + header->id = htons(q->id); header->qr = 1; header->opcode = 0; @@ -408,7 +408,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz short type; char *data; short rlen; - int id; + int id; int rv; q->id2 = 0; @@ -416,9 +416,9 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz header = (HEADER*)packet; /* Reject short packets */ - if (packetlen < sizeof(HEADER)) + if (packetlen < sizeof(HEADER)) return 0; - + if (header->qr != qr) { warnx("header->qr does not match the requested qr"); return -1; @@ -427,13 +427,13 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz data = packet + sizeof(HEADER); qdcount = ntohs(header->qdcount); ancount = ntohs(header->ancount); - + id = ntohs(header->id); id = id & 0xFFFF; /* Kill any sign extension */ - + rlen = 0; - if (q != NULL) + if (q != NULL) q->rcode = header->rcode; switch (qr) { @@ -443,7 +443,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz return -1; } - if (q != NULL) + if (q != NULL) q->id = id; /* Read name even if no answer, to give better error message */ @@ -451,14 +451,14 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz CHECKLEN(4); readshort(packet, &data, &type); readshort(packet, &data, &class); - + /* if CHECKLEN okay, then we're sure to have a proper name */ if (q != NULL) { /* We only need the first char to check it */ q->name[0] = name[0]; q->name[1] = '\0'; - } - + } + if (ancount < 1) { /* DNS errors like NXDOMAIN have ancount=0 and stop here. CNAME may also have A; MX/SRV may have @@ -539,7 +539,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz names[pref / 10 - 1][QUERY_NAME_SIZE-1] = '\0'; } - /* always trust rlen, not name encoding */ + /* always trust rlen, not name encoding */ data = rdatastart + rlen; CHECKLEN(0); } diff --git a/src/encoding.c b/src/encoding.c index 02079d6..af7620e 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -20,8 +20,8 @@ #include "encoding.h" int -build_hostname(char *buf, size_t buflen, - const char *data, const size_t datalen, +build_hostname(char *buf, size_t buflen, + const char *data, const size_t datalen, const char *topdomain, struct encoder *encoder, int maxlen) { size_t space; @@ -34,7 +34,7 @@ build_hostname(char *buf, size_t buflen, space -= (space / 57); /* space for dots */ memset(buf, 0, buflen); - + encoder->encode(buf, &space, data, datalen); if (!encoder->places_dots()) @@ -45,7 +45,7 @@ build_hostname(char *buf, size_t buflen, /* move b back one step to see if the dot is there */ b--; - if (*b != '.') + if (*b != '.') *++b = '.'; b++; /* move b ahead of the string so we can copy to it */ @@ -63,7 +63,7 @@ unpack_data(char *buf, size_t buflen, char *data, size_t datalen, struct encoder return enc->decode(buf, &buflen, data, datalen); } -int +int inline_dotify(char *buf, size_t buflen) { unsigned dots; @@ -101,7 +101,7 @@ inline_dotify(char *buf, size_t buflen) return total; } -int +int inline_undotify(char *buf, size_t len) { unsigned pos; @@ -124,7 +124,7 @@ inline_undotify(char *buf, size_t len) *writer++ = *reader++; pos++; } - + /* return new length of string */ return len - dots; } diff --git a/src/fw_query.c b/src/fw_query.c index 6e5f7df..4f7d8c4 100644 --- a/src/fw_query.c +++ b/src/fw_query.c @@ -29,9 +29,9 @@ void fw_query_init() void fw_query_put(struct fw_query *fw_query) { memcpy(&(fwq[fwq_ix]), fw_query, sizeof(struct fw_query)); - + ++fwq_ix; - if (fwq_ix >= FW_QUERY_CACHE_SIZE) + if (fwq_ix >= FW_QUERY_CACHE_SIZE) fwq_ix = 0; } diff --git a/src/iodine.c b/src/iodine.c index cf46829..4d7c1ca 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -53,7 +53,7 @@ static char *__progname; #define PASSWORD_ENV_VAR "IODINE_PASS" static void -sighandler(int sig) +sighandler(int sig) { client_stop(); } @@ -179,7 +179,7 @@ main(int argc, char **argv) srand((unsigned) time(NULL)); client_init(); - + #if !defined(BSD) && !defined(__GLIBC__) __progname = strrchr(argv[0], '/'); if (__progname == NULL) @@ -227,9 +227,9 @@ main(int argc, char **argv) case 'P': strncpy(password, optarg, sizeof(password)); password[sizeof(password)-1] = 0; - + /* XXX: find better way of cleaning up ps(1) */ - memset(optarg, 0, strlen(optarg)); + memset(optarg, 0, strlen(optarg)); break; case 'm': autodetect_frag_size = 0; @@ -247,7 +247,7 @@ main(int argc, char **argv) break; case 'F': pidfile = optarg; - break; + break; case 'T': set_qtype(optarg); break; @@ -273,7 +273,7 @@ main(int argc, char **argv) /* NOTREACHED */ } } - + check_superuser(usage); argc -= optind; @@ -310,7 +310,7 @@ main(int argc, char **argv) warnx("No nameserver found - not connected to any network?\n"); usage(); /* NOTREACHED */ - } + } if(check_topdomain(topdomain, &errormsg)) { warnx("Invalid topdomain: %s", errormsg); @@ -322,7 +322,7 @@ main(int argc, char **argv) client_set_lazymode(lazymode); client_set_topdomain(topdomain); client_set_hostname_maxlen(hostname_maxlen); - + if (username != NULL) { #ifndef WINDOWS32 if ((pw = getpwnam(username)) == NULL) { @@ -332,14 +332,14 @@ main(int argc, char **argv) } #endif } - + if (strlen(password) == 0) { if (NULL != getenv(PASSWORD_ENV_VAR)) snprintf(password, sizeof(password), "%s", getenv(PASSWORD_ENV_VAR)); else read_password(password, sizeof(password)); } - + client_set_password(password); if ((tun_fd = open_tun(device)) == -1) { @@ -365,22 +365,22 @@ main(int argc, char **argv) retval = 1; goto cleanup2; } - + if (client_get_conn() == CONN_RAW_UDP) { fprintf(stderr, "Sending raw traffic directly to %s\n", client_get_raw_addr()); } fprintf(stderr, "Connection setup complete, transmitting data.\n"); - if (foreground == 0) + if (foreground == 0) do_detach(); - + if (pidfile != NULL) do_pidfile(pidfile); if (newroot != NULL) do_chroot(newroot); - + if (username != NULL) { #ifndef WINDOWS32 gid_t gids[1]; diff --git a/src/iodined.c b/src/iodined.c index a6b75d0..711bbb9 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -152,7 +152,7 @@ static int get_external_ip(struct in_addr *ip) } static void -sigint(int sig) +sigint(int sig) { running = 0; } @@ -182,7 +182,7 @@ check_user_and_ip(int userid, struct query *q) /* Note: duplicate in handle_raw_login() except IP-address check */ if (userid < 0 || userid >= created_users ) { - return 1; + return 1; } if (!users[userid].active || users[userid].disabled) { return 1; @@ -217,7 +217,7 @@ send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q) packet[RAW_HDR_CMD] = cmd | (user & 0x0F); if (debug >= 2) { - fprintf(stderr, "TX-raw: client %s, cmd %d, %d bytes\n", + fprintf(stderr, "TX-raw: client %s, cmd %d, %d bytes\n", format_addr(&q->from, q->fromlen), cmd, len); } @@ -552,12 +552,12 @@ send_chunk_or_dataless(int dns_fd, int userid, struct query *q) pkt[0] = (1<<7) | ((users[userid].inpacket.seqno & 7) << 4) | (users[userid].inpacket.fragment & 15); /* Second byte is 3 bits downstream seqno, 4 bits downstream fragment, 1 bit last flag */ - pkt[1] = ((users[userid].outpacket.seqno & 7) << 5) | + pkt[1] = ((users[userid].outpacket.seqno & 7) << 5) | ((users[userid].outpacket.fragment & 15) << 1) | (last & 1); if (debug >= 1) { fprintf(stderr, "OUT pkt seq# %d, frag %d (last=%d), offset %d, fragsize %d, total %d, to user %d\n", - users[userid].outpacket.seqno & 7, users[userid].outpacket.fragment & 15, + users[userid].outpacket.seqno & 7, users[userid].outpacket.fragment & 15, last, users[userid].outpacket.offset, datalen, users[userid].outpacket.len, userid); } write_dns(dns_fd, q, pkt, datalen + 2, users[userid].downenc); @@ -611,7 +611,7 @@ tunnel_tun(int tun_fd, int dns_fd) if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0) return 0; - + /* find target ip in packet, in is padded with 4 bytes TUN header */ header = (struct ip*) (in + 4); userid = find_user_by_ip(header->ip_dst.s_addr); @@ -657,7 +657,7 @@ static void send_version_response(int fd, version_ack_t ack, uint32_t payload, int userid, struct query *q) { char out[9]; - + switch (ack) { case VERSION_ACK: strncpy(out, "VACK", sizeof(out)); @@ -669,7 +669,7 @@ send_version_response(int fd, version_ack_t ack, uint32_t payload, int userid, s strncpy(out, "VFUL", sizeof(out)); break; } - + out[4] = ((payload >> 24) & 0xff); out[5] = ((payload >> 16) & 0xff); out[6] = ((payload >> 8) & 0xff); @@ -742,7 +742,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32); /* Version greeting, compare and send ack/nak */ - if (read > 4) { + if (read > 4) { /* Received V + 32bits version */ version = (((unpacked[0] & 0xff) << 24) | ((unpacked[1] & 0xff) << 16) | @@ -760,7 +760,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) /* Store remote IP number */ tempin = (struct sockaddr_in *) &(q->from); memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); - + memcpy(&(users[userid].q), q, sizeof(struct query)); users[userid].encoder = get_base32_encoder(); users[userid].downenc = 'T'; @@ -807,12 +807,12 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) } else { /* No space for another user */ send_version_response(dns_fd, VERSION_FULL, created_users, 0, q); - syslog(LOG_INFO, "dropped user from %s, server full", + syslog(LOG_INFO, "dropped user from %s, server full", format_addr(&q->from, q->fromlen)); } } else { send_version_response(dns_fd, VERSION_NACK, VERSION, 0, q); - syslog(LOG_INFO, "dropped user from %s, sent bad version %08X", + syslog(LOG_INFO, "dropped user from %s, sent bad version %08X", format_addr(&q->from, q->fromlen), version); } return; @@ -843,7 +843,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) tempip.s_addr = users[userid].tun_ip; tmp[1] = strdup(inet_ntoa(tempip)); - read = snprintf(out, sizeof(out), "%s-%s-%d-%d", + read = snprintf(out, sizeof(out), "%s-%s-%d-%d", tmp[0], tmp[1], my_mtu, netmask); write_dns(dns_fd, q, out, read, users[userid].downenc); @@ -864,7 +864,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) in_addr_t replyaddr; unsigned addr; char reply[5]; - + userid = b32_8to5(in[1]); if (check_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); @@ -902,12 +902,12 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) } userid = b32_8to5(in[1]); - + if (check_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } - + codec = b32_8to5(in[2]); switch (codec) { @@ -1076,9 +1076,9 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } - + req_frag_size = ((b32_8to5(in[1]) & 1) << 10) | ((b32_8to5(in[2]) & 31) << 5) | (b32_8to5(in[3]) & 31); - if (req_frag_size < 2 || req_frag_size > 2047) { + if (req_frag_size < 2 || req_frag_size > 2047) { write_dns(dns_fd, q, "BADFRAG", 7, users[userid].downenc); } else { char buf[2048]; @@ -1111,9 +1111,9 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } - + max_frag_size = ((unpacked[1] & 0xff) << 8) | (unpacked[2] & 0xff); - if (max_frag_size < 2) { + if (max_frag_size < 2) { write_dns(dns_fd, q, "BADFRAG", 7, users[userid].downenc); } else { users[userid].fragsize = max_frag_size; @@ -1178,7 +1178,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) memcpy(&(users[userid].q.from2), &(q->from), q->fromlen); return; } - + if (users[userid].q_sendrealsoon.id != 0 && q->type == users[userid].q_sendrealsoon.type && !strcmp(q->name, users[userid].q_sendrealsoon.name)) { @@ -1194,7 +1194,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) &(q->from), q->fromlen); return; } - + dn_seq = unpacked[1] >> 4; dn_frag = unpacked[1] & 15; @@ -1289,7 +1289,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) like to re-try early and often (with _different_ .id!) */ if (users[userid].q.id != 0 && q->type == users[userid].q.type && - !strcmp(q->name, users[userid].q.name) && + !strcmp(q->name, users[userid].q.name) && users[userid].lazy) { /* We have this packet already, and it's waiting to be answered. Always keep the last duplicate, since the @@ -1306,7 +1306,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) memcpy(&(users[userid].q.from2), &(q->from), q->fromlen); return; } - + if (users[userid].q_sendrealsoon.id != 0 && q->type == users[userid].q_sendrealsoon.type && !strcmp(q->name, users[userid].q_sendrealsoon.name)) { @@ -1322,7 +1322,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) &(q->from), q->fromlen); return; } - + /* Decode data header */ up_seq = (b32_8to5(in[1]) >> 2) & 7; @@ -1333,7 +1333,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) process_downstream_ack(userid, dn_seq, dn_frag); - if (up_seq == users[userid].inpacket.seqno && + if (up_seq == users[userid].inpacket.seqno && up_frag <= users[userid].inpacket.fragment) { /* Got repeated old packet _with data_, probably because client didn't receive our ack. So re-send @@ -1491,9 +1491,9 @@ handle_ns_request(int dns_fd, struct query *q) warnx("dns_encode_ns_response doesn't fit"); return; } - + if (debug >= 2) { - fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes NS reply\n", + fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes NS reply\n", format_addr(&q->from, q->fromlen), q->type, q->name, len); } if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) { @@ -1523,7 +1523,7 @@ handle_a_request(int dns_fd, struct query *q, int fakeip) warnx("dns_encode_a_response doesn't fit"); return; } - + if (debug >= 2) { fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes A reply\n", format_addr(&q->from, q->fromlen), q->type, q->name, len); @@ -1558,7 +1558,7 @@ forward_query(int bind_fd, struct query *q) myaddr = (struct sockaddr_in *) &(q->from); memcpy(&(myaddr->sin_addr), &newaddr, sizeof(in_addr_t)); myaddr->sin_port = htons(bind_port); - + if (debug >= 2) { fprintf(stderr, "TX: NS reply \n"); } @@ -1567,7 +1567,7 @@ forward_query(int bind_fd, struct query *q) warn("forward query error"); } } - + static int tunnel_bind(int bind_fd, int dns_fd) { @@ -1579,14 +1579,14 @@ tunnel_bind(int bind_fd, int dns_fd) int r; fromlen = sizeof(struct sockaddr); - r = recvfrom(bind_fd, packet, sizeof(packet), 0, + r = recvfrom(bind_fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &fromlen); if (r <= 0) return 0; id = dns_get_id(packet, r); - + if (debug >= 2) { fprintf(stderr, "RX: Got response on query %u from DNS\n", (id & 0xFFFF)); } @@ -1604,8 +1604,8 @@ tunnel_bind(int bind_fd, int dns_fd) fprintf(stderr, "TX: client %s id %u, %d bytes\n", format_addr(&query->addr, query->addrlen), (id & 0xffff), r); } - - if (sendto(dns_fd, packet, r, 0, (const struct sockaddr *) &(query->addr), + + if (sendto(dns_fd, packet, r, 0, (const struct sockaddr *) &(query->addr), query->addrlen) <= 0) { warn("forward reply error"); } @@ -1625,7 +1625,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd) return 0; if (debug >= 2) { - fprintf(stderr, "RX: client %s, type %d, name %s\n", + fprintf(stderr, "RX: client %s, type %d, name %s\n", format_addr(&q.from, q.fromlen), q.type, q.name); } @@ -1736,9 +1736,9 @@ tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) } i = select(maxfd + 1, &fds, NULL, NULL, &tv); - + if(i < 0) { - if (running) + if (running) warn("select"); return 1; } @@ -1763,7 +1763,7 @@ tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) } if (FD_ISSET(dns_fd, &fds)) { tunnel_dns(tun_fd, dns_fd, bind_fd); - } + } if (FD_ISSET(bind_fd, &fds)) { tunnel_bind(bind_fd, dns_fd); } @@ -1791,7 +1791,7 @@ handle_full_packet(int tun_fd, int dns_fd, int userid) int ret; outlen = sizeof(out); - ret = uncompress((uint8_t*)out, &outlen, + ret = uncompress((uint8_t*)out, &outlen, (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); if (ret == Z_OK) { @@ -1843,7 +1843,7 @@ static void handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) { char myhash[16]; - + if (len < 16) return; /* can't use check_user_and_ip() since IP address will be different, @@ -1869,7 +1869,7 @@ handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) /* Store remote IP number */ tempin = (struct sockaddr_in *) &(q->from); memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); - + /* Correct hash, reply with hash of seed - 1 */ user_set_conn_type(userid, CONN_RAW_UDP); login_calculate(myhash, 16, password, users[userid].seed - 1); @@ -1975,7 +1975,7 @@ read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw msg.msg_control = address; msg.msg_controllen = sizeof(address); msg.msg_flags = 0; - + r = recvmsg(fd, &msg, 0); #else addrlen = sizeof(struct sockaddr); @@ -1993,22 +1993,22 @@ read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw if (dns_decode(NULL, 0, q, QR_QUERY, packet, r) < 0) { return 0; } - + #ifndef WINDOWS32 - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - - if (cmsg->cmsg_level == IPPROTO_IP && - cmsg->cmsg_type == DSTADDR_SOCKOPT) { - - q->destination = *dstaddr(cmsg); + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IP && + cmsg->cmsg_type == DSTADDR_SOCKOPT) { + + q->destination = *dstaddr(cmsg); break; - } + } } #endif return strlen(q->name); - } else if (r < 0) { + } else if (r < 0) { /* Error */ warn("read dns"); } @@ -2073,7 +2073,7 @@ write_dns_nameenc(char *buf, size_t buflen, char *data, int datalen, char downen /* Add dot (if it wasn't there already) and topdomain */ b = buf; b += strlen(buf) - 1; - if (*b != '.') + if (*b != '.') *++b = '.'; b++; @@ -2165,9 +2165,9 @@ write_dns(int fd, struct query *q, char *data, int datalen, char downenc) warnx("dns_encode doesn't fit"); return; } - + if (debug >= 2) { - fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes data\n", + fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes data\n", format_addr(&q->from, q->fromlen), q->type, q->name, datalen); } @@ -2247,11 +2247,11 @@ main(int argc, char **argv) int dnsd_fd; int tun_fd; - /* settings for forwarding normal DNS to + /* settings for forwarding normal DNS to * local real DNS server */ int bind_fd; int bind_enable; - + int choice; int port; int mtu; @@ -2293,7 +2293,7 @@ main(int argc, char **argv) b64 = get_base64_encoder(); b64u = get_base64u_encoder(); b128 = get_base128_encoder(); - + retval = 0; #ifdef WINDOWS32 @@ -2311,7 +2311,7 @@ main(int argc, char **argv) memset(password, 0, sizeof(password)); srand(time(NULL)); fw_query_init(); - + while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:z:F:i:")) != -1) { switch(choice) { case 'v': @@ -2363,16 +2363,16 @@ main(int argc, char **argv) break; case 'F': pidfile = optarg; - break; + break; case 'i': max_idle_time = atoi(optarg); break; case 'P': strncpy(password, optarg, sizeof(password)); password[sizeof(password)-1] = 0; - + /* XXX: find better way of cleaning up ps(1) */ - memset(optarg, 0, strlen(optarg)); + memset(optarg, 0, strlen(optarg)); break; case 'z': context = optarg; @@ -2388,9 +2388,9 @@ main(int argc, char **argv) check_superuser(usage); - if (argc != 2) + if (argc != 2) usage(); - + netsize = strchr(argv[0], '/'); if (netsize) { *netsize = 0; @@ -2399,7 +2399,7 @@ main(int argc, char **argv) } my_ip = inet_addr(argv[0]); - + if (my_ip == INADDR_NONE) { warnx("Bad IP address to use inside tunnel."); usage(); @@ -2425,12 +2425,12 @@ main(int argc, char **argv) warnx("Bad MTU given."); usage(); } - + if(port < 1 || port > 65535) { warnx("Bad port number given."); usage(); } - + if (port != 53) { fprintf(stderr, "ALERT! Other dns servers expect you to run on port 53.\n"); fprintf(stderr, "You must manually forward port 53 to port %d for things to work.\n", port); @@ -2485,7 +2485,7 @@ main(int argc, char **argv) warnx("Bad netmask (%d bits). Use 8-30 bits.", netmask); usage(); } - + if (strlen(password) == 0) { if (NULL != getenv(PASSWORD_ENV_VAR)) snprintf(password, sizeof(password), "%s", getenv(PASSWORD_ENV_VAR)); @@ -2533,16 +2533,16 @@ main(int argc, char **argv) } my_mtu = mtu; - + if (created_users < USERS) { fprintf(stderr, "Limiting to %d simultaneous users because of netmask /%d\n", created_users, netmask); } fprintf(stderr, "Listening to dns for domain %s\n", topdomain); - if (foreground == 0) + if (foreground == 0) do_detach(); - + if (pidfile != NULL) do_pidfile(pidfile); @@ -2572,7 +2572,7 @@ main(int argc, char **argv) do_setcon(context); syslog(LOG_INFO, "started, listening on port %d", port); - + tunnel(tun_fd, dnsd_fd, bind_fd, max_idle_time); syslog(LOG_INFO, "stopping"); @@ -2581,7 +2581,7 @@ cleanup3: cleanup2: close_dns(dnsd_fd); cleanup1: - close_tun(tun_fd); + close_tun(tun_fd); cleanup0: return retval; diff --git a/src/login.c b/src/login.c index 2c84a5a..a809998 100644 --- a/src/login.c +++ b/src/login.c @@ -27,11 +27,11 @@ #include "md5.h" -/* - * Needs a 16byte array for output, and 32 bytes password +/* + * Needs a 16byte array for output, and 32 bytes password */ -void -login_calculate(char *buf, int buflen, const char *pass, int seed) +void +login_calculate(char *buf, int buflen, const char *pass, int seed) { unsigned char temp[32]; md5_state_t ctx; @@ -39,7 +39,7 @@ login_calculate(char *buf, int buflen, const char *pass, int seed) int i; int k; - if (buflen < 16) + if (buflen < 16) return; memcpy(temp, pass, 32); diff --git a/src/md5.h b/src/md5.h index 698c995..3baa4dc 100644 --- a/src/md5.h +++ b/src/md5.h @@ -71,7 +71,7 @@ typedef struct md5_state_s { } md5_state_t; #ifdef __cplusplus -extern "C" +extern "C" { #endif diff --git a/src/read.c b/src/read.c index eed833f..66f19a7 100644 --- a/src/read.c +++ b/src/read.c @@ -61,7 +61,7 @@ readname_loop(char *packet, int packetlen, char **src, char *dst, size_t length, c--; } - + if (len >= length - 1) { break; /* We used up all space */ } @@ -104,8 +104,8 @@ readlong(char *packet, char **src, uint32_t *dst) p = (unsigned char *) *src; - *dst = ((uint32_t)p[0] << 24) - | ((uint32_t)p[1] << 16) + *dst = ((uint32_t)p[0] << 24) + | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | ((uint32_t)p[3]); @@ -163,7 +163,7 @@ putname(char **buf, size_t buflen, const char *host) h = strdup(host); left = buflen; p = *buf; - + word = strtok(h, "."); while(word) { if (strlen(word) > 63 || strlen(word) > left) { @@ -231,7 +231,7 @@ int putdata(char **dst, char *data, size_t len) { memcpy(*dst, data, len); - + (*dst) += len; return len; } diff --git a/src/tun.c b/src/tun.c index 39b763e..db37974 100644 --- a/src/tun.c +++ b/src/tun.c @@ -69,8 +69,8 @@ char if_name[250]; #include #include -int -open_tun(const char *tun_device) +int +open_tun(const char *tun_device) { int i; int tun_fd; @@ -88,7 +88,7 @@ open_tun(const char *tun_device) memset(&ifreq, 0, sizeof(ifreq)); - ifreq.ifr_flags = IFF_TUN; + ifreq.ifr_flags = IFF_TUN; if (tun_device != NULL) { strncpy(ifreq.ifr_name, tun_device, IFNAMSIZ); @@ -129,8 +129,8 @@ open_tun(const char *tun_device) #else /* BSD */ -int -open_tun(const char *tun_device) +int +open_tun(const char *tun_device) { int i; int tun_fd; @@ -184,7 +184,7 @@ get_device(char *device, int device_len, const char *wanted_dev) warnx("Error opening registry key " TAP_ADAPTER_KEY ); return; } - + while (TRUE) { char name[256]; char unit[256]; @@ -222,7 +222,7 @@ get_device(char *device, int device_len, const char *wanted_dev) strncmp(TAP_VERSION_ID_0901, component, strlen(TAP_VERSION_ID_0901)) == 0) { /* We found a TAP32 device, get its NetCfgInstanceId */ char iid_string[256] = NET_CFG_INST_ID; - + status = RegQueryValueEx(device_key, iid_string, NULL, &datatype, (LPBYTE) device, (DWORD *) &device_len); if (status != ERROR_SUCCESS || datatype != REG_SZ) { warnx("Error reading registry key %s\\%s on TAP device", unit, iid_string); @@ -299,7 +299,7 @@ DWORD WINAPI tun_reader(LPVOID arg) if (!res) { WaitForSingleObject(olpd.hEvent, INFINITE); res = GetOverlappedResult(dev_handle, &olpd, (LPDWORD) &len, FALSE); - res = sendto(sock, buf, len, 0, (struct sockaddr*) &(tun->addr), + res = sendto(sock, buf, len, 0, (struct sockaddr*) &(tun->addr), tun->addrlen); } } @@ -307,8 +307,8 @@ DWORD WINAPI tun_reader(LPVOID arg) return 0; } -int -open_tun(const char *tun_device) +int +open_tun(const char *tun_device) { char adapter[256]; char tapfile[512]; @@ -328,7 +328,7 @@ open_tun(const char *tun_device) } return -1; } - + fprintf(stderr, "Opening device %s\n", if_name); snprintf(tapfile, sizeof(tapfile), "%s%s.tap", TAP_DEVICE_SPACE, adapter); dev_handle = CreateFile(tapfile, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL); @@ -339,9 +339,9 @@ open_tun(const char *tun_device) /* Use a UDP connection to forward packets from tun, * so we can still use select() in main code. - * A thread does blocking reads on tun device and + * A thread does blocking reads on tun device and * sends data as udp to this socket */ - + localsock_len = get_addr("127.0.0.1", 55353, AF_INET, 0, &localsock); tunfd = open_dns(&localsock, localsock_len); @@ -349,20 +349,20 @@ open_tun(const char *tun_device) memcpy(&(data.addr), &localsock, localsock_len); data.addrlen = localsock_len; CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tun_reader, &data, 0, NULL); - + return tunfd; } -#endif +#endif -void -close_tun(int tun_fd) +void +close_tun(int tun_fd) { if (tun_fd >= 0) close(tun_fd); } -int -write_tun(int tun_fd, char *data, size_t len) +int +write_tun(int tun_fd, char *data, size_t len) { #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) || defined(WINDOWS32) data += 4; @@ -409,7 +409,7 @@ write_tun(int tun_fd, char *data, size_t len) } ssize_t -read_tun(int tun_fd, char *buf, size_t len) +read_tun(int tun_fd, char *buf, size_t len) { #if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) || defined(WINDOWS32) /* FreeBSD/Darwin/NetBSD has no header */ @@ -471,13 +471,13 @@ tun_setip(const char *ip, const char *other_ip, int netbits) # else display_ip = ip; # endif - snprintf(cmdline, sizeof(cmdline), + snprintf(cmdline, sizeof(cmdline), IFCONFIGPATH "ifconfig %s %s %s netmask %s", if_name, ip, display_ip, inet_ntoa(net)); - + fprintf(stderr, "Setting IP of %s to %s\n", if_name, ip); #ifndef LINUX netip.s_addr = inet_addr(ip); @@ -486,7 +486,7 @@ tun_setip(const char *ip, const char *other_ip, int netbits) if(r != 0) { return r; } else { - + snprintf(cmdline, sizeof(cmdline), "/sbin/route add %s/%d %s", inet_ntoa(netip), netbits, ip); @@ -499,13 +499,13 @@ tun_setip(const char *ip, const char *other_ip, int netbits) /* Set device as connected */ fprintf(stderr, "Enabling interface '%s'\n", if_name); status = 1; - r = DeviceIoControl(dev_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, + r = DeviceIoControl(dev_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL); if (!r) { fprintf(stderr, "Failed to enable interface\n"); return -1; } - + if (inet_aton(ip, &addr)) { ipdata[0] = (DWORD) addr.s_addr; /* local ip addr */ ipdata[1] = net.s_addr & ipdata[0]; /* network addr */ @@ -515,7 +515,7 @@ tun_setip(const char *ip, const char *other_ip, int netbits) } /* Tell ip/networkaddr/netmask to device for arp use */ - r = DeviceIoControl(dev_handle, TAP_IOCTL_CONFIG_TUN, &ipdata, + r = DeviceIoControl(dev_handle, TAP_IOCTL_CONFIG_TUN, &ipdata, sizeof(ipdata), &ipdata, sizeof(ipdata), &len, NULL); if (!r) { fprintf(stderr, "Failed to set interface in TUN mode\n"); @@ -530,18 +530,18 @@ tun_setip(const char *ip, const char *other_ip, int netbits) #endif } -int +int tun_setmtu(const unsigned mtu) { #ifndef WINDOWS32 char cmdline[512]; if (mtu > 200 && mtu <= 1500) { - snprintf(cmdline, sizeof(cmdline), + snprintf(cmdline, sizeof(cmdline), IFCONFIGPATH "ifconfig %s mtu %u", if_name, mtu); - + fprintf(stderr, "Setting MTU of %s to %u\n", if_name, mtu); return system(cmdline); } else { diff --git a/src/user.c b/src/user.c index cb8dfb1..67821a4 100644 --- a/src/user.c +++ b/src/user.c @@ -59,7 +59,7 @@ init_users(in_addr_t my_ip, int netbits) maxusers = (1 << (32-netbits)) - 3; /* 3: Net addr, broadcast addr, iodined addr */ usercount = MIN(maxusers, USERS); - + users = calloc(usercount, sizeof(struct tun_user)); for (i = 0; i < usercount; i++) { in_addr_t ip; @@ -98,13 +98,13 @@ users_waiting_on_reply() ret = 0; for (i = 0; i < usercount; i++) { - if (users[i].active && !users[i].disabled && + if (users[i].active && !users[i].disabled && users[i].last_pkt + 60 > time(NULL) && users[i].q.id != 0 && users[i].conn == CONN_DNS_NULL) { ret++; } } - + return ret; } @@ -143,8 +143,8 @@ all_users_waiting_to_send() for (i = 0; i < usercount; i++) { if (users[i].active && !users[i].disabled && users[i].last_pkt + 60 > now && - ((users[i].conn == CONN_RAW_UDP) || - ((users[i].conn == CONN_DNS_NULL) + ((users[i].conn == CONN_RAW_UDP) || + ((users[i].conn == CONN_DNS_NULL) #ifdef OUTPACKETQ_LEN && users[i].outpacketq_filled < 1 #else @@ -183,7 +183,7 @@ user_switch_codec(int userid, struct encoder *enc) { if (userid < 0 || userid >= usercount) return; - + users[userid].encoder = enc; } @@ -195,7 +195,7 @@ user_set_conn_type(int userid, enum connection c) if (c < 0 || c >= CONN_MAX) return; - + users[userid].conn = c; } - + diff --git a/src/util.c b/src/util.c index 83e9e3c..f4a538e 100644 --- a/src/util.c +++ b/src/util.c @@ -36,12 +36,12 @@ get_resolvconf_addr() rv = addr; pclose(fp); #else - + rv = NULL; - if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) + if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) err(1, "/etc/resolv.conf"); - + while (feof(fp) == 0) { fgets(buf, sizeof(buf), fp); @@ -50,7 +50,7 @@ get_resolvconf_addr() break; } } - + fclose(fp); #endif #else /* !WINDOWS32 */ diff --git a/tests/Makefile b/tests/Makefile index 43310eb..03eed98 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -13,9 +13,9 @@ all: $(TEST) $(TEST): $(OBJS) $(SRCOBJS) @echo LD $(TEST) - @$(CC) -o $@ $(SRCOBJS) $(OBJS) $(LDFLAGS) + @$(CC) -o $@ $(SRCOBJS) $(OBJS) $(LDFLAGS) -.c.o: +.c.o: @echo CC $< @$(CC) $(CFLAGS) -c $< diff --git a/tests/base32.c b/tests/base32.c index 51e6c7d..419253f 100644 --- a/tests/base32.c +++ b/tests/base32.c @@ -63,7 +63,7 @@ START_TEST(test_base32_decode) char buf[4096]; struct encoder *b32; int val; - + b32 = get_base32_encoder(); len = sizeof(buf); @@ -81,7 +81,7 @@ START_TEST(test_base32_5to8_8to5) int c; for (i = 0; i < 32; i++) { - c = b32_5to8(i); + c = b32_5to8(i); fail_unless(b32_8to5(c) == i); } } diff --git a/tests/encoding.c b/tests/encoding.c index fa74c69..665c4dd 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -85,7 +85,7 @@ START_TEST(test_build_hostname) } buflen = sizeof(buf); - + for (i = 1; i < sizeof(data); i++) { int len = build_hostname(buf, buflen, data, i, topdomain, get_base32_encoder(), sizeof(buf)); diff --git a/tests/fw_query.c b/tests/fw_query.c index bffcd7a..c6ed2c7 100644 --- a/tests/fw_query.c +++ b/tests/fw_query.c @@ -28,7 +28,7 @@ START_TEST(test_fw_query_simple) q.id = 0x848A; fw_query_init(); - + /* Test empty cache */ fw_query_get(0x848A, &qp); fail_unless(qp == NULL); @@ -49,7 +49,7 @@ START_TEST(test_fw_query_edge) int i; fw_query_init(); - + q.addrlen = 33; q.id = 0x848A; fw_query_put(&q); @@ -64,7 +64,7 @@ START_TEST(test_fw_query_edge) fw_query_get(0x848A, &qp); fail_unless(qp->addrlen == 33); fail_unless(qp->id == 0x848A); - + q.addrlen++; q.id++; fw_query_put(&q); diff --git a/tests/test.h b/tests/test.h index b36cd46..511cf31 100644 --- a/tests/test.h +++ b/tests/test.h @@ -29,11 +29,11 @@ TCase *test_user_create_tests(); TCase *test_fw_query_create_tests(); char *va_str(const char *, ...); - + #if (CHECK_MAJOR_VERSION == 0 && \ ((CHECK_MINOR_VERSION == 9 && CHECK_MICRO_VERSION < 2) || \ (CHECK_MINOR_VERSION < 9))) -#define tcase_set_timeout(...) +#define tcase_set_timeout(...) #endif #endif diff --git a/tests/user.c b/tests/user.c index 112aa2f..6534317 100644 --- a/tests/user.c +++ b/tests/user.c @@ -62,12 +62,12 @@ START_TEST(test_users_waiting) fail_unless(users_waiting_on_reply() == 0); users[3].last_pkt = time(NULL); - + fail_unless(users_waiting_on_reply() == 0); - + users[3].conn = CONN_DNS_NULL; users[3].q.id = 1; - + fail_unless(users_waiting_on_reply() == 1); } END_TEST @@ -83,17 +83,17 @@ START_TEST(test_find_user_by_ip) testip = (unsigned int) inet_addr("10.0.0.1"); fail_unless(find_user_by_ip(testip) == -1); - + testip = (unsigned int) inet_addr("127.0.0.2"); fail_unless(find_user_by_ip(testip) == -1); - + users[0].active = 1; - + testip = (unsigned int) inet_addr("127.0.0.2"); fail_unless(find_user_by_ip(testip) == -1); - + users[0].last_pkt = time(NULL); - + testip = (unsigned int) inet_addr("127.0.0.2"); fail_unless(find_user_by_ip(testip) == 0); } @@ -107,15 +107,15 @@ START_TEST(test_all_users_waiting_to_send) init_users(ip, 27); fail_unless(all_users_waiting_to_send() == 1); - + users[0].conn = CONN_DNS_NULL; users[0].active = 1; - + fail_unless(all_users_waiting_to_send() == 1); - + users[0].last_pkt = time(NULL); users[0].outpacket.len = 0; - + fail_unless(all_users_waiting_to_send() == 0); #ifdef OUTPACKETQ_LEN @@ -123,7 +123,7 @@ START_TEST(test_all_users_waiting_to_send) #else users[0].outpacket.len = 44; #endif - + fail_unless(all_users_waiting_to_send() == 1); } END_TEST @@ -150,7 +150,7 @@ START_TEST(test_find_available_user) fail_unless(find_available_user() == -1); users[3].last_pkt = 55; - + fail_unless(find_available_user() == 3); fail_unless(find_available_user() == -1); } @@ -178,7 +178,7 @@ START_TEST(test_find_available_user_small_net) fail_unless(find_available_user() == -1); users[3].last_pkt = 55; - + fail_unless(find_available_user() == 3); fail_unless(find_available_user() == -1); } From 3fadbfb580aff36e6a6bda1cd766ec38b456dae4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 4 Jun 2014 17:40:36 +0900 Subject: [PATCH 17/64] Do not let sockets be inherited by sub-processes Set FD_CLOEXEC flag on tunnel and UDP file descriptors. Fixes ticket #99, "should not allow UDP socket to be inherited by ifconfig" --- CHANGELOG | 1 + src/common.c | 18 ++++++++++++++++++ src/common.h | 2 ++ src/tun.c | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ad85947..5f8287a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ master: - A number of minor patches from Frank Denis, Gregor Herrmann and Barak A. Pearlmutter. - Testcase compilation fixes for OS X and FreeBSD + - Do not let sockets be inherited by sub-processes, fixes #99. 2010-02-06: 0.6.0-rc1 "Hotspotify" - Fixed tunnel not working on Windows. diff --git a/src/common.c b/src/common.c index cfdcb56..6373a30 100644 --- a/src/common.c +++ b/src/common.c @@ -189,6 +189,8 @@ open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) #ifndef WINDOWS32 /* To get destination address from each UDP datagram, see iodined.c:read_dns() */ setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag)); + + fd_set_close_on_exec(fd); #endif #ifdef IP_OPT_DONT_FRAG @@ -461,3 +463,19 @@ int recent_seqno(int ourseqno, int gotseqno) } return 0; } + +/* Set FD_CLOEXEC flag on file descriptor. + * This stops it from being inherited by system() calls. + */ +void +fd_set_close_on_exec(int fd) +{ + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + err(4, "Failed to get fd flags"); + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + err(4, "Failed to set fd flags"); +} diff --git a/src/common.h b/src/common.h index 8df77f8..7b91942 100644 --- a/src/common.h +++ b/src/common.h @@ -136,4 +136,6 @@ void warnx(const char *fmt, ...); int recent_seqno(int , int); +void fd_set_close_on_exec(int fd); + #endif diff --git a/src/tun.c b/src/tun.c index db37974..0af1d81 100644 --- a/src/tun.c +++ b/src/tun.c @@ -98,6 +98,7 @@ open_tun(const char *tun_device) if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) { fprintf(stderr, "Opened %s\n", ifreq.ifr_name); + fd_set_close_on_exec(tun_fd); return tun_fd; } @@ -112,6 +113,7 @@ open_tun(const char *tun_device) if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) { fprintf(stderr, "Opened %s\n", ifreq.ifr_name); snprintf(if_name, sizeof(if_name), "dns%d", i); + fd_set_close_on_exec(tun_fd); return tun_fd; } @@ -147,6 +149,7 @@ open_tun(const char *tun_device) } fprintf(stderr, "Opened %s\n", tun_name); + fd_set_close_on_exec(tun_fd); return tun_fd; } else { for (i = 0; i < TUN_MAX_TRY; i++) { @@ -155,6 +158,7 @@ open_tun(const char *tun_device) if ((tun_fd = open(tun_name, O_RDWR)) >= 0) { fprintf(stderr, "Opened %s\n", tun_name); snprintf(if_name, sizeof(if_name), "tun%d", i); + fd_set_close_on_exec(tun_fd); return tun_fd; } From fbb5a49cf3cb767b0bbc66fa9ee5e2a598cf0aaf Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 5 Jun 2014 02:19:57 +0200 Subject: [PATCH 18/64] Fix windows build --- src/common.c | 3 +++ src/common.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/common.c b/src/common.c index 6373a30..2715979 100644 --- a/src/common.c +++ b/src/common.c @@ -464,6 +464,7 @@ int recent_seqno(int ourseqno, int gotseqno) return 0; } +#ifndef WINDOWS32 /* Set FD_CLOEXEC flag on file descriptor. * This stops it from being inherited by system() calls. */ @@ -479,3 +480,5 @@ fd_set_close_on_exec(int fd) if (fcntl(fd, F_SETFD, flags) == -1) err(4, "Failed to set fd flags"); } +#endif + diff --git a/src/common.h b/src/common.h index 7b91942..f363ea5 100644 --- a/src/common.h +++ b/src/common.h @@ -136,6 +136,8 @@ void warnx(const char *fmt, ...); int recent_seqno(int , int); +#ifndef WINDOWS32 void fd_set_close_on_exec(int fd); +#endif #endif From 4d7678dc5b96b79f6f81ff452d476fd788bb7328 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 9 Jun 2014 18:11:16 +0200 Subject: [PATCH 19/64] Prefix exported functions from client.c --- src/client.c | 10 +++++----- src/client.h | 6 +++--- src/iodine.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/client.c b/src/client.c index 557d811..66c3ef2 100644 --- a/src/client.c +++ b/src/client.c @@ -168,7 +168,7 @@ client_set_password(const char *cp) } void -set_qtype(char *qtype) +client_set_qtype(char *qtype) { if (!strcasecmp(qtype, "NULL")) do_qtype = T_NULL; @@ -185,7 +185,7 @@ set_qtype(char *qtype) } char * -get_qtype() +client_get_qtype() { char *c = "UNDEFINED"; @@ -200,7 +200,7 @@ get_qtype() } void -set_downenc(char *encoding) +client_set_downenc(char *encoding) { if (!strcasecmp(encoding, "base32")) downenc = 'T'; @@ -1917,7 +1917,7 @@ handshake_qtype_autodetect(int dns_fd) highestworking = qtypenum; #if 0 fprintf(stderr, " Type %s timeout %d works\n", - get_qtype(), timeout); + client_get_qtype(), timeout); #endif break; /* try others with longer timeout */ @@ -2379,7 +2379,7 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz } } - fprintf(stderr, "Using DNS type %s queries\n", get_qtype()); + fprintf(stderr, "Using DNS type %s queries\n", client_get_qtype()); r = handshake_version(dns_fd, &seed); if (r) { diff --git a/src/client.h b/src/client.h index 874dd6c..69687d1 100644 --- a/src/client.h +++ b/src/client.h @@ -27,9 +27,9 @@ const char *client_get_raw_addr(); void client_set_nameserver(struct sockaddr_storage *, int); void client_set_topdomain(const char *cp); void client_set_password(const char *cp); -void set_qtype(char *qtype); -char *get_qtype(); -void set_downenc(char *encoding); +void client_set_qtype(char *qtype); +char *client_get_qtype(); +void client_set_downenc(char *encoding); void client_set_selecttimeout(int select_timeout); void client_set_lazymode(int lazy_mode); void client_set_hostname_maxlen(int i); diff --git a/src/iodine.c b/src/iodine.c index 4d7c1ca..2f24889 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -249,10 +249,10 @@ main(int argc, char **argv) pidfile = optarg; break; case 'T': - set_qtype(optarg); + client_set_qtype(optarg); break; case 'O': /* not -D, is Debug in server */ - set_downenc(optarg); + client_set_downenc(optarg); break; case 'L': lazymode = atoi(optarg); From 1f4b9250cf2c609b4f3e4963ac7998cb188b8afd Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 9 Jun 2014 18:55:27 +0200 Subject: [PATCH 20/64] Check that supplied query type is valid --- src/client.c | 3 ++- src/client.h | 2 +- src/iodine.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/client.c b/src/client.c index 66c3ef2..f33a8e9 100644 --- a/src/client.c +++ b/src/client.c @@ -167,7 +167,7 @@ client_set_password(const char *cp) password = cp; } -void +int client_set_qtype(char *qtype) { if (!strcasecmp(qtype, "NULL")) @@ -182,6 +182,7 @@ client_set_qtype(char *qtype) do_qtype = T_SRV; else if (!strcasecmp(qtype, "TXT")) do_qtype = T_TXT; + return (do_qtype == T_UNSET); } char * diff --git a/src/client.h b/src/client.h index 69687d1..983b830 100644 --- a/src/client.h +++ b/src/client.h @@ -27,7 +27,7 @@ const char *client_get_raw_addr(); void client_set_nameserver(struct sockaddr_storage *, int); void client_set_topdomain(const char *cp); void client_set_password(const char *cp); -void client_set_qtype(char *qtype); +int client_set_qtype(char *qtype); char *client_get_qtype(); void client_set_downenc(char *encoding); void client_set_selecttimeout(int select_timeout); diff --git a/src/iodine.c b/src/iodine.c index 2f24889..6cf7cc3 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -249,7 +249,8 @@ main(int argc, char **argv) pidfile = optarg; break; case 'T': - client_set_qtype(optarg); + if (client_set_qtype(optarg)) + errx(5, "Invalid query type '%s'", optarg); break; case 'O': /* not -D, is Debug in server */ client_set_downenc(optarg); From 2466cd184a69dde8ed55d773094651ac25e380bc Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 9 Jun 2014 19:47:44 +0200 Subject: [PATCH 21/64] Change readshort() to work with unsigned values --- src/dns.c | 8 ++++---- src/read.c | 6 +++--- src/read.h | 2 +- tests/read.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dns.c b/src/dns.c index 9cea926..b1c6fb2 100644 --- a/src/dns.c +++ b/src/dns.c @@ -404,10 +404,10 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz short qdcount; short ancount; uint32_t ttl; - short class; - short type; + unsigned short class; + unsigned short type; char *data; - short rlen; + unsigned short rlen; int id; int rv; @@ -509,7 +509,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz */ char names[250][QUERY_NAME_SIZE]; char *rdatastart; - short pref; + unsigned short pref; int i; int offset; diff --git a/src/read.c b/src/read.c index 66f19a7..a2dcd96 100644 --- a/src/read.c +++ b/src/read.c @@ -85,15 +85,15 @@ readname(char *packet, int packetlen, char **src, char *dst, size_t length) } int -readshort(char *packet, char **src, short *dst) +readshort(char *packet, char **src, unsigned short *dst) { unsigned char *p; p = (unsigned char *) *src; *dst = (p[0] << 8) | p[1]; - (*src) += sizeof(short); - return sizeof(short); + (*src) += sizeof(unsigned short); + return sizeof(unsigned short); } int diff --git a/src/read.h b/src/read.h index 3ce429d..2aac355 100644 --- a/src/read.h +++ b/src/read.h @@ -19,7 +19,7 @@ #define _READ_H_ int readname(char *, int, char **, char *, size_t); -int readshort(char *, char **, short *); +int readshort(char *, char **, unsigned short *); int readlong(char *, char **, uint32_t *); int readdata(char *, char **, char *, size_t); int readtxtbin(char *, char **, size_t, char *, size_t); diff --git a/tests/read.c b/tests/read.c index a961fe2..24a5214 100644 --- a/tests/read.c +++ b/tests/read.c @@ -51,7 +51,7 @@ START_TEST(test_read_putshort) i, ntohs(k), i); p = (char*)&k; - readshort(NULL, &p, (short *) &l); + readshort(NULL, &p, &l); fail_unless(l == i, "Bad value on readshort for %d: %d != %d", i, l, i); From 3ebcd29b13c5dcfc776d8cff20b43991c127c6c5 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 9 Jun 2014 20:05:29 +0200 Subject: [PATCH 22/64] Add support for using an unspecified RR type Add PRIVATE query type with id 65399 (private use range). According to RFC3597 the reply data in a query with unspecified RR type must be handled as unstructured binary data, which means it can contain raw packet data just like the NULL type. Since the reply format is optimal it is ordered just after NULL in the priority order. --- CHANGELOG | 2 ++ README | 25 +++++++++++++------------ doc/proto_00000502.txt | 7 ++++--- man/iodine.8 | 6 +++++- src/client.c | 23 ++++++++++++++--------- src/common.h | 4 +++- src/dns.c | 2 +- src/iodine.c | 2 +- src/iodined.c | 1 + 9 files changed, 44 insertions(+), 28 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5f8287a..01173a1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,8 @@ master: Barak A. Pearlmutter. - Testcase compilation fixes for OS X and FreeBSD - Do not let sockets be inherited by sub-processes, fixes #99. + - Add unspecified RR type (called PRIVATE; id 65399, in private use + range). For servers with RFC3597 support. Fixes #97. 2010-02-06: 0.6.0-rc1 "Hotspotify" - Fixed tunnel not working on Windows. diff --git a/README b/README index 257680f..cfc8ede 100644 --- a/README +++ b/README @@ -177,12 +177,13 @@ packet, and one query can be max 256 chars. Each domain name part can be max 63 chars. So your domain name and subdomain should be as short as possible to allow maximum upstream throughput. -Several DNS request types are supported, with the NULL type expected to provide -the largest downstream bandwidth. Other available types are TXT, SRV, MX, -CNAME and A (returning CNAME), in decreasing bandwidth order. Normally the +Several DNS request types are supported, with the NULL and PRIVATE types +expected to provide the largest downstream bandwidth. The PRIVATE type uses +value 65399 in the private-use range. Other available types are TXT, SRV, MX, +CNAME and A (returning CNAME), in decreasing bandwidth order. Normally the "best" request type is autodetected and used. However, DNS relays may impose limits on for example NULL and TXT, making SRV or MX actually the best choice. -This is not autodetected, but can be forced using the -T option. It is +This is not autodetected, but can be forced using the -T option. It is advisable to try various alternatives especially when the autodetected request type provides a downstream fragment size of less than 200 bytes. @@ -190,14 +191,14 @@ Note that SRV, MX and A (returning CNAME) queries may/will cause additional lookups by "smart" caching nameservers to get an actual IP address, which may either slow down or fail completely. -DNS responses for non-NULL queries can be encoded with the same set of codecs -as upstream data. This is normally also autodetected, but no fully exhaustive -tests are done, so some problems may not be noticed when selecting more -advanced codecs. In that case, you'll see failures/corruption in the fragment -size autoprobe. In particular, several DNS relays have been found that change -replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when that -hostname exceeds ca. 180 characters. In these and similar cases, use the -O -option to try other downstream codecs; Base32 should always work. +DNS responses for non-NULL/PRIVATE queries can be encoded with the same set of +codecs as upstream data. This is normally also autodetected, but no fully +exhaustive tests are done, so some problems may not be noticed when selecting +more advanced codecs. In that case, you'll see failures/corruption in the +fragment size autoprobe. In particular, several DNS relays have been found that +change replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when +that hostname exceeds ca. 180 characters. In these and similar cases, use the +-O option to try other downstream codecs; Base32 should always work. Normal operation now is for the server to _not_ answer a DNS request until the next DNS request has come in, a.k.a. being "lazy". This way, the server diff --git a/doc/proto_00000502.txt b/doc/proto_00000502.txt index 46cf2de..831824d 100644 --- a/doc/proto_00000502.txt +++ b/doc/proto_00000502.txt @@ -122,7 +122,8 @@ Server sends: s or S: Downstream encoding Base64, for TXT/CNAME/A/MX u or U: Downstream encoding Base64u, for TXT/CNAME/A/MX v or V: Downstream encoding Base128, for TXT/CNAME/A/MX - r or R: Downstream encoding Raw, for TXT/NULL (default for NULL) + r or R: Downstream encoding Raw, for PRIVATE/TXT/NULL (default for + PRIVATE and NULL) If codec unsupported for request type, server will use Base32; note that server will answer any mix of request types that a client sends. Server may disregard this option; client must always use the downstream @@ -188,8 +189,8 @@ encoded with the chosen upstream codec. Downstream data starts with 2 byte header. Then payload data, which may be compressed. -In NULL responses, downstream data is always raw. In all other response types, -downstream data is encoded (see Options above). +In NULL and PRIVATE responses, downstream data is always raw. In all other +response types, downstream data is encoded (see Options above). Encoding type is indicated by 1 prefix char: TXT: End result is always DNS-chopped (series of len-prefixed strings diff --git a/man/iodine.8 b/man/iodine.8 index ca2d72c..feb8283 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -169,6 +169,7 @@ more bandwidth. In that case, use this option to override the autodetection. In (expected) decreasing bandwidth order, the supported DNS request types are: .IR NULL , +.IR PRIVATE , .IR TXT , .IR SRV , .IR MX , @@ -183,7 +184,10 @@ and .I A may/will cause additional lookups by "smart" caching nameservers to get an actual IP address, which may either slow down or fail -completely. +completely. The +.IR PRIVATE +type uses value 65399 (in the 'private use' range) and requires servers +implementing RFC 3597. .TP .B -O downenc Force downstream encoding type for all query type responses except NULL. diff --git a/src/client.c b/src/client.c index f33a8e9..8db89fc 100644 --- a/src/client.c +++ b/src/client.c @@ -172,6 +172,8 @@ client_set_qtype(char *qtype) { if (!strcasecmp(qtype, "NULL")) do_qtype = T_NULL; + else if (!strcasecmp(qtype, "PRIVATE")) + do_qtype = T_PRIVATE; else if (!strcasecmp(qtype, "CNAME")) do_qtype = T_CNAME; else if (!strcasecmp(qtype, "A")) @@ -191,6 +193,7 @@ client_get_qtype() char *c = "UNDEFINED"; if (do_qtype == T_NULL) c = "NULL"; + else if (do_qtype == T_PRIVATE) c = "PRIVATE"; else if (do_qtype == T_CNAME) c = "CNAME"; else if (do_qtype == T_A) c = "A"; else if (do_qtype == T_MX) c = "MX"; @@ -1786,7 +1789,7 @@ handshake_downenc_autodetect(int dns_fd) int base64uok = 0; int base128ok = 0; - if (do_qtype == T_NULL) { + if (do_qtype == T_NULL || do_qtype == T_PRIVATE) { /* no other choice than raw */ fprintf(stderr, "No alternative downstream codec available, using default (Raw)\n"); return ' '; @@ -1840,13 +1843,14 @@ handshake_qtypetest(int dns_fd, int timeout) int trycodec; int k; - if (do_qtype == T_NULL) + if (do_qtype == T_NULL || do_qtype == T_PRIVATE) trycodec = 'R'; else trycodec = 'T'; /* We could use 'Z' bouncing here, but 'Y' also tests that 0-255 - byte values can be returned, which is needed for NULL to work. */ + byte values can be returned, which is needed for NULL/PRIVATE + to work. */ send_downenctest(dns_fd, trycodec, 1, NULL, 0); @@ -1871,11 +1875,12 @@ handshake_qtype_numcvt(int num) { switch (num) { case 0: return T_NULL; - case 1: return T_TXT; - case 2: return T_SRV; - case 3: return T_MX; - case 4: return T_CNAME; - case 5: return T_A; + case 1: return T_PRIVATE; + case 2: return T_TXT; + case 3: return T_SRV; + case 4: return T_MX; + case 5: return T_CNAME; + case 6: return T_A; } return T_UNSET; } @@ -2317,7 +2322,7 @@ handshake_autoprobe_fragsize(int dns_fd) fprintf(stderr, "Note: this probably won't work well.\n"); fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n"); } else if (max_fragsize < 202 && - (do_qtype == T_NULL || do_qtype == T_TXT || + (do_qtype == T_NULL || do_qtype == T_PRIVATE || do_qtype == T_TXT || do_qtype == T_SRV || do_qtype == T_MX)) { fprintf(stderr, "Note: this isn't very much.\n"); fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n"); diff --git a/src/common.h b/src/common.h index f363ea5..3c98c01 100644 --- a/src/common.h +++ b/src/common.h @@ -75,8 +75,10 @@ extern const unsigned char raw_header[RAW_HDR_LEN]; # define DONT_FRAG_VALUE 1 #endif +#define T_PRIVATE 65399 +/* Undefined RR type; "private use" range, see http://www.bind9.net/dns-parameters */ #define T_UNSET 65432 -/* Unused RR type; "private use" range, see http://www.bind9.net/dns-parameters */ +/* Unused RR type, never actually sent */ struct packet { diff --git a/src/dns.c b/src/dns.c index b1c6fb2..0d3b8b3 100644 --- a/src/dns.c +++ b/src/dns.c @@ -467,7 +467,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz } /* Here type is still the question type */ - if (type == T_NULL) { + if (type == T_NULL || type == T_PRIVATE) { /* Assume that first answer is what we wanted */ readname(packet, packetlen, &data, name, sizeof(name)); CHECKLEN(10); diff --git a/src/iodine.c b/src/iodine.c index 6cf7cc3..75e9e50 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -83,7 +83,7 @@ help() { "[-P password] [-m maxfragsize] [-M maxlen] [-T type] [-O enc] [-L 0|1] [-I sec] " "[-z context] [-F pidfile] [nameserver] topdomain\n", __progname); fprintf(stderr, "Options to try if connection doesn't work:\n"); - fprintf(stderr, " -T force dns type: NULL, TXT, SRV, MX, CNAME, A (default: autodetect)\n"); + fprintf(stderr, " -T force dns type: NULL, PRIVATE, TXT, SRV, MX, CNAME, A (default: autodetect)\n"); fprintf(stderr, " -O force downstream encoding for -T other than NULL: Base32, Base64, Base64u,\n"); fprintf(stderr, " Base128, or (only for TXT:) Raw (default: autodetect)\n"); fprintf(stderr, " -I max interval between requests (default 4 sec) to prevent DNS timeouts\n"); diff --git a/src/iodined.c b/src/iodined.c index 711bbb9..c14f1a7 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -1662,6 +1662,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd) switch (q.type) { case T_NULL: + case T_PRIVATE: case T_CNAME: case T_A: case T_MX: From bf658b0c594514b786b528bf649a26094e62a042 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Jun 2014 20:50:35 +0200 Subject: [PATCH 23/64] Misc cleanup of tun.c - Make variables static - open_tun(): First Linux code, then Windows, then BSDs - write_tun()/read_tun(): Split Windows and normal code --- src/tun.c | 167 +++++++++++++++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/src/tun.c b/src/tun.c index 0af1d81..60eedd7 100644 --- a/src/tun.c +++ b/src/tun.c @@ -33,8 +33,8 @@ #include "windows.h" #include -HANDLE dev_handle; -struct tun_data data; +static HANDLE dev_handle; +static struct tun_data data; static void get_name(char *ifname, int namelen, char *dev_name); @@ -60,9 +60,8 @@ static void get_name(char *ifname, int namelen, char *dev_name); #include "tun.h" #include "common.h" -char if_name[250]; +static char if_name[250]; -#ifndef WINDOWS32 #ifdef LINUX #include @@ -129,51 +128,8 @@ open_tun(const char *tun_device) return -1; } -#else /* BSD */ +#elif WINDOWS32 -int -open_tun(const char *tun_device) -{ - int i; - int tun_fd; - char tun_name[50]; - - if (tun_device != NULL) { - snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device); - strncpy(if_name, tun_device, sizeof(if_name)); - if_name[sizeof(if_name)-1] = '\0'; - - if ((tun_fd = open(tun_name, O_RDWR)) < 0) { - warn("open_tun: %s: %s", tun_name, strerror(errno)); - return -1; - } - - fprintf(stderr, "Opened %s\n", tun_name); - fd_set_close_on_exec(tun_fd); - return tun_fd; - } else { - for (i = 0; i < TUN_MAX_TRY; i++) { - snprintf(tun_name, sizeof(tun_name), "/dev/tun%d", i); - - if ((tun_fd = open(tun_name, O_RDWR)) >= 0) { - fprintf(stderr, "Opened %s\n", tun_name); - snprintf(if_name, sizeof(if_name), "tun%d", i); - fd_set_close_on_exec(tun_fd); - return tun_fd; - } - - if (errno == ENOENT) - break; - } - - warn("open_tun: Failed to open tunneling device"); - } - - return -1; -} - -#endif /* !LINUX */ -#else /* WINDOWS32 */ static void get_device(char *device, int device_len, const char *wanted_dev) { @@ -356,6 +312,50 @@ open_tun(const char *tun_device) return tunfd; } + +#else /* BSD and friends */ + +int +open_tun(const char *tun_device) +{ + int i; + int tun_fd; + char tun_name[50]; + + if (tun_device != NULL) { + snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device); + strncpy(if_name, tun_device, sizeof(if_name)); + if_name[sizeof(if_name)-1] = '\0'; + + if ((tun_fd = open(tun_name, O_RDWR)) < 0) { + warn("open_tun: %s: %s", tun_name, strerror(errno)); + return -1; + } + + fprintf(stderr, "Opened %s\n", tun_name); + fd_set_close_on_exec(tun_fd); + return tun_fd; + } else { + for (i = 0; i < TUN_MAX_TRY; i++) { + snprintf(tun_name, sizeof(tun_name), "/dev/tun%d", i); + + if ((tun_fd = open(tun_name, O_RDWR)) >= 0) { + fprintf(stderr, "Opened %s\n", tun_name); + snprintf(if_name, sizeof(if_name), "tun%d", i); + fd_set_close_on_exec(tun_fd); + return tun_fd; + } + + if (errno == ENOENT) + break; + } + + warn("open_tun: Failed to open tunneling device"); + } + + return -1; +} + #endif void @@ -365,10 +365,49 @@ close_tun(int tun_fd) close(tun_fd); } +#ifdef WINDOWS32 int write_tun(int tun_fd, char *data, size_t len) { -#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) || defined(WINDOWS32) + DWORD written; + DWORD res; + OVERLAPPED olpd; + + data += 4; + len -= 4; + + olpd.Offset = 0; + olpd.OffsetHigh = 0; + olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + res = WriteFile(dev_handle, data, len, &written, &olpd); + if (!res && GetLastError() == ERROR_IO_PENDING) { + WaitForSingleObject(olpd.hEvent, INFINITE); + res = GetOverlappedResult(dev_handle, &olpd, &written, FALSE); + if (written != len) { + return -1; + } + } + return 0; +} + +ssize_t +read_tun(int tun_fd, char *buf, size_t len) +{ + int bytes; + memset(buf, 0, 4); + + bytes = recv(tun_fd, buf + 4, len - 4, 0); + if (bytes < 0) { + return bytes; + } else { + return bytes + 4; + } +} +#else +int +write_tun(int tun_fd, char *data, size_t len) +{ +#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) data += 4; len -= 4; #else /* !FREEBSD/DARWIN */ @@ -385,47 +424,22 @@ write_tun(int tun_fd, char *data, size_t len) #endif /* !LINUX */ #endif /* FREEBSD */ -#ifndef WINDOWS32 if (write(tun_fd, data, len) != len) { warn("write_tun"); return 1; } -#else /* WINDOWS32 */ - { - DWORD written; - DWORD res; - OVERLAPPED olpd; - - olpd.Offset = 0; - olpd.OffsetHigh = 0; - olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - res = WriteFile(dev_handle, data, len, &written, &olpd); - if (!res && GetLastError() == ERROR_IO_PENDING) { - WaitForSingleObject(olpd.hEvent, INFINITE); - res = GetOverlappedResult(dev_handle, &olpd, &written, FALSE); - if (written != len) { - return -1; - } - } - } -#endif return 0; } ssize_t read_tun(int tun_fd, char *buf, size_t len) { -#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) || defined(WINDOWS32) +#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) /* FreeBSD/Darwin/NetBSD has no header */ int bytes; memset(buf, 0, 4); -#ifdef WINDOWS32 - /* Windows needs recv() since it is local UDP socket */ - bytes = recv(tun_fd, buf + 4, len - 4, 0); -#else - /* The other need read() because fd is not a socket */ + bytes = read(tun_fd, buf + 4, len - 4); -#endif /*WINDOWS32*/ if (bytes < 0) { return bytes; } else { @@ -435,6 +449,7 @@ read_tun(int tun_fd, char *buf, size_t len) return read(tun_fd, buf, len); #endif /* !FREEBSD */ } +#endif int tun_setip(const char *ip, const char *other_ip, int netbits) From b715be5cf3978fbe589b03b09c9398d0d791f850 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 16 Jun 2014 21:12:49 +0200 Subject: [PATCH 24/64] Fix authentication bypass bug The client could bypass the password check by continuing after getting error from the server and guessing the network parameters. The server would still accept the rest of the setup and also network traffic. Add checks for normal and raw mode that user has authenticated before allowing any other communication. Problem found by Oscar Reparaz. --- CHANGELOG | 1 + src/iodined.c | 44 +++++++++++++++++++++++++++++++++----------- src/user.c | 8 +++++++- src/user.h | 2 ++ tests/user.c | 9 +++++++++ 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 01173a1..9f3f967 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ master: - Do not let sockets be inherited by sub-processes, fixes #99. - Add unspecified RR type (called PRIVATE; id 65399, in private use range). For servers with RFC3597 support. Fixes #97. + - Fix authentication bypass vulnerability; found by Oscar Reparaz. 2010-02-06: 0.6.0-rc1 "Hotspotify" - Fixed tunnel not working on Windows. diff --git a/src/iodined.c b/src/iodined.c index c14f1a7..cdfc920 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -174,6 +174,7 @@ syslog(int a, const char *str, ...) } #endif +/* This will not check that user has passed login challenge */ static int check_user_and_ip(int userid, struct query *q) { @@ -200,6 +201,20 @@ check_user_and_ip(int userid, struct query *q) return memcmp(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); } +/* This checks that user has passed normal (non-raw) login challenge */ +static int +check_authenticated_user_and_ip(int userid, struct query *q) +{ + int res = check_user_and_ip(userid, q); + if (res) + return res; + + if (!users[userid].authenticated) + return 1; + + return 0; +} + static void send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q) { @@ -836,8 +851,10 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) login_calculate(logindata, 16, password, users[userid].seed); if (read >= 18 && (memcmp(logindata, unpacked+1, 16) == 0)) { - /* Login ok, send ip/mtu/netmask info */ + /* Store login ok */ + users[userid].authenticated = 1; + /* Send ip/mtu/netmask info */ tempip.s_addr = my_ip; tmp[0] = strdup(inet_ntoa(tempip)); tempip.s_addr = users[userid].tun_ip; @@ -866,7 +883,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) char reply[5]; userid = b32_8to5(in[1]); - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -903,7 +920,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) userid = b32_8to5(in[1]); - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -944,7 +961,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) userid = b32_8to5(in[1]); - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -1072,7 +1089,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) /* Downstream fragsize probe packet */ userid = (b32_8to5(in[1]) >> 1) & 15; - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -1107,7 +1124,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) /* Downstream fragsize packet */ userid = unpacked[0]; - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -1140,7 +1157,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) /* Ping packet, store userid */ userid = unpacked[0]; - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -1270,7 +1287,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) userid = code; /* Check user and sending ip number */ - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { write_dns(dns_fd, q, "BADIP", 5, 'T'); return; /* illegal id */ } @@ -1847,10 +1864,11 @@ handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) if (len < 16) return; - /* can't use check_user_and_ip() since IP address will be different, + /* can't use check_authenticated_user_and_ip() since IP address will be different, so duplicate here except IP address */ if (userid < 0 || userid >= created_users) return; if (!users[userid].active || users[userid].disabled) return; + if (!users[userid].authenticated) return; if (users[userid].last_pkt + 60 < time(NULL)) return; if (debug >= 1) { @@ -1875,15 +1893,18 @@ handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) user_set_conn_type(userid, CONN_RAW_UDP); login_calculate(myhash, 16, password, users[userid].seed - 1); send_raw(fd, myhash, 16, userid, RAW_HDR_CMD_LOGIN, q); + + users[userid].authenticated_raw = 1; } } static void handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid) { - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { return; } + if (!users[userid].authenticated_raw) return; /* Update query and time info for user */ users[userid].last_pkt = time(NULL); @@ -1905,9 +1926,10 @@ handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, static void handle_raw_ping(struct query *q, int dns_fd, int userid) { - if (check_user_and_ip(userid, q) != 0) { + if (check_authenticated_user_and_ip(userid, q) != 0) { return; } + if (!users[userid].authenticated_raw) return; /* Update query and time info for user */ users[userid].last_pkt = time(NULL); diff --git a/src/user.c b/src/user.c index 67821a4..0dc95db 100644 --- a/src/user.c +++ b/src/user.c @@ -75,6 +75,8 @@ init_users(in_addr_t my_ip, int netbits) users[i].tun_ip = ip; net.s_addr = ip; users[i].disabled = 0; + users[i].authenticated = 0; + users[i].authenticated_raw = 0; users[i].active = 0; /* Rest is reset on login ('V' packet) */ } @@ -116,7 +118,9 @@ find_user_by_ip(uint32_t ip) ret = -1; for (i = 0; i < usercount; i++) { - if (users[i].active && !users[i].disabled && + if (users[i].active && + users[i].authenticated && + !users[i].disabled && users[i].last_pkt + 60 > time(NULL) && ip == users[i].tun_ip) { ret = i; @@ -168,6 +172,8 @@ find_available_user() /* Not used at all or not used in one minute */ if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) { users[i].active = 1; + users[i].authenticated = 0; + users[i].authenticated_raw = 0; users[i].last_pkt = time(NULL); users[i].fragsize = 4096; users[i].conn = CONN_DNS_NULL; diff --git a/src/user.h b/src/user.h index 00d883b..76fc54b 100644 --- a/src/user.h +++ b/src/user.h @@ -37,6 +37,8 @@ struct tun_user { char id; int active; + int authenticated; + int authenticated_raw; int disabled; time_t last_pkt; int seed; diff --git a/tests/user.c b/tests/user.c index 6534317..2e4f36d 100644 --- a/tests/user.c +++ b/tests/user.c @@ -94,6 +94,11 @@ START_TEST(test_find_user_by_ip) users[0].last_pkt = time(NULL); + testip = (unsigned int) inet_addr("127.0.0.2"); + fail_unless(find_user_by_ip(testip) == -1); + + users[0].authenticated = 1; + testip = (unsigned int) inet_addr("127.0.0.2"); fail_unless(find_user_by_ip(testip) == 0); } @@ -137,7 +142,11 @@ START_TEST(test_find_available_user) init_users(ip, 27); for (i = 0; i < USERS; i++) { + users[i].authenticated = 1; + users[i].authenticated_raw = 1; fail_unless(find_available_user() == i); + fail_if(users[i].authenticated); + fail_if(users[i].authenticated_raw); } for (i = 0; i < USERS; i++) { From eec0a868d9be78a2affa4c15d52da566eccdc573 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 16 Jun 2014 22:26:01 +0200 Subject: [PATCH 25/64] Set correct sockaddr length when sending Fix EINVAL error on NetBSD --- src/client.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client.c b/src/client.c index 8db89fc..0f951ac 100644 --- a/src/client.c +++ b/src/client.c @@ -63,6 +63,7 @@ static int running; static const char *password; static struct sockaddr_storage nameserv; +static int nameserv_len; static struct sockaddr_in raw_serv; static const char *topdomain; @@ -153,6 +154,7 @@ void client_set_nameserver(struct sockaddr_storage *addr, int addrlen) { memcpy(&nameserv, addr, addrlen); + nameserv_len = addrlen; } void @@ -270,7 +272,7 @@ send_query(int fd, char *hostname) fprintf(stderr, " Sendquery: id %5d name[0] '%c'\n", q.id, hostname[0]); #endif - sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, sizeof(nameserv)); + sendto(fd, packet, len, 0, (struct sockaddr*)&nameserv, nameserv_len); /* There are DNS relays that time out quickly but don't send anything back on timeout. From b4c3656c3ccb5b819f86951588f742b8d0ff682b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 16 Jun 2014 23:43:20 +0200 Subject: [PATCH 26/64] Update changelog after release --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 9f3f967..7e9446d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ iodine - http://code.kryo.se/iodine CHANGES: master: + - Nothing yet + +2014-06-16: 0.7.0 "Kryoptonite" - Partial IPv6 support (#107) Client can connect to iodined through an relaying IPv6 nameserver. Server only supports IPv4 for now. From cc4bc22447d15deacf44bc1d369621a63c934427 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 25 Jul 2014 02:02:48 +0200 Subject: [PATCH 27/64] osflags: use pkg-config for systemd support Recent versions of systemd don't ship with libsystemd-daemon.so anymore, but instead use libsystemd.so for everything. This is obviously problematic for using the same LDFLAGS on old systemd and new systemd. So, they also ship compatability pkgconfig files, which use the old names but return the new library. So, the most portable way to support both old and new systemd is to use pkgconfig. It's not a problem either, since systems that use systemd are bound to also have pkgconfig installed. --- src/osflags | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osflags b/src/osflags index 9eda8f0..0f8a26c 100755 --- a/src/osflags +++ b/src/osflags @@ -19,7 +19,7 @@ link) Linux) FLAGS=""; [ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -lselinux"; - [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS -lsystemd-daemon"; + [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS $(pkg-config --libs libsystemd-daemon)"; echo $FLAGS; ;; esac From 81d932703b1368d1e6a083435ae0c3bc95635af3 Mon Sep 17 00:00:00 2001 From: Nicolas Braud-Santoni Date: Sun, 3 Aug 2014 21:42:36 +0200 Subject: [PATCH 28/64] Revamping the README file --- README => README.md | 345 +++++++++++++++++++++++--------------------- 1 file changed, 184 insertions(+), 161 deletions(-) rename README => README.md (53%) diff --git a/README b/README.md similarity index 53% rename from README rename to README.md index cfc8ede..033545c 100644 --- a/README +++ b/README.md @@ -1,130 +1,136 @@ +iodine - +===================================== -iodine - http://code.kryo.se/iodine - -*********************************** This is a piece of software that lets you tunnel IPv4 data through a DNS server. This can be usable in different situations where internet access is firewalled, but DNS queries are allowed. -COMPILING: +COMPILING +--------- Iodine has no configure script. There are two optional features for Linux (SELinux and systemd support) that will be enabled automatically if the -relevant header files are found in /usr/include. (See script at ./src/osflags) +relevant header files are found in `/usr/include`. +(See script at `./src/osflags`) -Run 'make' to compile the server and client binaries. -Run 'make install' to copy binaries and manpage to the destination directory. -Run 'make test' to compile and run the unit tests. (Requires the check library) +Run `make` to compile the server and client binaries. +Run `make install` to copy binaries and manpage to the destination directory. +Run `make test` to compile and run the unit tests. (Requires the `check` library) -QUICKSTART: +QUICKSTART +---------- Try it out within your own LAN! Follow these simple steps: -- On your server, run: ./iodined -f 10.0.0.1 test.com - (If you already use the 10.0.0.0 network, use another internal net like - 172.16.0.0) -- Enter a password -- On the client, run: ./iodine -f -r 192.168.0.1 test.com - (Replace 192.168.0.1 with your server's ip address) -- Enter the same password -- Now the client has the tunnel ip 10.0.0.2 and the server has 10.0.0.1 -- Try pinging each other through the tunnel +- On your server, run: `./iodined -f 10.0.0.1 test.com`. + If you already use the `10.0.0.0` network, use another internal net like + `172.16.0.0`. +- Enter a password. +- On the client, run: `./iodine -f -r 192.168.0.1 test.com`. + Replace `192.168.0.1` with your server's ip address. +- Enter the same password. +- Now the client has the tunnel ip `10.0.0.2` and the server has `10.0.0.1`. +- Try pinging each other through the tunnel. - Done! :) + To actually use it through a relaying nameserver, see below. -HOW TO USE: +HOW TO USE +---------- Note: server and client are required to speak the exact same protocol. In most cases, this means running the same iodine version. Unfortunately, implementing backward and forward protocol compatibility is usually not feasible. -Server side: -To use this tunnel, you need control over a real domain (like mydomain.com), -and a server with a public IP address to run iodined on. If this server -already runs a DNS program, change its listening port and then use iodined's --b option to let iodined forward the DNS requests. (Note that this procedure -is not advised in production environments, because iodined's DNS forwarding +### Server side +To use this tunnel, you need control over a real domain (like `mydomain.com`), +and a server with a public IP address to run `iodined` on. If this server +already runs a DNS program, change its listening port and then use `iodined`'s +`-b` option to let `iodined` forward the DNS requests. (Note that this procedure +is not advised in production environments, because `iodined`'s DNS forwarding is not completely transparent.) -Then, delegate a subdomain (say, t1.mydomain.com) to the iodined server. +Then, delegate a subdomain (say, `t1.mydomain.com`) to the iodined server. If you use BIND for your domain, add two lines like these to the zone file: -t1 IN NS t1ns.mydomain.com. ; note the dot! -t1ns IN A 10.15.213.99 + t1 IN NS t1ns.mydomain.com. ; note the dot! + t1ns IN A 10.15.213.99 -The "NS" line is all that's needed to route queries for the "t1" subdomain -to the "t1ns" server. We use a short name for the subdomain, to keep as much -space as possible available for the data traffic. At the end of the "NS" line -is the name of your iodined server. This can be any name, pointing anywhere, +The `NS` line is all that's needed to route queries for the `t1` subdomain +to the `t1ns` server. We use a short name for the subdomain, to keep as much +space as possible available for the data traffic. At the end of the `NS` line +is the name of your `iodined` server. This can be any name, pointing anywhere, but in this case it's easily kept in the same zone file. It must be a name -(not an IP address), and that name itself must have an A record (not a CNAME). +(not an IP address), and that name itself must have an `A` record +(not a `CNAME`). -If your iodined server has a dynamic IP, use a dynamic dns provider. Simply -point the "NS" line to it, and leave the "A" line out: +If your `iodined` server has a dynamic IP, use a dynamic DNS provider. Simply +point the `NS` line to it, and leave the `A` line out: -t1 IN NS myname.mydyndnsprovider.com. ; note the dot! + t1 IN NS myname.mydyndnsprovider.com. ; note the dot! Then reload or restart your nameserver program. Now any DNS queries for -domains ending in t1.mydomain.com will be sent to your iodined server. +domains ending in `t1.mydomain.com` will be sent to your `iodined` server. -Finally start iodined on your server. The first argument is the IP address +Finally start `iodined` on your server. The first argument is the IP address inside the tunnel, which can be from any range that you don't use yet (for -example 192.168.99.1), and the second argument is the assigned domain (in this -case t1.mydomain.com). Using the -f option will keep iodined running in the +example `192.168.99.1`), and the second argument is the assigned domain (in this +case `t1.mydomain.com`). Using the `-f` option will keep iodined running in the foreground, which helps when testing. iodined will open a virtual interface ("tun device"), and will also start listening for DNS queries on UDP port 53. -Either enter a password on the commandline (-P pass) or after the server has +Either enter a password on the commandline (`-P pass`) or after the server has started. Now everything is ready for the client. If there is a chance you'll be using an iodine tunnel from unexpected -environments, start iodined with a -c option. - +environments, start `iodined` with a `-c` option. Resulting commandline in this example situation: -./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com -Client side: -All the setup is done, just start iodine. It takes one or two arguments, the + ./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com + +### Client side +All the setup is done, just start `iodine`. It takes one or two arguments, the first is the local relaying DNS server (optional) and the second is the domain -you used (t1.mydomain.com). If you don't specify the first argument, the +you used (`t1.mydomain.com`). If you don't specify the first argument, the system's current DNS setting will be consulted. -If DNS queries are allowed to any computer, you can directly give the iodined -server's address as first argument (in the example: t1ns.mydomain.com or -10.15.213.99). In that case, it may also happen that _any_ traffic is allowed +If DNS queries are allowed to any computer, you can directly give the `iodined` +server's address as first argument (in the example: `t1ns.mydomain.com` or +`10.15.213.99`). In that case, it may also happen that _any_ traffic is allowed to the DNS port (53 UDP) of any computer. Iodine will detect this, and switch to raw UDP tunneling if possible. To force DNS tunneling in any case, use the --r option (especially useful when testing within your own network). +`-r` option (especially useful when testing within your own network). The client's tunnel interface will get an IP close to the server's (in this -case 192.168.99.2 or .3 etc.) and a suitable MTU. Enter the same password as +case `192.168.99.2` or `.3` etc.) and a suitable MTU. Enter the same password as on the server either as commandline option or after the client has started. -Using the -f option will keep the iodine client running in the foreground. +Using the `-f` option will keep the iodine client running in the foreground. -Resulting commandline in this example situation: -./iodine -f -P secretpassword t1.mydomain.com -(add -r to force DNS tunneling even if raw UDP tunneling would be possible) +Resulting commandline in this example situation, adding -r forces DNS tunneling +even if raw UDP tunneling would be possible: + + ./iodine -f -P secretpassword t1.mydomain.com From either side, you should now be able to ping the IP address on the other -end of the tunnel. In this case, ping 192.168.99.1 from the iodine client, and -192.168.99.2 or .3 etc. from the iodine server. +end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and +`192.168.99.2` from the iodine server. -MISC. INFO: +### MISC. INFO -IPv6: +#### IPv6 At the moment the iodined server only supports IPv4. The data inside the tunnel is IPv4 only. The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay nameservers will translate between protocols automatically if needed. Use -options -4 or -6 to force the client to use a specific IP version for its DNS +options `-4` or `-6` to force the client to use a specific IP version for its DNS queries. The client has to force IPv4 if it has dual-stack connectivity and -the hostname handling the tunnel domain has both A and AAAA records. +the hostname handling the tunnel domain has both `A` and `AAAA` records. -Routing: +#### Routing It is possible to route all traffic through the DNS tunnel. To do this, first add a host route to the nameserver used by iodine over the wired/wireless interface with the default gateway as gateway. Then replace the default @@ -138,70 +144,77 @@ shell (SSH) access, possibly with port forwarding. The latter can also be used for web browsing, when you run a web proxy (for example Privoxy) on your server. -Testing: -The iodined server replies to NS requests sent for subdomains of the tunnel -domain. If your iodined subdomain is t1.mydomain.com, send a NS request for -foo123.t1.mydomain.com to see if the delegation works. dig is a good tool -for this: -dig -t NS foo123.t1.mydomain.com +#### Testing +The `iodined` server replies to `NS` requests sent for subdomains of the tunnel +domain. If your iodined subdomain is `t1.mydomain.com`, send a `NS` request for +`foo123.t1.mydomain.com` to see if the delegation works. +`dig` is a good tool for this: + % dig -t NS foo123.t1.mydomain.com + ns.io.citronna.de. + Also, the iodined server will answer requests starting with 'z' for any of the supported request types, for example: -dig -t TXT z456.t1.mydomain.com -dig -t SRV z456.t1.mydomain.com -dig -t CNAME z456.t1.mydomain.com + + dig -t TXT z456.t1.mydomain.com + dig -t SRV z456.t1.mydomain.com + dig -t CNAME z456.t1.mydomain.com + The reply should look like garbled text in all these cases. -Operational info: + +Operational info +---------------- + The DNS-response fragment size is normally autoprobed to get maximum bandwidth. -To force a specific value (and speed things up), use the -m option. +To force a specific value (and speed things up), use the `-m` option. The DNS hostnames are normally used up to their maximum length, 255 characters. Some DNS relays have been found that answer full-length queries rather unreliably, giving widely varying (and mostly very bad) results of the -fragment size autoprobe on repeated tries. In these cases, use the -M switch -to reduce the DNS hostname length to for example 200 characters, which makes -these DNS relays much more stable. This is also useful on some "de-optimizing" +fragment size autoprobe on repeated tries. In these cases, use the `-M` switch +to reduce the DNS hostname length to, for example 200 characters, which makes +these DNS relays much more stable. This is also useful on some “de-optimizing” DNS relays that stuff the response with two full copies of the query, leaving -very little space for downstream data (also not capable of EDNS0). The -M +very little space for downstream data (also not capable of EDNS0). The `-M` switch can trade some upstream bandwidth for downstream bandwidth. Note that -the minimum -M value is about 100, since the protocol can split packets (1200 +the minimum `-M` value is about 100, since the protocol can split packets (1200 bytes max) in only 16 fragments, requiring at least 75 real data bytes per fragment. The upstream data is sent gzipped encoded with Base32; or Base64 if the relay -server supports mixed case and '+' in domain names; or Base64u if '_' is +server supports mixed case and `+` in domain names; or Base64u if `_` is supported instead; or Base128 if high-byte-value characters are supported. This upstream encoding is autodetected. The DNS protocol allows one query per packet, and one query can be max 256 chars. Each domain name part can be max 63 chars. So your domain name and subdomain should be as short as possible to allow maximum upstream throughput. -Several DNS request types are supported, with the NULL and PRIVATE types -expected to provide the largest downstream bandwidth. The PRIVATE type uses -value 65399 in the private-use range. Other available types are TXT, SRV, MX, -CNAME and A (returning CNAME), in decreasing bandwidth order. Normally the -"best" request type is autodetected and used. However, DNS relays may impose -limits on for example NULL and TXT, making SRV or MX actually the best choice. -This is not autodetected, but can be forced using the -T option. It is -advisable to try various alternatives especially when the autodetected request -type provides a downstream fragment size of less than 200 bytes. +Several DNS request types are supported, with the `NULL` and `PRIVATE` types +expected to provide the largest downstream bandwidth. The `PRIVATE` type uses +value 65399 in the private-use range. Other available types are `TXT`, `SRV`, +`MX`, `CNAME` and `A` (returning `CNAME`), in decreasing bandwidth order. +Normally the “best” request type is autodetected and used. However, DNS relays +may impose limits on for example NULL and TXT, making SRV or MX actually the best +choice. This is not autodetected, but can be forced using the `-T` option. +It is advisable to try various alternatives especially when the autodetected +request type provides a downstream fragment size of less than 200 bytes. -Note that SRV, MX and A (returning CNAME) queries may/will cause additional -lookups by "smart" caching nameservers to get an actual IP address, which may -either slow down or fail completely. +Note that `SRV`, `MX` and `A` (returning `CNAME`) queries may/will cause +additional lookups by "smart" caching nameservers to get an actual IP address, +which may either slow down or fail completely. -DNS responses for non-NULL/PRIVATE queries can be encoded with the same set of +DNS responses for non-`NULL/PRIVATE` queries can be encoded with the same set of codecs as upstream data. This is normally also autodetected, but no fully exhaustive tests are done, so some problems may not be noticed when selecting more advanced codecs. In that case, you'll see failures/corruption in the fragment size autoprobe. In particular, several DNS relays have been found that -change replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when -that hostname exceeds ca. 180 characters. In these and similar cases, use the --O option to try other downstream codecs; Base32 should always work. +change replies returning hostnames (`SRV`, `MX`, `CNAME`, `A`) to lowercase only +when that hostname exceeds ca. 180 characters. In these and similar cases, use +the `-O` option to try other downstream codecs; Base32 should always work. Normal operation now is for the server to _not_ answer a DNS request until -the next DNS request has come in, a.k.a. being "lazy". This way, the server +the next DNS request has come in, a.k.a. being “lazy”. This way, the server will always have a DNS request handy when new downstream data has to be sent. This greatly improves (interactive) performance and latency, and allows to slow down the quiescent ping requests to 4 second intervals by default, and @@ -209,24 +222,24 @@ possibly much slower. In fact, the main purpose of the pings now is to force a reply to the previous ping, and prevent DNS server timeouts (usually at least 5-10 seconds per RFC1035). Some DNS servers are more impatient and will give SERVFAIL errors (timeouts) in periods without tunneled data traffic. All -data should still get through in these cases, but iodine will reduce the ping +data should still get through in these cases, but `iodine` will reduce the ping interval to 1 second anyway (-I1) to reduce the number of error messages. This -may not help for very impatient DNS relays like dnsadvantage.com (ultradns), +may not help for very impatient DNS relays like `dnsadvantage.com` (ultradns), which time out in 1 second or even less. Yet data will still get trough, and -you can ignore the SERVFAIL errors. +you can ignore the `SERVFAIL` errors. If you are running on a local network without any DNS server in-between, try --I 50 (iodine and iodined close the connection after 60 seconds of silence). +`-I 50` (iodine and iodined close the connection after 60 seconds of silence). The only time you'll notice a slowdown, is when DNS reply packets go missing; -the iodined server then has to wait for a new ping to re-send the data. You can +the `iodined` server then has to wait for a new ping to re-send the data. You can speed this up by generating some upstream traffic (keypress, ping). If this -happens often, check your network for bottlenecks and/or run with -I1. +happens often, check your network for bottlenecks and/or run with `-I1`. -The delayed answering in lazy mode will cause some "carrier grade" commercial +The delayed answering in lazy mode will cause some “carrier grade” commercial DNS relays to repeatedly re-send the same DNS query to the iodined server. If the DNS relay is actually implemented as a pool of parallel servers, duplicate requests may even arrive from multiple sources. This effect will -only be visible in the network traffic at the iodined server, and will not +only be visible in the network traffic at the `iodined` server, and will not affect the client's connection. Iodined will notice these duplicates, and send the same answer (when its time has come) to both the original query and the latest duplicate. After that, the full answer is cached for a short while. @@ -236,16 +249,19 @@ iodine client will ignore (if it ever arrives there). If you have problems, try inspecting the traffic with network monitoring tools like tcpdump or ethereal/wireshark, and make sure that the relaying DNS server has not cached the response. A cached error message could mean that you -started the client before the server. The -D (and -DD) option on the server +started the client before the server. The `-D` (and `-DD`) option on the server can also show received and sent queries. -TIPS & TRICKS: +TIPS & TRICKS +------------- If your port 53 is taken on a specific interface by an application that does -not use it, use -p on iodined to specify an alternate port (like -p 5353) and -use for instance iptables (on Linux) to forward the traffic: -iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353 +not use it, use `-p` on iodined to specify an alternate port (like `-p 5353`) +and use for instance iptables (on Linux) to forward the traffic: + + iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353 + (Sent in by Tom Schouten) Iodined will reject data from clients that have not been active (data/pings) @@ -265,67 +281,70 @@ DNSCACHE_LEN is still advised, preferably 2 or higher, however you can also undefine it to save a few more kilobytes. -PERFORMANCE: +PERFORMANCE +----------- This section tabulates some performance measurements. To view properly, use a fixed-width font like Courier. Measurements were done in protocol 00000502 in lazy mode; upstream encoding -always Base128; iodine -M255; iodined -m1130. Network conditions were not +always Base128; `iodine -M255`; `iodined -m1130`. Network conditions were not extremely favorable; results are not benchmarks but a realistic indication of real-world performance that can be expected in similar situations. -Upstream/downstream throughput was measured by scp'ing a file previously -read from /dev/urandom (i.e. incompressible), and measuring size with -"ls -l ; sleep 30 ; ls -l" on a separate non-tunneled connection. Given the -large scp block size of 16 kB, this gives a resolution of 4.3 kbit/s, which +Upstream/downstream throughput was measured by `scp`'ing a file previously +read from `/dev/urandom` (i.e. incompressible), and measuring size with +`ls -l ; sleep 30 ; ls -l` on a separate non-tunneled connection. Given the +large `scp` block size of 16 kB, this gives a resolution of 4.3 kbit/s, which explains why some values are exactly equal. -Ping round-trip times measured with "ping -c100", presented are average rtt +Ping round-trip times measured with `ping -c100`, presented are average rtt and mean deviation (indicating spread around the average), in milliseconds. -Situation 1: -Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter - iodine DNS "relay" bind9 DNS cache iodined +### Situation 1: `Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter` - downstr. upstream downstr. ping-up ping-down - fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev ------------------------------------------------------------------------------- - -iodine -> Wifi AP :53 - -Tnull (= -Oraw) 982 43.6 131.0 28.0 4.6 26.8 3.4 - -iodine -> Home server :53 - -Tnull (= -Oraw) 1174 48.0 305.8 26.6 5.0 26.9 8.4 - -iodine -> DSL provider :53 - -Tnull (= -Oraw) 1174 56.7 367.0 20.6 3.1 21.2 4.4 - -Ttxt -Obase32 730 56.7 174.7* - -Ttxt -Obase64 874 56.7 174.7 - -Ttxt -Obase128 1018 56.7 174.7 - -Ttxt -Oraw 1162 56.7 358.2 - -Tsrv -Obase128 910 56.7 174.7 - -Tcname -Obase32 151 56.7 43.6 - -Tcname -Obase128 212 56.7 52.4 - -iodine -> DSL provider :53 - wired (no Wifi) -Tnull 1174 74.2 585.4 20.2 5.6 19.6 3.4 - - [174.7* : these all have 2frag/packet] + iodine DNS "relay" bind9 DNS cache iodined + + downstr. upstream downstr. ping-up ping-down + fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev + ----------------------------------------------------------------------------- + + iodine -> Wifi AP :53 + -Tnull (= -Oraw) 982 43.6 131.0 28.0 4.6 26.8 3.4 + + iodine -> Home server :53 + -Tnull (= -Oraw) 1174 48.0 305.8 26.6 5.0 26.9 8.4 + + iodine -> DSL provider :53 + -Tnull (= -Oraw) 1174 56.7 367.0 20.6 3.1 21.2 4.4 + -Ttxt -Obase32 730 56.7 174.7* + -Ttxt -Obase64 874 56.7 174.7 + -Ttxt -Obase128 1018 56.7 174.7 + -Ttxt -Oraw 1162 56.7 358.2 + -Tsrv -Obase128 910 56.7 174.7 + -Tcname -Obase32 151 56.7 43.6 + -Tcname -Obase128 212 56.7 52.4 + + iodine -> DSL provider :53 + wired (no Wifi) -Tnull 1174 74.2 585.4 20.2 5.6 19.6 3.4 + + [174.7* : these all have 2frag/packet] -Situation 2: -Laptop -> Wifi+vpn / wired -> Home server - iodine iodined +### Situation 2: `Laptop -> Wifi+vpn / wired -> Home server` - downstr. upstream downstr. ping-up ping-down - fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev ------------------------------------------------------------------------------- + iodine iodined + + downstr. upstream downstr. ping-up ping-down + fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev + ----------------------------------------------------------------------------- + + wifi + openvpn -Tnull 1186 166.0 1022.3 6.3 1.3 6.6 1.6 + + wired -Tnull 1186 677.2 2464.1 1.3 0.2 1.3 0.1 -wifi + openvpn -Tnull 1186 166.0 1022.3 6.3 1.3 6.6 1.6 - -wired -Tnull 1186 677.2 2464.1 1.3 0.2 1.3 0.1 +### Notes Performance is strongly coupled to low ping times, as iodine requires confirmation for every data fragment before moving on to the next. Allowing @@ -335,29 +354,33 @@ The current protocol scales performance with DNS responsivity, since the DNS servers are on average handling at most one DNS request per client. -PORTABILITY: +PORTABILITY +----------- iodine has been tested on Linux (arm, ia64, x86, AMD64 and SPARC64), FreeBSD (ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc and x86, with -http://tuntaposx.sourceforge.net/). and Windows (with OpenVPN TAP32 driver, see +). and Windows (with OpenVPN TAP32 driver, see win32 readme file). It should be easy to port to other unix-like systems that -has TUN/TAP tunneling support. Let us know if you get it to run on other -platforms. +have TUN/TAP tunneling support. Let us know if you get it to run on other +platforms. -THE NAME: +THE NAME +-------- The name iodine was chosen since it starts with IOD (IP Over DNS) and since iodine has atomic number 53, which happens to be the DNS port number. -THANKS: +THANKS +------ - To kuxien for FreeBSD and OS X testing - To poplix for code audit -AUTHORS & LICENSE: +AUTHORS & LICENSE +----------------- Copyright (c) 2006-2014 Erik Ekman , 2006-2009 Bjorn Andersson . Also major contributions by Anne Bezemer. @@ -375,5 +398,5 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -MD5 implementation by L. Peter Deutsch (license and source in src/md5.[ch]) +MD5 implementation by L. Peter Deutsch (license and source in `src/md5.[ch]`) Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. From 46532539c2284343d567d67f9c5c906411d5bc40 Mon Sep 17 00:00:00 2001 From: "Barak A. Pearlmutter" Date: Thu, 24 Apr 2014 15:03:47 +0100 Subject: [PATCH 29/64] Rename VERSION define prep for autotools: autoconf defines VERSION so s/VERSION/PROTOCOL_VERSION/ --- src/client.c | 7 ++++--- src/iodined.c | 4 ++-- src/version.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/client.c b/src/client.c index 0f951ac..c6236f6 100644 --- a/src/client.c +++ b/src/client.c @@ -1395,7 +1395,7 @@ handshake_version(int dns_fd, int *seed) for (i = 0; running && i < 5; i++) { - send_version(dns_fd, VERSION); + send_version(dns_fd, PROTOCOL_VERSION); read = handshake_waitdns(dns_fd, in, sizeof(in), 'v', 'V', i+1); @@ -1411,11 +1411,12 @@ handshake_version(int dns_fd, int *seed) userid_char = hex[userid & 15]; userid_char2 = hex2[userid & 15]; - fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", VERSION, userid); + fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n", + PROTOCOL_VERSION, userid); return 0; } else if (strncmp("VNAK", in, 4) == 0) { warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up", - VERSION, payload); + PROTOCOL_VERSION, payload); return 1; } else if (strncmp("VFUL", in, 4) == 0) { warnx("Server full, all %d slots are taken. Try again later", payload); diff --git a/src/iodined.c b/src/iodined.c index cdfc920..82a82eb 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -765,7 +765,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) ((unpacked[3] & 0xff))); } - if (version == VERSION) { + if (version == PROTOCOL_VERSION) { userid = find_available_user(); if (userid >= 0) { int i; @@ -826,7 +826,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) format_addr(&q->from, q->fromlen)); } } else { - send_version_response(dns_fd, VERSION_NACK, VERSION, 0, q); + send_version_response(dns_fd, VERSION_NACK, PROTOCOL_VERSION, 0, q); syslog(LOG_INFO, "dropped user from %s, sent bad version %08X", format_addr(&q->from, q->fromlen), version); } diff --git a/src/version.h b/src/version.h index 2ab00ff..67b7c42 100644 --- a/src/version.h +++ b/src/version.h @@ -20,7 +20,7 @@ /* This is the version of the network protocol It is usually equal to the latest iodine version number */ -#define VERSION 0x00000502 +#define PROTOCOL_VERSION 0x00000502 #endif /* _VERSION_H_ */ From 743342383640592b3338899a051057dcfe62caab Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 7 Aug 2014 20:03:46 +0200 Subject: [PATCH 30/64] Remove redundant strerror() in warn() calls --- src/tun.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tun.c b/src/tun.c index 60eedd7..c955b6d 100644 --- a/src/tun.c +++ b/src/tun.c @@ -81,7 +81,7 @@ open_tun(const char *tun_device) #endif if ((tun_fd = open(tunnel, O_RDWR)) < 0) { - warn("open_tun: %s: %s", tunnel, strerror(errno)); + warn("open_tun: %s", tunnel); return -1; } @@ -102,7 +102,7 @@ open_tun(const char *tun_device) } if (errno != EBUSY) { - warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno)); + warn("open_tun: ioctl[TUNSETIFF]"); return -1; } } else { @@ -117,7 +117,7 @@ open_tun(const char *tun_device) } if (errno != EBUSY) { - warn("open_tun: ioctl[TUNSETIFF]: %s", strerror(errno)); + warn("open_tun: ioctl[TUNSETIFF]"); return -1; } } @@ -328,7 +328,7 @@ open_tun(const char *tun_device) if_name[sizeof(if_name)-1] = '\0'; if ((tun_fd = open(tun_name, O_RDWR)) < 0) { - warn("open_tun: %s: %s", tun_name, strerror(errno)); + warn("open_tun: %s", tun_name); return -1; } From 9a45c4aa6640b9f8ee1b6bcc9178e2f791dc19e0 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Thu, 7 Aug 2014 21:14:10 +0200 Subject: [PATCH 31/64] Change license wording to follow ISC license exactly "Permission to use, copy, modify, and distribute this software" is now "Permission to use, copy, modify, and/or distribute this software". Add license header to source files missing one. --- README.md | 2 +- src/android_dns.h | 15 +++++++++++++++ src/base128.c | 2 +- src/base128.h | 2 +- src/base32.c | 2 +- src/base32.h | 2 +- src/base64.c | 2 +- src/base64.h | 2 +- src/client.c | 2 +- src/client.h | 2 +- src/common.c | 2 +- src/common.h | 2 +- src/dns.c | 2 +- src/dns.h | 2 +- src/encoding.c | 2 +- src/encoding.h | 2 +- src/fw_query.c | 2 +- src/fw_query.h | 2 +- src/iodine.c | 2 +- src/iodined.c | 2 +- src/login.c | 2 +- src/login.h | 2 +- src/read.c | 2 +- src/read.h | 2 +- src/tun.c | 2 +- src/tun.h | 2 +- src/user.c | 2 +- src/user.h | 2 +- src/util.c | 2 +- src/util.h | 17 +++++++++++++++++ src/version.h | 2 +- src/windows.h | 2 +- tests/base32.c | 2 +- tests/base64.c | 2 +- tests/common.c | 17 +++++++++++++++++ tests/dns.c | 2 +- tests/encoding.c | 2 +- tests/fw_query.c | 2 +- tests/login.c | 2 +- tests/read.c | 2 +- tests/test.c | 2 +- tests/test.h | 2 +- tests/user.c | 2 +- 43 files changed, 89 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 033545c..5ef7446 100644 --- a/README.md +++ b/README.md @@ -385,7 +385,7 @@ AUTHORS & LICENSE Copyright (c) 2006-2014 Erik Ekman , 2006-2009 Bjorn Andersson . Also major contributions by Anne Bezemer. -Permission to use, copy, modify, and distribute this software for any purpose +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. diff --git a/src/android_dns.h b/src/android_dns.h index dafd8ec..0085af6 100644 --- a/src/android_dns.h +++ b/src/android_dns.h @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2009 Marcel Bokhorst + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #ifndef __FIX_ANDROID_H__ #define __FIX_ANDROID_H__ diff --git a/src/base128.c b/src/base128.c index 7ddc38c..be7ba86 100644 --- a/src/base128.c +++ b/src/base128.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2009 J.A.Bezemer@opensourcepartners.nl * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/base128.h b/src/base128.h index 235b2f9..f4c55f6 100644 --- a/src/base128.h +++ b/src/base128.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2009 J.A.Bezemer@opensourcepartners.nl * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/base32.c b/src/base32.c index d971ce2..a058d38 100644 --- a/src/base32.c +++ b/src/base32.c @@ -3,7 +3,7 @@ * 2006-2009 Bjorn Andersson * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/base32.h b/src/base32.h index 53975c5..83ba784 100644 --- a/src/base32.h +++ b/src/base32.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/base64.c b/src/base64.c index 71bbcf1..7834731 100644 --- a/src/base64.c +++ b/src/base64.c @@ -3,7 +3,7 @@ * 2006-2009 Bjorn Andersson * Mostly rewritten 2009 J.A.Bezemer@opensourcepartners.nl * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/base64.h b/src/base64.h index 662175e..8ce4742 100644 --- a/src/base64.h +++ b/src/base64.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/client.c b/src/client.c index c6236f6..b0bb68c 100644 --- a/src/client.c +++ b/src/client.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/client.h b/src/client.h index 983b830..c2493f1 100644 --- a/src/client.h +++ b/src/client.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/common.c b/src/common.c index 2715979..a7f4aa7 100644 --- a/src/common.c +++ b/src/common.c @@ -2,7 +2,7 @@ * 2006-2009 Bjorn Andersson * Copyright (c) 2007 Albert Lee . * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/common.h b/src/common.h index 3c98c01..4f51175 100644 --- a/src/common.h +++ b/src/common.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/dns.c b/src/dns.c index 0d3b8b3..5f187e4 100644 --- a/src/dns.c +++ b/src/dns.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/dns.h b/src/dns.h index 7c1faff..b5d83b2 100644 --- a/src/dns.h +++ b/src/dns.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/encoding.c b/src/encoding.c index af7620e..4906a6b 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/encoding.h b/src/encoding.h index ab22279..abb82da 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/fw_query.c b/src/fw_query.c index 4f7d8c4..873307a 100644 --- a/src/fw_query.c +++ b/src/fw_query.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2008-2014 Erik Ekman * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/fw_query.h b/src/fw_query.h index f8f0de6..0aa8778 100644 --- a/src/fw_query.h +++ b/src/fw_query.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2008-2014 Erik Ekman * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/iodine.c b/src/iodine.c index 75e9e50..2599a6d 100644 --- a/src/iodine.c +++ b/src/iodine.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/iodined.c b/src/iodined.c index 82a82eb..d7bf363 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/login.c b/src/login.c index a809998..aa817c0 100644 --- a/src/login.c +++ b/src/login.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/login.h b/src/login.h index ebea25c..4d6d293 100644 --- a/src/login.h +++ b/src/login.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/read.c b/src/read.c index a2dcd96..2c26584 100644 --- a/src/read.c +++ b/src/read.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/read.h b/src/read.h index 2aac355..5da474d 100644 --- a/src/read.h +++ b/src/read.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/tun.c b/src/tun.c index c955b6d..1196ce2 100644 --- a/src/tun.c +++ b/src/tun.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/tun.h b/src/tun.h index 230484c..8982a9f 100644 --- a/src/tun.h +++ b/src/tun.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/user.c b/src/user.c index 0dc95db..61a16e8 100644 --- a/src/user.c +++ b/src/user.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/user.h b/src/user.h index 76fc54b..b5ccaa9 100644 --- a/src/user.h +++ b/src/user.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/util.c b/src/util.c index f4a538e..5cbad72 100644 --- a/src/util.c +++ b/src/util.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/util.h b/src/util.h index 6872077..a0ee03b 100644 --- a/src/util.h +++ b/src/util.h @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #ifndef __UTIL_H__ #define __UTIL_H__ diff --git a/src/version.h b/src/version.h index 67b7c42..5843a7a 100644 --- a/src/version.h +++ b/src/version.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/src/windows.h b/src/windows.h index c665a60..96288d1 100644 --- a/src/windows.h +++ b/src/windows.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/base32.c b/tests/base32.c index 419253f..4b460e2 100644 --- a/tests/base32.c +++ b/tests/base32.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/base64.c b/tests/base64.c index cd96d21..bcefc4c 100644 --- a/tests/base64.c +++ b/tests/base64.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/common.c b/tests/common.c index c1bc73f..742c04a 100644 --- a/tests/common.c +++ b/tests/common.c @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2006-2014 Erik Ekman , + * 2006-2009 Bjorn Andersson + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include #include #include diff --git a/tests/dns.c b/tests/dns.c index cdd3378..1f484ab 100644 --- a/tests/dns.c +++ b/tests/dns.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/encoding.c b/tests/encoding.c index 665c4dd..0d5f358 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/fw_query.c b/tests/fw_query.c index c6ed2c7..be8ce10 100644 --- a/tests/fw_query.c +++ b/tests/fw_query.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2009-2014 Erik Ekman * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/login.c b/tests/login.c index e154ee2..c814cee 100644 --- a/tests/login.c +++ b/tests/login.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/read.c b/tests/read.c index 24a5214..764e635 100644 --- a/tests/read.c +++ b/tests/read.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/test.c b/tests/test.c index cc753d4..eda792b 100644 --- a/tests/test.c +++ b/tests/test.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/test.h b/tests/test.h index 511cf31..d3f7985 100644 --- a/tests/test.h +++ b/tests/test.h @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * diff --git a/tests/user.c b/tests/user.c index 2e4f36d..7d8804e 100644 --- a/tests/user.c +++ b/tests/user.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson * - * Permission to use, copy, modify, and distribute this software for any + * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * From 434a023afefd5987efba964b952501b4d94818ca Mon Sep 17 00:00:00 2001 From: Ryan Welton Date: Fri, 8 Aug 2014 21:59:10 -0400 Subject: [PATCH 32/64] Fix warning for comparing enum CC user.c user.c:202:15: warning: comparison of unsigned enum expression < 0 is always false [-Wtautological-compare] if (c < 0 || c >= CONN_MAX) ~ ^ ~ --- src/common.h | 2 +- src/user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.h b/src/common.h index 4f51175..3dd22b3 100644 --- a/src/common.h +++ b/src/common.h @@ -104,7 +104,7 @@ struct query { }; enum connection { - CONN_RAW_UDP, + CONN_RAW_UDP = 0, CONN_DNS_NULL, CONN_MAX }; diff --git a/src/user.c b/src/user.c index 61a16e8..6391573 100644 --- a/src/user.c +++ b/src/user.c @@ -199,7 +199,7 @@ user_set_conn_type(int userid, enum connection c) if (userid < 0 || userid >= usercount) return; - if (c < 0 || c >= CONN_MAX) + if (c < CONN_RAW_UDP || c >= CONN_MAX) return; users[userid].conn = c; From 11606497941c4ad13724c53b406fad57a2913475 Mon Sep 17 00:00:00 2001 From: gregor herrmann Date: Fri, 23 Jan 2015 09:50:41 +0100 Subject: [PATCH 33/64] fix compilation error on kFreeBSD and Hurd --- src/osflags | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osflags b/src/osflags index 0f8a26c..45c2e59 100755 --- a/src/osflags +++ b/src/osflags @@ -38,6 +38,9 @@ cflags) [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS -DHAVE_SYSTEMD"; echo $FLAGS; ;; + GNU/kFreeBSD|GNU) + echo '-D_GNU_SOURCE' + ;; esac ;; *) From 33abc0ca2607b9cbaade53503e7b7cfb16119e17 Mon Sep 17 00:00:00 2001 From: Catalin Patulea Date: Thu, 5 Mar 2015 13:06:23 -0800 Subject: [PATCH 34/64] Support utun devices on Mac OS X. As of 10.6, OS X has native tunnel devices. They are implemented as sockets rather than character devices, but otherwise they appear to behave the same as Free/OpenBSD tunnels. '-d utunX' will tell iodine to use a utun device. For backward compatibility, we'll continue to default to the old tuntap devices for now. This is a port of Peter Sagerson 's openvpn commit 43e5016a. --- src/tun.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 25 deletions(-) diff --git a/src/tun.c b/src/tun.c index 1196ce2..4fb7126 100644 --- a/src/tun.c +++ b/src/tun.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2006-2014 Erik Ekman , * 2006-2009 Bjorn Andersson + * 2013 Peter Sagerson * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -25,6 +26,15 @@ #include #include +#ifdef DARWIN +#include +#include +#include +#include +#include +#include +#endif + #ifndef IFCONFIGPATH #define IFCONFIGPATH "PATH=/sbin:/bin " #endif @@ -315,6 +325,86 @@ open_tun(const char *tun_device) #else /* BSD and friends */ +#ifdef DARWIN + +/* Extract the device number from the name, if given. The value returned will + * be suitable for sockaddr_ctl.sc_unit, which means 0 for auto-assign, or + * (n + 1) for manual. + */ +static int +utun_unit(const char *dev) +{ + const char *unit_str = dev; + int unit = 0; + + while (*unit_str != '\0' && !isdigit(*unit_str)) + unit_str++; + + if (isdigit(*unit_str)) + unit = strtol(unit_str, NULL, 10) + 1; + + return unit; +} + +static int +open_utun(const char *dev) +{ + struct sockaddr_ctl addr; + struct ctl_info info; + char ifname[10]; + socklen_t ifname_len = sizeof(ifname); + int fd = -1; + int err = 0; + + fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if (fd < 0) { + warn("open_utun: socket(PF_SYSTEM)"); + return -1; + } + + /* Look up the kernel controller ID for utun devices. */ + bzero(&info, sizeof(info)); + strncpy(info.ctl_name, UTUN_CONTROL_NAME, MAX_KCTL_NAME); + + err = ioctl(fd, CTLIOCGINFO, &info); + if (err != 0) { + warn("open_utun: ioctl(CTLIOCGINFO)"); + close(fd); + return -1; + } + + /* Connecting to the socket creates the utun device. */ + addr.sc_len = sizeof(addr); + addr.sc_family = AF_SYSTEM; + addr.ss_sysaddr = AF_SYS_CONTROL; + addr.sc_id = info.ctl_id; + addr.sc_unit = utun_unit(dev); + + err = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (err != 0) { + warn("open_utun: connect"); + close(fd); + return -1; + } + + /* Retrieve the assigned interface name. */ + err = getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, ifname, &ifname_len); + if (err != 0) { + warn("open_utun: getsockopt(UTUN_OPT_IFNAME)"); + close(fd); + return -1; + } + + strncpy(if_name, ifname, sizeof(if_name)); + + fprintf(stderr, "Opened %s\n", ifname); + fd_set_close_on_exec(fd); + + return fd; +} + +#endif + int open_tun(const char *tun_device) { @@ -322,6 +412,15 @@ open_tun(const char *tun_device) int tun_fd; char tun_name[50]; +#ifdef DARWIN + if (!strncmp(tun_device, "utun", 4)) { + tun_fd = open_utun(tun_device); + if (tun_fd >= 0) { + return tun_fd; + } + } +#endif + if (tun_device != NULL) { snprintf(tun_name, sizeof(tun_name), "/dev/%s", tun_device); strncpy(if_name, tun_device, sizeof(if_name)); @@ -407,22 +506,32 @@ read_tun(int tun_fd, char *buf, size_t len) int write_tun(int tun_fd, char *data, size_t len) { -#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) - data += 4; - len -= 4; -#else /* !FREEBSD/DARWIN */ +#if defined (FREEBSD) || defined (NETBSD) + /* FreeBSD/NetBSD has no header */ + int header = 0; +#elif defined (DARWIN) + /* Darwin tun has no header, Darwin utun does */ + int header = !strncmp(if_name, "utun", 4); +#else /* LINUX/OPENBSD */ + int header = 1; +#endif + + if (!header) { + data += 4; + len -= 4; + } else { #ifdef LINUX - data[0] = 0x00; - data[1] = 0x00; - data[2] = 0x08; - data[3] = 0x00; + data[0] = 0x00; + data[1] = 0x00; + data[2] = 0x08; + data[3] = 0x00; #else /* OPENBSD */ - data[0] = 0x00; - data[1] = 0x00; - data[2] = 0x00; - data[3] = 0x02; -#endif /* !LINUX */ -#endif /* FREEBSD */ + data[0] = 0x00; + data[1] = 0x00; + data[2] = 0x00; + data[3] = 0x02; +#endif + } if (write(tun_fd, data, len) != len) { warn("write_tun"); @@ -434,20 +543,29 @@ write_tun(int tun_fd, char *data, size_t len) ssize_t read_tun(int tun_fd, char *buf, size_t len) { -#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) - /* FreeBSD/Darwin/NetBSD has no header */ - int bytes; - memset(buf, 0, 4); +#if defined (FREEBSD) || defined (NETBSD) + /* FreeBSD/NetBSD has no header */ + int header = 0; +#elif defined (DARWIN) + /* Darwin tun has no header, Darwin utun does */ + int header = !strncmp(if_name, "utun", 4); +#else /* LINUX/OPENBSD */ + int header = 1; +#endif - bytes = read(tun_fd, buf + 4, len - 4); - if (bytes < 0) { - return bytes; + if (!header) { + int bytes; + memset(buf, 0, 4); + + bytes = read(tun_fd, buf + 4, len - 4); + if (bytes < 0) { + return bytes; + } else { + return bytes + 4; + } } else { - return bytes + 4; + return read(tun_fd, buf, len); } -#else /* !FREEBSD */ - return read(tun_fd, buf, len); -#endif /* !FREEBSD */ } #endif From b38b2ca7c5189d4664adedb2e5e4554437963bc0 Mon Sep 17 00:00:00 2001 From: Catalin Patulea Date: Wed, 8 Apr 2015 01:40:19 -0400 Subject: [PATCH 35/64] Clarify that header is for both OPENBSD and DARWIN(utun). --- src/tun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tun.c b/src/tun.c index 4fb7126..44bb220 100644 --- a/src/tun.c +++ b/src/tun.c @@ -525,7 +525,7 @@ write_tun(int tun_fd, char *data, size_t len) data[1] = 0x00; data[2] = 0x08; data[3] = 0x00; -#else /* OPENBSD */ +#else /* OPENBSD and DARWIN(utun) */ data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; From 9e105d21d4e4155248f98cd081543ef5203eacd4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 8 Apr 2015 08:42:05 +0200 Subject: [PATCH 36/64] Add explanation for tun packet headers --- src/tun.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tun.c b/src/tun.c index 44bb220..c05a591 100644 --- a/src/tun.c +++ b/src/tun.c @@ -521,11 +521,15 @@ write_tun(int tun_fd, char *data, size_t len) len -= 4; } else { #ifdef LINUX + // Linux prefixes with 32 bits ethertype + // 0x0800 for IPv4, 0x86DD for IPv6 data[0] = 0x00; data[1] = 0x00; data[2] = 0x08; data[3] = 0x00; #else /* OPENBSD and DARWIN(utun) */ + // BSDs prefix with 32 bits address family + // AF_INET for IPv4, AF_INET6 for IPv6 data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; From 1f51bab2a3f09d13505d6e569b6e3c685f8fdfd2 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 8 Apr 2015 08:50:07 +0200 Subject: [PATCH 37/64] Update changelog --- CHANGELOG | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 7e9446d..32354ed 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,7 +6,13 @@ iodine - http://code.kryo.se/iodine CHANGES: master: - - Nothing yet + - Mac OS X: Support native utun VPN devices. Patch by + Peter Sagerson, ported from OpenVPN by Catalin Patulea. + - Fix compilation failure on kFreeBSD and Hurd, by Gregor Herrmann + - Patch from Ryan Welton that fixes compilation warning. + - REAMDE converted to markdown by Nicolas Braud-Santoni. + - Linux: use pkg-config for systemd support flags. + Patch by Jason A. Donenfeld. 2014-06-16: 0.7.0 "Kryoptonite" - Partial IPv6 support (#107) From 840155ca9aed2330540f6874cf95e8c5f852ff79 Mon Sep 17 00:00:00 2001 From: Catalin Patulea Date: Wed, 8 Apr 2015 02:59:26 -0400 Subject: [PATCH 38/64] Document utunX. --- README.md | 4 ++++ man/iodine.8 | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ef7446..51bc053 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,10 @@ supported request types, for example: The reply should look like garbled text in all these cases. +#### Mac OS X +On Mac OS X 10.6 and later, iodine supports the native utun devices built into +the OS - use `-d utunX`. + Operational info ---------------- diff --git a/man/iodine.8 b/man/iodine.8 index feb8283..c9072a5 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -118,7 +118,8 @@ Chroot to 'chrootdir' after setting up tunnel. .TP .B -d device Use the TUN device 'device' instead of the normal one, which is dnsX on Linux -and otherwise tunX. +and otherwise tunX. On Mac OS X 10.6, this can also be utunX, which will attempt +to use an utun device built into the OS. .TP .B -P password Use 'password' to authenticate. If not used, From 778d29825d2e0f90e540d5c835df844fb25cb19d Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 27 Jun 2015 11:57:39 +0200 Subject: [PATCH 39/64] Switch to IPv6-ready storage of user IP address --- src/iodined.c | 28 +++++++++++++++++----------- src/user.h | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index d7bf363..4125ef7 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -178,8 +178,6 @@ syslog(int a, const char *str, ...) static int check_user_and_ip(int userid, struct query *q) { - struct sockaddr_in *tempin; - /* Note: duplicate in handle_raw_login() except IP-address check */ if (userid < 0 || userid >= created_users ) { @@ -197,8 +195,19 @@ check_user_and_ip(int userid, struct query *q) return 0; } - tempin = (struct sockaddr_in *) &(q->from); - return memcmp(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); + if (q->from.ss_family != users[userid].host.ss_family) { + return 1; + } + /* Check IPv4 */ + if (q->from.ss_family == AF_INET) { + struct sockaddr_in *expected, *received; + + expected = (struct sockaddr_in *) &(users[userid].host); + received = (struct sockaddr_in *) &(q->from); + return memcmp(&(expected->sin_addr), &(received->sin_addr), sizeof(struct in_addr)); + } + /* Unknown address family */ + return 1; } /* This checks that user has passed normal (non-raw) login challenge */ @@ -769,12 +778,11 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) userid = find_available_user(); if (userid >= 0) { int i; - struct sockaddr_in *tempin; users[userid].seed = rand(); /* Store remote IP number */ - tempin = (struct sockaddr_in *) &(q->from); - memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); + memcpy(&(users[userid].host), &(q->from), q->fromlen); + users[userid].hostlen = q->fromlen; memcpy(&(users[userid].q), q, sizeof(struct query)); users[userid].encoder = get_base32_encoder(); @@ -1879,15 +1887,13 @@ handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) /* User sends hash of seed + 1 */ login_calculate(myhash, 16, password, users[userid].seed + 1); if (memcmp(packet, myhash, 16) == 0) { - struct sockaddr_in *tempin; - /* Update query and time info for user */ users[userid].last_pkt = time(NULL); memcpy(&(users[userid].q), q, sizeof(struct query)); /* Store remote IP number */ - tempin = (struct sockaddr_in *) &(q->from); - memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); + memcpy(&(users[userid].host), &(q->from), q->fromlen); + users[userid].hostlen = q->fromlen; /* Correct hash, reply with hash of seed - 1 */ user_set_conn_type(userid, CONN_RAW_UDP); diff --git a/src/user.h b/src/user.h index b5ccaa9..9f624b3 100644 --- a/src/user.h +++ b/src/user.h @@ -43,7 +43,8 @@ struct tun_user { time_t last_pkt; int seed; in_addr_t tun_ip; - struct in_addr host; + struct sockaddr_storage host; + socklen_t hostlen; struct query q; struct query q_sendrealsoon; int q_sendrealsoon_new; From 582a818f2a9c7387246fec8d40f45222622fcea8 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 27 Jun 2015 12:11:43 +0200 Subject: [PATCH 40/64] Switch external IP service to api.ipify.org externalip.net seems to have gone away --- src/iodined.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index 4125ef7..fa9b874 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -99,20 +99,20 @@ static int read_dns(int, int, struct query *); static void write_dns(int, struct query *, char *, int, char); static void handle_full_packet(int, int, int); -/* Ask externalip.net webservice to get external ip */ +/* Ask ipify.org webservice to get external ip */ static int get_external_ip(struct in_addr *ip) { int sock; struct addrinfo *addr; int res; - const char *getstr = "GET /ip/ HTTP/1.0\r\n" + const char *getstr = "GET / HTTP/1.0\r\n" /* HTTP 1.0 to avoid chunked transfer coding */ - "Host: api.externalip.net\r\n\r\n"; + "Host: api.ipify.org\r\n\r\n"; char buf[512]; char *b; int len; - res = getaddrinfo("api.externalip.net", "80", NULL, &addr); + res = getaddrinfo("api.ipify.org", "80", NULL, &addr); if (res < 0) return 1; sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); From 69a91d5421befd0529e94ca824413699ab33c18d Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 27 Jun 2015 12:14:34 +0200 Subject: [PATCH 41/64] Update changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 32354ed..26dd65e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ master: - REAMDE converted to markdown by Nicolas Braud-Santoni. - Linux: use pkg-config for systemd support flags. Patch by Jason A. Donenfeld. + - Change external IP webservice to ipify.org 2014-06-16: 0.7.0 "Kryoptonite" - Partial IPv6 support (#107) From 987a21a0d8d0186e94568f68406d9e20d8f60ea3 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sat, 27 Jun 2015 12:17:13 +0200 Subject: [PATCH 42/64] Update manpage --- man/iodine.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/iodine.8 b/man/iodine.8 index c9072a5..5d7b1f6 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -280,7 +280,7 @@ You must make sure the dns requests are forwarded to this port yourself. .B -n auto|external_ip The IP address to return in NS responses. Default is to return the address used as destination in the query. -If external_ip is 'auto', iodined will use externalip.net web service to +If external_ip is 'auto', iodined will use ipify.org web service to retrieve the external IP of the host and use that for NS responses. .TP .B -b dnsport From 3069665646880e311753a46a830ee4990dbfe841 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 10:36:49 +0200 Subject: [PATCH 43/64] Speling --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 26dd65e..be995f0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,7 +10,7 @@ master: Peter Sagerson, ported from OpenVPN by Catalin Patulea. - Fix compilation failure on kFreeBSD and Hurd, by Gregor Herrmann - Patch from Ryan Welton that fixes compilation warning. - - REAMDE converted to markdown by Nicolas Braud-Santoni. + - README converted to markdown by Nicolas Braud-Santoni. - Linux: use pkg-config for systemd support flags. Patch by Jason A. Donenfeld. - Change external IP webservice to ipify.org From 07c2fd4068eed5fe5ff06fb8eea7b481325cf41a Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 12:54:35 +0200 Subject: [PATCH 44/64] Prepare server code for IPv6 listening socket Add a struct with multiple dns file descriptors (for IPv4 and IPv6) and pass this to required areas. Choose which descriptor to use when sending by looking at the destination address family. --- src/iodined.c | 150 +++++++++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 56 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index fa9b874..8b32b66 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -95,12 +95,31 @@ static int debug; static char *__progname; #endif -static int read_dns(int, int, struct query *); -static void write_dns(int, struct query *, char *, int, char); -static void handle_full_packet(int, int, int); +/* Struct with IPv4 and IPv6 file descriptors. + * Need to be passed on down to tunneling code since we can get a + * packet on one fd meant for a user on the other. + */ +struct dnsfd { + int v4fd; + int v6fd; +}; + +static int read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q); +static void write_dns(int fd, struct query *q, char *data, int datalen, char downenc); +static void handle_full_packet(int tun_fd, struct dnsfd *dns_fds, int userid); + +static int +get_dns_fd(struct dnsfd *fds, struct sockaddr_storage *addr) +{ + if (addr->ss_family == AF_INET6) { + return fds->v6fd; + } + return fds->v4fd; +} /* Ask ipify.org webservice to get external ip */ -static int get_external_ip(struct in_addr *ip) +static int +get_external_ip(struct in_addr *ip) { int sock; struct addrinfo *addr; @@ -624,7 +643,7 @@ send_chunk_or_dataless(int dns_fd, int userid, struct query *q) } static int -tunnel_tun(int tun_fd, int dns_fd) +tunnel_tun(int tun_fd, struct dnsfd *dns_fds) { unsigned long outlen; struct ip *header; @@ -659,13 +678,17 @@ tunnel_tun(int tun_fd, int dns_fd) start_new_outpacket(userid, out, outlen); /* Start sending immediately if query is waiting */ - if (users[userid].q_sendrealsoon.id != 0) + if (users[userid].q_sendrealsoon.id != 0) { + int dns_fd = get_dns_fd(dns_fds, &users[userid].q_sendrealsoon.from); send_chunk_or_dataless(dns_fd, userid, &users[userid].q_sendrealsoon); - else if (users[userid].q.id != 0) + } else if (users[userid].q.id != 0) { + int dns_fd = get_dns_fd(dns_fds, &users[userid].q.from); send_chunk_or_dataless(dns_fd, userid, &users[userid].q); + } return outlen; } else { /* CONN_RAW_UDP */ + int dns_fd = get_dns_fd(dns_fds, &users[userid].q.from); send_raw(dns_fd, out, outlen, userid, RAW_HDR_CMD_DATA, &users[userid].q); return outlen; } @@ -742,7 +765,7 @@ process_downstream_ack(int userid, int down_seq, int down_frag) } static void -handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) +handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query *q, int domain_len) { struct in_addr tempip; char in[512]; @@ -1420,7 +1443,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len) } if (upstream_ok && lastfrag) { /* packet is complete */ - handle_full_packet(tun_fd, dns_fd, userid); + handle_full_packet(tun_fd, dns_fds, userid); } /* If there is a query that must be returned real soon, do it. @@ -1594,13 +1617,14 @@ forward_query(int bind_fd, struct query *q) } static int -tunnel_bind(int bind_fd, int dns_fd) +tunnel_bind(int bind_fd, struct dnsfd *dns_fds) { char packet[64*1024]; struct sockaddr_storage from; socklen_t fromlen; struct fw_query *query; unsigned short id; + int dns_fd; int r; fromlen = sizeof(struct sockaddr); @@ -1630,6 +1654,7 @@ tunnel_bind(int bind_fd, int dns_fd) format_addr(&query->addr, query->addrlen), (id & 0xffff), r); } + dns_fd = get_dns_fd(dns_fds, &query->addr); if (sendto(dns_fd, packet, r, 0, (const struct sockaddr *) &(query->addr), query->addrlen) <= 0) { warn("forward reply error"); @@ -1639,14 +1664,14 @@ tunnel_bind(int bind_fd, int dns_fd) } static int -tunnel_dns(int tun_fd, int dns_fd, int bind_fd) +tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd) { struct query q; int read; int domain_len; int inside_topdomain = 0; - if ((read = read_dns(dns_fd, tun_fd, &q)) <= 0) + if ((read = read_dns(dns_fd, dns_fds, tun_fd, &q)) <= 0) return 0; if (debug >= 2) { @@ -1694,7 +1719,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd) case T_SRV: case T_TXT: /* encoding is "transparent" here */ - handle_null_request(tun_fd, dns_fd, &q, domain_len); + handle_null_request(tun_fd, dns_fd, dns_fds, &q, domain_len); break; case T_NS: handle_ns_request(dns_fd, &q); @@ -1712,7 +1737,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd) } static int -tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) +tunnel(int tun_fd, struct dnsfd *dns_fds, int bind_fd, int max_idle_time) { struct timeval tv; fd_set fds; @@ -1745,8 +1770,8 @@ tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) FD_ZERO(&fds); - FD_SET(dns_fd, &fds); - maxfd = dns_fd; + FD_SET(dns_fds->v4fd, &fds); + maxfd = dns_fds->v4fd; if (bind_fd) { /* wait for replies from real DNS */ @@ -1783,15 +1808,15 @@ tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) } } } - } else { - if (FD_ISSET(tun_fd, &fds)) { - tunnel_tun(tun_fd, dns_fd); - } - if (FD_ISSET(dns_fd, &fds)) { - tunnel_dns(tun_fd, dns_fd, bind_fd); - } + } else { + if (FD_ISSET(tun_fd, &fds)) { + tunnel_tun(tun_fd, dns_fds); + } + if (FD_ISSET(dns_fds->v4fd, &fds)) { + tunnel_dns(tun_fd, dns_fds->v4fd, dns_fds, bind_fd); + } if (FD_ISSET(bind_fd, &fds)) { - tunnel_bind(bind_fd, dns_fd); + tunnel_bind(bind_fd, dns_fds); } } @@ -1801,15 +1826,17 @@ tunnel(int tun_fd, int dns_fd, int bind_fd, int max_idle_time) users[userid].last_pkt + 60 > time(NULL) && users[userid].q_sendrealsoon.id != 0 && users[userid].conn == CONN_DNS_NULL && - !users[userid].q_sendrealsoon_new) + !users[userid].q_sendrealsoon_new) { + int dns_fd = get_dns_fd(dns_fds, &users[userid].q_sendrealsoon.from); send_chunk_or_dataless(dns_fd, userid, &users[userid].q_sendrealsoon); + } } return 0; } static void -handle_full_packet(int tun_fd, int dns_fd, int userid) +handle_full_packet(int tun_fd, struct dnsfd *dns_fds, int userid) { unsigned long outlen; char out[64*1024]; @@ -1838,10 +1865,13 @@ handle_full_packet(int tun_fd, int dns_fd, int userid) users[userid].inpacket.len); /* Start sending immediately if query is waiting */ - if (users[touser].q_sendrealsoon.id != 0) + if (users[touser].q_sendrealsoon.id != 0) { + int dns_fd = get_dns_fd(dns_fds, &users[touser].q_sendrealsoon.from); send_chunk_or_dataless(dns_fd, touser, &users[touser].q_sendrealsoon); - else if (users[touser].q.id != 0) + } else if (users[touser].q.id != 0) { + int dns_fd = get_dns_fd(dns_fds, &users[touser].q.from); send_chunk_or_dataless(dns_fd, touser, &users[touser].q); + } #ifdef OUTPACKETQ_LEN } else { save_to_outpacketq(touser, @@ -1850,6 +1880,7 @@ handle_full_packet(int tun_fd, int dns_fd, int userid) #endif } } else{ /* CONN_RAW_UDP */ + int dns_fd = get_dns_fd(dns_fds, &users[touser].q.from); send_raw(dns_fd, users[userid].inpacket.data, users[userid].inpacket.len, touser, RAW_HDR_CMD_DATA, &users[touser].q); @@ -1905,7 +1936,7 @@ handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) } static void -handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid) +handle_raw_data(char *packet, int len, struct query *q, struct dnsfd *dns_fds, int tun_fd, int userid) { if (check_authenticated_user_and_ip(userid, q) != 0) { return; @@ -1926,7 +1957,7 @@ handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, users[userid].inpacket.len, userid); } - handle_full_packet(tun_fd, dns_fd, userid); + handle_full_packet(tun_fd, dns_fds, userid); } static void @@ -1950,7 +1981,7 @@ handle_raw_ping(struct query *q, int dns_fd, int userid) } static int -raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd) +raw_decode(char *packet, int len, struct query *q, int dns_fd, struct dnsfd *dns_fds, int tun_fd) { int raw_user; @@ -1967,7 +1998,7 @@ raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd) break; case RAW_HDR_CMD_DATA: /* Data packet */ - handle_raw_data(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, tun_fd, raw_user); + handle_raw_data(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fds, tun_fd, raw_user); break; case RAW_HDR_CMD_PING: /* Keepalive packet */ @@ -1981,7 +2012,8 @@ raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd) } static int -read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw_decode() below */ +read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) +/* FIXME: dns_fds and tun_fd are because of raw_decode() below */ { struct sockaddr_in from; socklen_t addrlen; @@ -2016,7 +2048,7 @@ read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw q->fromlen = addrlen; /* TODO do not handle raw packets here! */ - if (raw_decode(packet, r, q, fd, tun_fd)) { + if (raw_decode(packet, r, q, fd, dns_fds, tun_fd)) { return 0; } if (dns_decode(NULL, 0, q, QR_QUERY, packet, r) < 0) { @@ -2262,7 +2294,7 @@ int main(int argc, char **argv) { extern char *__progname; - char *listen_ip; + char *listen_ip4; char *errormsg; #ifndef WINDOWS32 struct passwd *pw; @@ -2273,7 +2305,7 @@ main(int argc, char **argv) char *context; char *device; char *pidfile; - int dnsd_fd; + struct dnsfd dns_fds; int tun_fd; /* settings for forwarding normal DNS to @@ -2289,8 +2321,8 @@ main(int argc, char **argv) int ns_get_externalip; int retval; int max_idle_time = 0; - struct sockaddr_storage dnsaddr; - int dnsaddr_len; + struct sockaddr_storage dns4addr; + int dns4addr_len; #ifdef HAVE_SYSTEMD int nb_fds; #endif @@ -2308,7 +2340,7 @@ main(int argc, char **argv) bind_fd = 0; mtu = 1130; /* Very many relays give fragsize 1150 or slightly higher for NULL; tun/zlib adds ~17 bytes. */ - listen_ip = NULL; + listen_ip4 = NULL; port = 53; ns_ip = INADDR_ANY; ns_get_externalip = 0; @@ -2374,7 +2406,7 @@ main(int argc, char **argv) mtu = atoi(optarg); break; case 'l': - listen_ip = optarg; + listen_ip4 = optarg; break; case 'p': port = atoi(optarg); @@ -2471,14 +2503,14 @@ main(int argc, char **argv) foreground = 1; } - dnsaddr_len = get_addr(listen_ip, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dnsaddr); - if (dnsaddr_len < 0) { + dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dns4addr); + if (dns4addr_len < 0) { warnx("Bad IP address to listen on."); usage(); } if(bind_enable) { - in_addr_t dns_ip = ((struct sockaddr_in *) &dnsaddr)->sin_addr.s_addr; + in_addr_t dns_ip = ((struct sockaddr_in *) &dns4addr)->sin_addr.s_addr; if (bind_port < 1 || bind_port > 65535) { warnx("Bad DNS server port number given."); usage(); @@ -2526,30 +2558,36 @@ main(int argc, char **argv) if ((tun_fd = open_tun(device)) == -1) { retval = 1; - goto cleanup0; + goto cleanup_none; } if (!skipipconfig) { const char *other_ip = users_get_first_ip(); if (tun_setip(argv[0], other_ip, netmask) != 0 || tun_setmtu(mtu) != 0) { retval = 1; free((void*) other_ip); - goto cleanup1; + goto cleanup_tun; } free((void*) other_ip); } + + /* Mark both file descriptors as unused */ + dns_fds.v4fd = -1; + dns_fds.v6fd = -1; + #ifdef HAVE_SYSTEMD nb_fds = sd_listen_fds(0); if (nb_fds > 1) { retval = 1; warnx("Too many file descriptors received!\n"); - goto cleanup1; + goto cleanup_tun; } else if (nb_fds == 1) { - dnsd_fd = SD_LISTEN_FDS_START; + /* XXX: assume we get IPv4 socket */ + dns_fds.v4fd = SD_LISTEN_FDS_START; } else { #endif - if ((dnsd_fd = open_dns(&dnsaddr, dnsaddr_len)) < 0) { + if ((dns_fds.v4fd = open_dns(&dns4addr, dns4addr_len)) < 0) { retval = 1; - goto cleanup2; + goto cleanup_tun; } #ifdef HAVE_SYSTEMD } @@ -2557,7 +2595,7 @@ main(int argc, char **argv) if (bind_enable) { if ((bind_fd = open_dns_from_host(NULL, 0, AF_INET, 0)) < 0) { retval = 1; - goto cleanup3; + goto cleanup_dns4; } } @@ -2602,16 +2640,16 @@ main(int argc, char **argv) syslog(LOG_INFO, "started, listening on port %d", port); - tunnel(tun_fd, dnsd_fd, bind_fd, max_idle_time); + tunnel(tun_fd, &dns_fds, bind_fd, max_idle_time); syslog(LOG_INFO, "stopping"); -cleanup3: close_dns(bind_fd); -cleanup2: - close_dns(dnsd_fd); -cleanup1: +cleanup_dns4: + if (dns_fds.v4fd >= 0) + close_dns(dns_fds.v4fd); +cleanup_tun: close_tun(tun_fd); -cleanup0: +cleanup_none: return retval; } From 7a117bd71eb9e67d21faaf456c0c9f495cce3f2b Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 20:01:48 +0200 Subject: [PATCH 45/64] IPv6 support for DNS traffic in server Server will by default listen on both IPv4 and IPv6. No way to only listen on one protocol right now. Use -L to only listen on a specific v6 address. IP address to use for raw mode is still IPv4 only. Use -n on server to make raw mode work from IPv6 clients, then they will get an IPv4 address from the server for raw mode. Tunnel data is still IPv4. --- CHANGELOG | 2 ++ README.md | 10 ++++--- man/iodine.8 | 38 ++++++++++++++---------- src/common.h | 4 +-- src/iodined.c | 81 ++++++++++++++++++++++++++++++++++++++------------- 5 files changed, 92 insertions(+), 43 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index be995f0..a637541 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ master: - Linux: use pkg-config for systemd support flags. Patch by Jason A. Donenfeld. - Change external IP webservice to ipify.org + - Add support for IPv6 in the server. (Raw mode missing) + Traffic inside tunnel is still IPv4. 2014-06-16: 0.7.0 "Kryoptonite" - Partial IPv6 support (#107) diff --git a/README.md b/README.md index 51bc053..9939a5c 100644 --- a/README.md +++ b/README.md @@ -121,14 +121,16 @@ end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and ### MISC. INFO #### IPv6 -At the moment the iodined server only supports IPv4. The data inside the tunnel -is IPv4 only. +The data inside the tunnel is IPv4 only. + +The server listens to both IPv4 and IPv6 for incoming requests. Raw mode +currently only works for IPv4, or can use IPv4 from IPv6 login if -n option is +used. The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay nameservers will translate between protocols automatically if needed. Use options `-4` or `-6` to force the client to use a specific IP version for its DNS -queries. The client has to force IPv4 if it has dual-stack connectivity and -the hostname handling the tunnel domain has both `A` and `AAAA` records. +queries. #### Routing It is possible to route all traffic through the DNS tunnel. To do this, first diff --git a/man/iodine.8 b/man/iodine.8 index 5d7b1f6..3a8cea6 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -54,7 +54,9 @@ iodine, iodined \- tunnel IPv4 over DNS .B ] [-m .I mtu .B ] [-l -.I listen_ip +.I listen_ip4 +.B ] [-L +.I listen_ip6 .B ] [-p .I port .B ] [-n @@ -81,9 +83,9 @@ iodine, iodined \- tunnel IPv4 over DNS .I topdomain .SH DESCRIPTION .B iodine -lets you tunnel IPv4 data through a DNS +lets you tunnel IPv4 data through a DNS server. This can be useful in situations where Internet access is firewalled, -but DNS queries are allowed. It needs a TUN/TAP device to operate. The +but DNS queries are allowed. It needs a TUN/TAP device to operate. The bandwidth is asymmetrical, with a measured maximum of 680 kbit/s upstream and 2.3 Mbit/s downstream in a wired LAN test network. @@ -122,7 +124,7 @@ and otherwise tunX. On Mac OS X 10.6, this can also be utunX, which will attempt to use an utun device built into the OS. .TP .B -P password -Use 'password' to authenticate. If not used, +Use 'password' to authenticate. If not used, .B stdin will be used as input. Only the first 32 characters will be used. .TP @@ -245,7 +247,7 @@ rejected, however this will cause problems when requests are routed via a cluster of DNS servers. .TP .B -s -Don't try to configure IP address or MTU. +Don't try to configure IP address or MTU. This should only be used if you have already configured the device that will be used. .TP @@ -261,18 +263,22 @@ This is easily done with : "LC_ALL=C luit iodined \-DD ..." (see luit(1)). .TP .B -m mtu -Set 'mtu' as mtu size for the tun device. +Set 'mtu' as mtu size for the tun device. This will be sent to the client on login, and the client will use the same mtu for its tun device. Default 1130. Note that the DNS traffic will be automatically fragmented when needed. .TP -.B -l listen_ip -Make the server listen only on 'listen_ip' for incoming requests. -By default, incoming requests are accepted from all interfaces. +.B -l listen_ip4 +Make the server listen only on 'listen_ip4' for incoming IPv4 requests. +By default, incoming requests are accepted from all interfaces (0.0.0.0). +.TP +.B -L listen_ip6 +Make the server listen only on 'listen_ip6' for incoming IPv6 requests. +By default, incoming requests are accepted from all interfaces (::) .TP .B -p port -Make the server listen on 'port' instead of 53 for traffic. -If 'listen_ip' does not include localhost, this 'port' can be the same +Make the server listen on 'port' instead of 53 for traffic. +If 'listen_ip4' does not include localhost, this 'port' can be the same as 'dnsport'. .B Note: You must make sure the dns requests are forwarded to this port yourself. @@ -308,7 +314,7 @@ file. .B topdomain The dns traffic will be sent as queries for subdomains under \'topdomain'. This is normally a subdomain to a domain you own. Use a short -domain name to get better throughput. If +domain name to get better throughput. If .B nameserver is the iodined server, then the topdomain can be chosen freely. This argument must be the same on both the client and the server. @@ -316,15 +322,15 @@ must be the same on both the client and the server. .TP .B tunnel_ip[/netmask] This is the server's ip address on the tun interface. The client will be -given the next ip number in the range. It is recommended to use the +given the next ip number in the range. It is recommended to use the 10.0.0.0 or 172.16.0.0 ranges. The default netmask is /27, can be overridden by specifying it here. Using a smaller network will limit the number of concurrent users. .TP .B topdomain The dns traffic is expected to arrive as queries for -subdomains under 'topdomain'. This is normally a subdomain to a domain you -own. Use a short domain name to get better throughput. This argument must be +subdomains under 'topdomain'. This is normally a subdomain to a domain you +own. Use a short domain name to get better throughput. This argument must be the same on both the client and the server. Queries for domains other than 'topdomain' will be forwarded when the \-b option is given, otherwise they will be dropped. @@ -349,7 +355,7 @@ except to the used ssh or vpn ports. If the environment variable .B IODINE_PASS is set, iodine will use the value it is set to as password instead of asking -for one. The +for one. The .B -P option still has precedence. .SS IODINED_PASS diff --git a/src/common.h b/src/common.h index 3dd22b3..a5b3427 100644 --- a/src/common.h +++ b/src/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2014 Erik Ekman , + * Copyright (c) 2006-2015 Erik Ekman , * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and/or distribute this software for any @@ -97,7 +97,7 @@ struct query { unsigned short id; struct in_addr destination; struct sockaddr_storage from; - int fromlen; + socklen_t fromlen; unsigned short id2; struct sockaddr from2; int fromlen2; diff --git a/src/iodined.c b/src/iodined.c index 8b32b66..aa73a45 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2014 Erik Ekman , + * Copyright (c) 2006-2015 Erik Ekman , * 2006-2009 Bjorn Andersson * * Permission to use, copy, modify, and/or distribute this software for any @@ -225,6 +225,14 @@ check_user_and_ip(int userid, struct query *q) received = (struct sockaddr_in *) &(q->from); return memcmp(&(expected->sin_addr), &(received->sin_addr), sizeof(struct in_addr)); } + /* Check IPv6 */ + if (q->from.ss_family == AF_INET6) { + struct sockaddr_in6 *expected, *received; + + expected = (struct sockaddr_in6 *) &(users[userid].host); + received = (struct sockaddr_in6 *) &(q->from); + return memcmp(&(expected->sin6_addr), &(received->sin6_addr), sizeof(struct in6_addr)); + } /* Unknown address family */ return 1; } @@ -1769,9 +1777,16 @@ tunnel(int tun_fd, struct dnsfd *dns_fds, int bind_fd, int max_idle_time) } FD_ZERO(&fds); + maxfd = 0; - FD_SET(dns_fds->v4fd, &fds); - maxfd = dns_fds->v4fd; + if (dns_fds->v4fd >= 0) { + FD_SET(dns_fds->v4fd, &fds); + maxfd = MAX(dns_fds->v4fd, maxfd); + } + if (dns_fds->v6fd >= 0) { + FD_SET(dns_fds->v6fd, &fds); + maxfd = MAX(dns_fds->v6fd, maxfd); + } if (bind_fd) { /* wait for replies from real DNS */ @@ -1815,6 +1830,9 @@ tunnel(int tun_fd, struct dnsfd *dns_fds, int bind_fd, int max_idle_time) if (FD_ISSET(dns_fds->v4fd, &fds)) { tunnel_dns(tun_fd, dns_fds->v4fd, dns_fds, bind_fd); } + if (FD_ISSET(dns_fds->v6fd, &fds)) { + tunnel_dns(tun_fd, dns_fds->v6fd, dns_fds, bind_fd); + } if (FD_ISSET(bind_fd, &fds)) { tunnel_bind(bind_fd, dns_fds); } @@ -2015,7 +2033,7 @@ static int read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) /* FIXME: dns_fds and tun_fd are because of raw_decode() below */ { - struct sockaddr_in from; + struct sockaddr_storage from; socklen_t addrlen; char packet[64*1024]; int r; @@ -2025,7 +2043,7 @@ read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) struct iovec iov; struct cmsghdr *cmsg; - addrlen = sizeof(struct sockaddr); + addrlen = sizeof(struct sockaddr_storage); iov.iov_base = packet; iov.iov_len = sizeof(packet); @@ -2039,7 +2057,7 @@ read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) r = recvmsg(fd, &msg, 0); #else - addrlen = sizeof(struct sockaddr); + addrlen = sizeof(struct sockaddr_storage); r = recvfrom(fd, packet, sizeof(packet), 0, (struct sockaddr*)&from, &addrlen); #endif /* !WINDOWS32 */ @@ -2236,26 +2254,27 @@ write_dns(int fd, struct query *q, char *data, int datalen, char downenc) } static void -usage() { +print_usage() { extern char *__progname; fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] [-z context] " - "[-l ip address to listen on] [-p port] [-n external ip] " - "[-b dnsport] [-P password] [-F pidfile] [-i max idle time] " + "[-l ipv4 listen address] [-L ipv6 listen address] " + "[-p port] [-n external ip] [-b dnsport] " + "[-P password] [-F pidfile] [-i max idle time] " "tunnel_ip[/netmask] topdomain\n", __progname); +} + +static void +usage() { + print_usage(); exit(2); } static void help() { - extern char *__progname; - fprintf(stderr, "iodine IP over DNS tunneling server\n"); - fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " - "[-t chrootdir] [-d device] [-m mtu] [-z context] " - "[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password] " - "[-F pidfile] tunnel_ip[/netmask] topdomain\n", __progname); + print_usage(); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); fprintf(stderr, " -c to disable check of client IP/port on each request\n"); @@ -2269,8 +2288,10 @@ help() { fprintf(stderr, " -d device to set tunnel device name\n"); fprintf(stderr, " -m mtu to set tunnel device mtu\n"); fprintf(stderr, " -z context to apply SELinux context after initialization\n"); - fprintf(stderr, " -l ip address to listen on for incoming dns traffic " + fprintf(stderr, " -l IPv4 address to listen on for incoming dns traffic " "(default 0.0.0.0)\n"); + fprintf(stderr, " -L IPv6 address to listen on for incoming dns traffic " + "(default ::)\n"); fprintf(stderr, " -p port to listen on for incoming dns traffic (default 53)\n"); fprintf(stderr, " -n ip to respond with to NS queries\n"); fprintf(stderr, " -b port to forward normal DNS queries to (on localhost)\n"); @@ -2295,6 +2316,7 @@ main(int argc, char **argv) { extern char *__progname; char *listen_ip4; + char *listen_ip6; char *errormsg; #ifndef WINDOWS32 struct passwd *pw; @@ -2322,7 +2344,9 @@ main(int argc, char **argv) int retval; int max_idle_time = 0; struct sockaddr_storage dns4addr; - int dns4addr_len; + socklen_t dns4addr_len; + struct sockaddr_storage dns6addr; + socklen_t dns6addr_len; #ifdef HAVE_SYSTEMD int nb_fds; #endif @@ -2341,6 +2365,7 @@ main(int argc, char **argv) mtu = 1130; /* Very many relays give fragsize 1150 or slightly higher for NULL; tun/zlib adds ~17 bytes. */ listen_ip4 = NULL; + listen_ip6 = NULL; port = 53; ns_ip = INADDR_ANY; ns_get_externalip = 0; @@ -2373,7 +2398,7 @@ main(int argc, char **argv) srand(time(NULL)); fw_query_init(); - while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:z:F:i:")) != -1) { + while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:L:p:n:b:P:z:F:i:")) != -1) { switch(choice) { case 'v': version(); @@ -2408,6 +2433,9 @@ main(int argc, char **argv) case 'l': listen_ip4 = optarg; break; + case 'L': + listen_ip6 = optarg; + break; case 'p': port = atoi(optarg); break; @@ -2505,7 +2533,12 @@ main(int argc, char **argv) dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dns4addr); if (dns4addr_len < 0) { - warnx("Bad IP address to listen on."); + warnx("Bad IPv4 address to listen on."); + usage(); + } + dns6addr_len = get_addr(listen_ip6, port, AF_INET6, AI_PASSIVE | AI_NUMERICHOST, &dns6addr); + if (dns6addr_len < 0) { + warnx("Bad IPv6 address to listen on."); usage(); } @@ -2589,13 +2622,17 @@ main(int argc, char **argv) retval = 1; goto cleanup_tun; } + if ((dns_fds.v6fd = open_dns(&dns6addr, dns6addr_len)) < 0) { + retval = 1; + goto cleanup_dns; + } #ifdef HAVE_SYSTEMD } #endif if (bind_enable) { if ((bind_fd = open_dns_from_host(NULL, 0, AF_INET, 0)) < 0) { retval = 1; - goto cleanup_dns4; + goto cleanup_dns; } } @@ -2644,7 +2681,9 @@ main(int argc, char **argv) syslog(LOG_INFO, "stopping"); close_dns(bind_fd); -cleanup_dns4: +cleanup_dns: + if (dns_fds.v6fd >= 0) + close_dns(dns_fds.v6fd); if (dns_fds.v4fd >= 0) close_dns(dns_fds.v4fd); cleanup_tun: From ec0e3f2e51113e197fa5dc083312c2301293ff1f Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 20:25:22 +0200 Subject: [PATCH 46/64] Change sockaddr lengths back to signed They are used to check negative return values. --- src/iodined.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index aa73a45..b4b12c2 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2344,9 +2344,9 @@ main(int argc, char **argv) int retval; int max_idle_time = 0; struct sockaddr_storage dns4addr; - socklen_t dns4addr_len; + int dns4addr_len; struct sockaddr_storage dns6addr; - socklen_t dns6addr_len; + int dns6addr_len; #ifdef HAVE_SYSTEMD int nb_fds; #endif From 7a51b2290979b6f1e828aeb9a1f106fe9d4f718e Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 21:05:23 +0200 Subject: [PATCH 47/64] Simplify cleanup code --- src/iodined.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index b4b12c2..be51281 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2587,32 +2587,32 @@ main(int argc, char **argv) read_password(password, sizeof(password)); } + /* Mark both file descriptors as unused */ + dns_fds.v4fd = -1; + dns_fds.v6fd = -1; + created_users = init_users(my_ip, netmask); if ((tun_fd = open_tun(device)) == -1) { - retval = 1; - goto cleanup_none; + /* nothing to clean up, just return */ + return 1; } if (!skipipconfig) { const char *other_ip = users_get_first_ip(); if (tun_setip(argv[0], other_ip, netmask) != 0 || tun_setmtu(mtu) != 0) { retval = 1; free((void*) other_ip); - goto cleanup_tun; + goto cleanup; } free((void*) other_ip); } - /* Mark both file descriptors as unused */ - dns_fds.v4fd = -1; - dns_fds.v6fd = -1; - #ifdef HAVE_SYSTEMD nb_fds = sd_listen_fds(0); if (nb_fds > 1) { retval = 1; warnx("Too many file descriptors received!\n"); - goto cleanup_tun; + goto cleanup; } else if (nb_fds == 1) { /* XXX: assume we get IPv4 socket */ dns_fds.v4fd = SD_LISTEN_FDS_START; @@ -2620,11 +2620,11 @@ main(int argc, char **argv) #endif if ((dns_fds.v4fd = open_dns(&dns4addr, dns4addr_len)) < 0) { retval = 1; - goto cleanup_tun; + goto cleanup; } if ((dns_fds.v6fd = open_dns(&dns6addr, dns6addr_len)) < 0) { retval = 1; - goto cleanup_dns; + goto cleanup; } #ifdef HAVE_SYSTEMD } @@ -2632,7 +2632,7 @@ main(int argc, char **argv) if (bind_enable) { if ((bind_fd = open_dns_from_host(NULL, 0, AF_INET, 0)) < 0) { retval = 1; - goto cleanup_dns; + goto cleanup; } } @@ -2681,14 +2681,12 @@ main(int argc, char **argv) syslog(LOG_INFO, "stopping"); close_dns(bind_fd); -cleanup_dns: +cleanup: if (dns_fds.v6fd >= 0) close_dns(dns_fds.v6fd); if (dns_fds.v4fd >= 0) close_dns(dns_fds.v4fd); -cleanup_tun: close_tun(tun_fd); -cleanup_none: return retval; } From b4e9148df8ddf8beefde62c78f1ac4f067f77109 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 22:41:54 +0200 Subject: [PATCH 48/64] Support raw mode for both IPv4 and IPv6 Read destination address of IP request packet and return it. Check length in client and use it as IPv4 or v6 depending on length. --- CHANGELOG | 3 +- README.md | 3 +- doc/proto_00000502.txt | 22 +++++---- src/client.c | 47 ++++++++++--------- src/common.c | 5 +- src/common.h | 15 ++---- src/iodined.c | 102 ++++++++++++++++++++++++++++++++--------- 7 files changed, 126 insertions(+), 71 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a637541..894ceaa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,7 +14,8 @@ master: - Linux: use pkg-config for systemd support flags. Patch by Jason A. Donenfeld. - Change external IP webservice to ipify.org - - Add support for IPv6 in the server. (Raw mode missing) + - Add support for IPv6 in the server. + Raw mode will be with same protocol as used for login. Traffic inside tunnel is still IPv4. 2014-06-16: 0.7.0 "Kryoptonite" diff --git a/README.md b/README.md index 9939a5c..61ab5ad 100644 --- a/README.md +++ b/README.md @@ -124,8 +124,7 @@ end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and The data inside the tunnel is IPv4 only. The server listens to both IPv4 and IPv6 for incoming requests. Raw mode -currently only works for IPv4, or can use IPv4 from IPv6 login if -n option is -used. +will be attempted on the same protocol as used for the login. The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay nameservers will translate between protocols automatically if needed. Use diff --git a/doc/proto_00000502.txt b/doc/proto_00000502.txt index 831824d..2edf49a 100644 --- a/doc/proto_00000502.txt +++ b/doc/proto_00000502.txt @@ -38,7 +38,7 @@ Server replies: VFUL (server has no free slots), followed by max users 4 byte value: means login challenge/server protocol version/max users 1 byte userid of the new user, or any byte if not VACK - + Login: Client sends: First byte l or L @@ -50,17 +50,19 @@ Server replies: LNAK means not accepted x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits) -IP Request: +IP Request: (for where to try raw login) Client sends: First byte i or I 5 bits coded as Base32 char, meaning userid CMC as 3 Base32 chars Server replies - BADIP if bad userid, or - I and then 4 bytes network order external IP address of iodined server + BADIP if bad userid + First byte I + Then comes external IP address of iodined server + as 4 bytes (IPv4) or 16 bytes (IPv6) Upstream codec check / bounce: -Client sends: +Client sends: First byte z or Z Lots of data that should not be decoded Server replies: @@ -100,7 +102,7 @@ Client sends: 7: Base128 (a-zA-Z0-9\274-\375) CMC as 3 Base32 chars Server sends: - Name of codec if accepted. After this all upstream data packets must + Name of codec if accepted. After this all upstream data packets must be encoded with the new codec. BADCODEC if not accepted. Client must then revert to previous codec BADLEN if length of query is too short @@ -182,7 +184,7 @@ GGGG = Downstream fragment number C = Compression enabled for downstream packet UDCMC = Upstream Data CMC, 36 steps a-z0-9, case-insensitive -Upstream data packet starts with 1 byte ASCII hex coded user byte; then 3 bytes +Upstream data packet starts with 1 byte ASCII hex coded user byte; then 3 bytes Base32 encoded header; then 1 char data-CMC; then comes the payload data, encoded with the chosen upstream codec. @@ -225,8 +227,8 @@ always starting with the 2 bytes downstream data header as shown above. If server has nothing to send, no data is added after the header. If server has something to send, it will add the downstream data packet (or some fragment of it) after the header. - - + + "Lazy-mode" operation ===================== @@ -250,7 +252,7 @@ downstream data has to be sent. *: upstream data ack is usually done as reply on the previous ping packet, and the upstream-data packet itself is kept in queue. - + Client: Downstream data is acked immediately, to keep it flowing fast (includes a ping after last downstream frag). diff --git a/src/client.c b/src/client.c index b0bb68c..759f652 100644 --- a/src/client.c +++ b/src/client.c @@ -64,7 +64,8 @@ static const char *password; static struct sockaddr_storage nameserv; static int nameserv_len; -static struct sockaddr_in raw_serv; +static struct sockaddr_storage raw_serv; +static int raw_serv_len; static const char *topdomain; static uint16_t rand_seed; @@ -242,7 +243,7 @@ client_set_hostname_maxlen(int i) const char * client_get_raw_addr() { - return inet_ntoa(raw_serv.sin_addr); + return format_addr(&raw_serv, raw_serv_len); } static void @@ -1488,8 +1489,10 @@ handshake_raw_udp(int dns_fd, int seed) int i; int r; int len; - unsigned remoteaddr = 0; - struct in_addr server; + int got_addr; + + memset(&raw_serv, 0, sizeof(raw_serv)); + got_addr = 0; fprintf(stderr, "Testing raw UDP data to the server (skip with -r)"); for (i=0; running && i<3 ;i++) { @@ -1499,15 +1502,23 @@ handshake_raw_udp(int dns_fd, int seed) len = handshake_waitdns(dns_fd, in, sizeof(in), 'i', 'I', i+1); if (len == 5 && in[0] == 'I') { - /* Received IP address */ - remoteaddr = (in[1] & 0xff); - remoteaddr <<= 8; - remoteaddr |= (in[2] & 0xff); - remoteaddr <<= 8; - remoteaddr |= (in[3] & 0xff); - remoteaddr <<= 8; - remoteaddr |= (in[4] & 0xff); - server.s_addr = ntohl(remoteaddr); + /* Received IPv4 address */ + struct sockaddr_in *raw4_serv = (struct sockaddr_in *) &raw_serv; + raw4_serv->sin_family = AF_INET; + memcpy(&raw4_serv->sin_addr, &in[1], sizeof(struct in_addr)); + raw4_serv->sin_port = htons(53); + raw_serv_len = sizeof(struct sockaddr_in); + got_addr = 1; + break; + } + if (len == 17 && in[0] == 'I') { + /* Received IPv6 address */ + struct sockaddr_in6 *raw6_serv = (struct sockaddr_in6 *) &raw_serv; + raw6_serv->sin6_family = AF_INET6; + memcpy(&raw6_serv->sin6_addr, &in[1], sizeof(struct in6_addr)); + raw6_serv->sin6_port = htons(53); + raw_serv_len = sizeof(struct sockaddr_in6); + got_addr = 1; break; } @@ -1518,19 +1529,13 @@ handshake_raw_udp(int dns_fd, int seed) if (!running) return 0; - if (!remoteaddr) { + if (!got_addr) { fprintf(stderr, "Failed to get raw server IP, will use DNS mode.\n"); return 0; } - fprintf(stderr, "Server is at %s, trying raw login: ", inet_ntoa(server)); + fprintf(stderr, "Server is at %s, trying raw login: ", format_addr(&raw_serv, raw_serv_len)); fflush(stderr); - /* Store address to iodined server */ - memset(&raw_serv, 0, sizeof(raw_serv)); - raw_serv.sin_family = AF_INET; - raw_serv.sin_port = htons(53); - raw_serv.sin_addr = server; - /* do login against port 53 on remote server * based on the old seed. If reply received, * switch to raw udp mode */ diff --git a/src/common.c b/src/common.c index a7f4aa7..2062239 100644 --- a/src/common.c +++ b/src/common.c @@ -173,7 +173,7 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora int open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) { - int flag = 1; + int flag; int fd; if ((fd = socket(sockaddr->ss_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) { @@ -187,9 +187,6 @@ open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &flag, sizeof(flag)); #ifndef WINDOWS32 - /* To get destination address from each UDP datagram, see iodined.c:read_dns() */ - setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag)); - fd_set_close_on_exec(fd); #endif diff --git a/src/common.h b/src/common.h index a5b3427..cb59f3f 100644 --- a/src/common.h +++ b/src/common.h @@ -53,14 +53,6 @@ extern const unsigned char raw_header[RAW_HDR_LEN]; #define QUERY_NAME_SIZE 256 -#if defined IP_RECVDSTADDR -# define DSTADDR_SOCKOPT IP_RECVDSTADDR -# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x)) -#elif defined IP_PKTINFO -# define DSTADDR_SOCKOPT IP_PKTINFO -# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr)) -#endif - #if defined IP_MTU_DISCOVER /* Linux */ # define IP_OPT_DONT_FRAG IP_MTU_DISCOVER @@ -95,12 +87,13 @@ struct query { unsigned short type; unsigned short rcode; unsigned short id; - struct in_addr destination; + struct sockaddr_storage destination; + socklen_t dest_len; struct sockaddr_storage from; socklen_t fromlen; unsigned short id2; - struct sockaddr from2; - int fromlen2; + struct sockaddr_storage from2; + socklen_t fromlen2; }; enum connection { diff --git a/src/iodined.c b/src/iodined.c index be51281..c78361c 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -72,6 +72,18 @@ WSADATA wsa_data; #define PASSWORD_ENV_VAR "IODINED_PASS" +#if defined IP_RECVDSTADDR +# define DSTADDR_SOCKOPT IP_RECVDSTADDR +# define dstaddr(x) ((struct in_addr *) CMSG_DATA(x)) +#elif defined IP_PKTINFO +# define DSTADDR_SOCKOPT IP_PKTINFO +# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr)) +#endif + +#ifndef IPV6_RECVPKTINFO +#define IPV6_RECVPKTINFO IPV6_PKTINFO +#endif + static int running = 1; static char *topdomain; static char password[33]; @@ -917,9 +929,8 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query return; } else if(in[0] == 'I' || in[0] == 'i') { /* Request for IP number */ - in_addr_t replyaddr; - unsigned addr; - char reply[5]; + char reply[17]; + int length; userid = b32_8to5(in[1]); if (check_authenticated_user_and_ip(userid, q) != 0) { @@ -927,21 +938,24 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query return; /* illegal id */ } - if (ns_ip != INADDR_ANY) { - /* If set, use assigned external ip (-n option) */ - replyaddr = ns_ip; + reply[0] = 'I'; + if (q->from.ss_family == AF_INET) { + if (ns_ip != INADDR_ANY) { + /* If set, use assigned external ip (-n option) */ + memcpy(&reply[1], &ns_ip, sizeof(ns_ip)); + } else { + /* otherwise return destination ip from packet */ + struct sockaddr_in *addr = (struct sockaddr_in *) &q->destination; + memcpy(&reply[1], &addr->sin_addr, sizeof(struct in_addr)); + } + length = 1 + sizeof(struct in_addr); } else { - /* otherwise return destination ip from packet */ - memcpy(&replyaddr, &q->destination.s_addr, sizeof(in_addr_t)); + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) &q->destination; + memcpy(&reply[1], &addr->sin6_addr, sizeof(struct in6_addr)); + length = 1 + sizeof(struct in6_addr); } - addr = htonl(replyaddr); - reply[0] = 'I'; - reply[1] = (addr >> 24) & 0xFF; - reply[2] = (addr >> 16) & 0xFF; - reply[3] = (addr >> 8) & 0xFF; - reply[4] = (addr >> 0) & 0xFF; - write_dns(dns_fd, q, reply, sizeof(reply), 'T'); + write_dns(dns_fd, q, reply, length, 'T'); } else if(in[0] == 'Z' || in[0] == 'z') { /* Check for case conservation and chars not allowed according to RFC */ @@ -1539,7 +1553,8 @@ handle_ns_request(int dns_fd, struct query *q) if (ns_ip != INADDR_ANY) { /* If ns_ip set, overwrite destination addr with it. * Destination addr will be sent as additional record (A, IN) */ - memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t)); + struct sockaddr_in *addr = (struct sockaddr_in *) &q->destination; + memcpy(&addr->sin_addr, &ns_ip, sizeof(ns_ip)); } len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain); @@ -1566,12 +1581,14 @@ handle_a_request(int dns_fd, struct query *q, int fakeip) if (fakeip) { in_addr_t ip = inet_addr("127.0.0.1"); - memcpy(&q->destination.s_addr, &ip, sizeof(in_addr_t)); + struct sockaddr_in *addr = (struct sockaddr_in *) &q->destination; + memcpy(&addr->sin_addr, &ip, sizeof(ip)); } else if (ns_ip != INADDR_ANY) { /* If ns_ip set, overwrite destination addr with it. * Destination addr will be sent as additional record (A, IN) */ - memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t)); + struct sockaddr_in *addr = (struct sockaddr_in *) &q->destination; + memcpy(&addr->sin_addr, &ns_ip, sizeof(ns_ip)); } len = dns_encode_a_response(buf, sizeof(buf), q); @@ -2038,7 +2055,7 @@ read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) char packet[64*1024]; int r; #ifndef WINDOWS32 - char address[96]; + char control[CMSG_SPACE(sizeof (struct in6_pktinfo))]; struct msghdr msg; struct iovec iov; struct cmsghdr *cmsg; @@ -2051,8 +2068,8 @@ read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) msg.msg_namelen = (unsigned) addrlen; msg.msg_iov = &iov; msg.msg_iovlen = 1; - msg.msg_control = address; - msg.msg_controllen = sizeof(address); + msg.msg_control = control; + msg.msg_controllen = sizeof(control); msg.msg_flags = 0; r = recvmsg(fd, &msg, 0); @@ -2074,13 +2091,29 @@ read_dns(int fd, struct dnsfd *dns_fds, int tun_fd, struct query *q) } #ifndef WINDOWS32 + memset(&q->destination, 0, sizeof(struct sockaddr_storage)); + /* Read destination IP address */ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == DSTADDR_SOCKOPT) { - q->destination = *dstaddr(cmsg); + struct sockaddr_in *addr = (struct sockaddr_in *) &q->destination; + addr->sin_family = AF_INET; + addr->sin_addr = *dstaddr(cmsg); + q->dest_len = sizeof(*addr); + break; + } + if (cmsg->cmsg_level == IPPROTO_IPV6 && + cmsg->cmsg_type == IPV6_PKTINFO) { + + struct in6_pktinfo *pktinfo; + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) &q->destination; + pktinfo = (struct in6_pktinfo *) CMSG_DATA(cmsg); + addr->sin6_family = AF_INET6; + memcpy(&addr->sin6_addr, &pktinfo->ipi6_addr, sizeof(struct in6_addr)); + q->dest_len = sizeof(*addr); break; } } @@ -2311,6 +2344,24 @@ version() { exit(0); } +static void +prepare_dns_fd(int fd) +{ +#ifndef WINDOWS32 + int flag = 1; + + /* To get destination address from each UDP datagram, see read_dns() */ + setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag)); +#ifdef IPV6_RECVPKTINFO + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, (const void*) &flag, sizeof(flag)); +#endif +#ifdef IPV6_PKTINFO + setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, (const void*) &flag, sizeof(flag)); +#endif + +#endif +} + int main(int argc, char **argv) { @@ -2629,6 +2680,13 @@ main(int argc, char **argv) #ifdef HAVE_SYSTEMD } #endif + + /* Setup dns file descriptors to get destination IP address */ + if (dns_fds.v4fd >= 0) + prepare_dns_fd(dns_fds.v4fd); + if (dns_fds.v6fd >= 0) + prepare_dns_fd(dns_fds.v6fd); + if (bind_enable) { if ((bind_fd = open_dns_from_host(NULL, 0, AF_INET, 0)) < 0) { retval = 1; From e7d253b1c100255c225f079a1bf11d3c1191cbea Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 28 Jun 2015 22:52:33 +0200 Subject: [PATCH 49/64] Fix compile on Darwin (hopefully) --- src/osflags | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/osflags b/src/osflags index 45c2e59..6af11aa 100755 --- a/src/osflags +++ b/src/osflags @@ -32,6 +32,9 @@ cflags) BeOS) echo '-Dsocklen_t=int'; ;; + Darwin) + echo '-D__APPLE_USE_RFC_3542'; + ;; Linux) FLAGS="-D_GNU_SOURCE" [ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -DHAVE_SETCON"; From 4d03ee7786a992c3b666eb58c06f28f71628ee60 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 30 Jun 2015 21:32:21 +0200 Subject: [PATCH 50/64] Allow choosing only IPv4 or IPv6 in server IPv6 might still allow IPv4 since V6_ONLY is not set by the server. --- README.md | 5 +++-- man/iodine.8 | 14 +++++++------- src/iodined.c | 22 ++++++++++++++++++---- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 61ab5ad..1c76829 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,9 @@ end of the tunnel. In this case, `ping 192.168.99.1` from the iodine client, and #### IPv6 The data inside the tunnel is IPv4 only. -The server listens to both IPv4 and IPv6 for incoming requests. Raw mode -will be attempted on the same protocol as used for the login. +The server listens to both IPv4 and IPv6 for incoming requests by default. +Use options `-4` or `-6` to only listen on one protocol. Raw mode will be +attempted on the same protocol as used for the login. The client can use IPv4 or IPv6 nameservers to connect to iodined. The relay nameservers will translate between protocols automatically if needed. Use diff --git a/man/iodine.8 b/man/iodine.8 index 3a8cea6..0eb9b9b 100644 --- a/man/iodine.8 +++ b/man/iodine.8 @@ -45,7 +45,7 @@ iodine, iodined \- tunnel IPv4 over DNS .B iodined [-h] -.B iodined [-c] [-s] [-f] [-D] [-u +.B iodined [-4] [-6] [-c] [-s] [-f] [-D] [-u .I user .B ] [-t .I chrootdir @@ -112,6 +112,12 @@ Print usage info and exit. .B -f Keep running in foreground. .TP +.B -4 +Force/allow only IPv4 DNS queries +.TP +.B -6 +Force/allow only IPv6 DNS queries +.TP .B -u user Drop privileges and run as user 'user' after setting up tunnel. .TP @@ -135,12 +141,6 @@ Apply SELinux 'context' after initialization. Create 'pidfile' and write process id in it. .SS Client Options: .TP -.B -4 -Force IPv4 DNS queries -.TP -.B -6 -Force IPv6 DNS queries -.TP .B -r Skip raw UDP mode. If not used, iodine will try getting the public IP address of the iodined host and test if it is reachable directly. If it is, traffic diff --git a/src/iodined.c b/src/iodined.c index c78361c..51b9c13 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2290,7 +2290,8 @@ static void print_usage() { extern char *__progname; - fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] " + fprintf(stderr, "Usage: %s [-v] [-h] " + "[-4] [-6] [-c] [-s] [-f] [-D] [-u user] " "[-t chrootdir] [-d device] [-m mtu] [-z context] " "[-l ipv4 listen address] [-L ipv6 listen address] " "[-p port] [-n external ip] [-b dnsport] " @@ -2310,6 +2311,8 @@ help() { print_usage(); fprintf(stderr, " -v to print version info and exit\n"); fprintf(stderr, " -h to print this help and exit\n"); + fprintf(stderr, " -4 to listen only on IPv4\n"); + fprintf(stderr, " -6 to listen only on IPv6\n"); fprintf(stderr, " -c to disable check of client IP/port on each request\n"); fprintf(stderr, " -s to skip creating and configuring the tun device, " "which then has to be created manually\n"); @@ -2378,6 +2381,7 @@ main(int argc, char **argv) char *context; char *device; char *pidfile; + int addrfamily; struct dnsfd dns_fds; int tun_fd; @@ -2420,6 +2424,7 @@ main(int argc, char **argv) port = 53; ns_ip = INADDR_ANY; ns_get_externalip = 0; + addrfamily = AF_UNSPEC; check_ip = 1; skipipconfig = 0; debug = 0; @@ -2449,8 +2454,14 @@ main(int argc, char **argv) srand(time(NULL)); fw_query_init(); - while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:L:p:n:b:P:z:F:i:")) != -1) { + while ((choice = getopt(argc, argv, "46vcsfhDu:t:d:m:l:L:p:n:b:P:z:F:i:")) != -1) { switch(choice) { + case '4': + addrfamily = AF_INET; + break; + case '6': + addrfamily = AF_INET6; + break; case 'v': version(); break; @@ -2669,11 +2680,14 @@ main(int argc, char **argv) dns_fds.v4fd = SD_LISTEN_FDS_START; } else { #endif - if ((dns_fds.v4fd = open_dns(&dns4addr, dns4addr_len)) < 0) { + if ((addrfamily == AF_UNSPEC || addrfamily == AF_INET) && + (dns_fds.v4fd = open_dns(&dns4addr, dns4addr_len)) < 0) { + retval = 1; goto cleanup; } - if ((dns_fds.v6fd = open_dns(&dns6addr, dns6addr_len)) < 0) { + if ((addrfamily == AF_UNSPEC || addrfamily == AF_INET6) && + (dns_fds.v6fd = open_dns(&dns6addr, dns6addr_len)) < 0) { retval = 1; goto cleanup; } From fc1611fc40382ced82487821507af0a5f5504ae8 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 30 Jun 2015 21:56:11 +0200 Subject: [PATCH 51/64] Only accept IPv6 in server IPv6 socket Set IPV6_V6ONLY flag on server socket. Not all operating systems support mixing v4/v6 in one socket, so separate them all the time. --- src/common.c | 10 ++++++++++ src/common.h | 1 + src/iodined.c | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 2062239..ce6c2aa 100644 --- a/src/common.c +++ b/src/common.c @@ -172,6 +172,12 @@ get_addr(char *host, int port, int addr_family, int flags, struct sockaddr_stora int open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) +{ + return open_dns_opt(sockaddr, sockaddr_len, -1); +} + +int +open_dns_opt(struct sockaddr_storage *sockaddr, size_t sockaddr_len, int v6only) { int flag; int fd; @@ -190,6 +196,10 @@ open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) fd_set_close_on_exec(fd); #endif + if (sockaddr->ss_family == AF_INET6 && v6only >= 0) { + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*) &v6only, sizeof(v6only)); + } + #ifdef IP_OPT_DONT_FRAG /* Set dont-fragment ip header flag */ flag = DONT_FRAG_VALUE; diff --git a/src/common.h b/src/common.h index cb59f3f..2de23e9 100644 --- a/src/common.h +++ b/src/common.h @@ -106,6 +106,7 @@ void check_superuser(void (*usage_fn)(void)); char *format_addr(struct sockaddr_storage *sockaddr, int sockaddr_len); int get_addr(char *, int, int, int, struct sockaddr_storage *); int open_dns(struct sockaddr_storage *, size_t); +int open_dns_opt(struct sockaddr_storage *sockaddr, size_t sockaddr_len, int v6only); int open_dns_from_host(char *host, int port, int addr_family, int flags); void close_dns(int); diff --git a/src/iodined.c b/src/iodined.c index 51b9c13..659c9a7 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2687,7 +2687,9 @@ main(int argc, char **argv) goto cleanup; } if ((addrfamily == AF_UNSPEC || addrfamily == AF_INET6) && - (dns_fds.v6fd = open_dns(&dns6addr, dns6addr_len)) < 0) { + /* Set IPv6 socket to V6ONLY */ + (dns_fds.v6fd = open_dns_opt(&dns6addr, dns6addr_len, 1)) < 0) { + retval = 1; goto cleanup; } From 7d915500b73ca74eafb88f359421be2d1258870f Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 30 Jun 2015 23:35:19 +0200 Subject: [PATCH 52/64] Drop old mingw --- Makefile | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Makefile b/Makefile index a75eaa8..a63a603 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ iodine-latest: @date >> iodine-latest/VERSION.txt @echo "Git version: " >> iodine-latest/VERSION.txt @git rev-parse HEAD >> iodine-latest/VERSION.txt - @for i in README CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done + @for i in README.md CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done @unix2dos iodine-latest/* cross-android: @@ -90,15 +90,3 @@ iodine-latest-windows.zip: iodine-latest @cp README-win32.txt iodine-latest-windows @zip -r iodine-latest-windows.zip iodine-latest-windows -cross-mingw: - @(cd src; $(MAKE) TARGETOS=windows32 CC=i686-mingw32-gcc all) - -iodine-latest-win32.zip: cross-mingw iodine-latest - @mv iodine-latest iodine-latest-win32 - @mkdir -p iodine-latest-win32/bin - @i686-mingw32-strip bin/iodine* - @for i in `ls bin`; do cp bin/$$i iodine-latest-win32/bin/$$i.exe; done - @cp /usr/i686-mingw32/usr/bin/zlib1.dll iodine-latest-win32/bin - @cp README-win32.txt iodine-latest-win32 - @zip -r iodine-latest-win32.zip iodine-latest-win32 - From f61ed01a3cb8d216da5cfe54c496acfe0732e743 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 19 Jul 2015 09:48:03 +0200 Subject: [PATCH 53/64] Remove unused method users_waiting_on_reply() --- src/user.c | 18 ------------------ src/user.h | 1 - tests/user.c | 24 ------------------------ 3 files changed, 43 deletions(-) diff --git a/src/user.c b/src/user.c index 6391573..ce1fa5a 100644 --- a/src/user.c +++ b/src/user.c @@ -92,24 +92,6 @@ users_get_first_ip() return strdup(inet_ntoa(ip)); } -int -users_waiting_on_reply() -{ - int ret; - int i; - - ret = 0; - for (i = 0; i < usercount; i++) { - if (users[i].active && !users[i].disabled && - users[i].last_pkt + 60 > time(NULL) && - users[i].q.id != 0 && users[i].conn == CONN_DNS_NULL) { - ret++; - } - } - - return ret; -} - int find_user_by_ip(uint32_t ip) { diff --git a/src/user.h b/src/user.h index 9f624b3..7d2553a 100644 --- a/src/user.h +++ b/src/user.h @@ -81,7 +81,6 @@ extern struct tun_user *users; int init_users(in_addr_t, int); const char* users_get_first_ip(); -int users_waiting_on_reply(); int find_user_by_ip(uint32_t); int all_users_waiting_to_send(); int find_available_user(); diff --git a/tests/user.c b/tests/user.c index 7d8804e..0bd60c0 100644 --- a/tests/user.c +++ b/tests/user.c @@ -48,30 +48,6 @@ START_TEST(test_init_users) } END_TEST -START_TEST(test_users_waiting) -{ - in_addr_t ip; - - ip = inet_addr("127.0.0.1"); - init_users(ip, 27); - - fail_unless(users_waiting_on_reply() == 0); - - users[3].active = 1; - - fail_unless(users_waiting_on_reply() == 0); - - users[3].last_pkt = time(NULL); - - fail_unless(users_waiting_on_reply() == 0); - - users[3].conn = CONN_DNS_NULL; - users[3].q.id = 1; - - fail_unless(users_waiting_on_reply() == 1); -} -END_TEST - START_TEST(test_find_user_by_ip) { in_addr_t ip; From d8bf5cc85b7fe36f5e3ac766fd67ed6bcc6e94e4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 19 Jul 2015 10:03:27 +0200 Subject: [PATCH 54/64] Fix test build after removed test --- tests/user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/user.c b/tests/user.c index 0bd60c0..bdc189e 100644 --- a/tests/user.c +++ b/tests/user.c @@ -176,7 +176,6 @@ test_user_create_tests() tc = tcase_create("User"); tcase_add_test(tc, test_init_users); - tcase_add_test(tc, test_users_waiting); tcase_add_test(tc, test_find_user_by_ip); tcase_add_test(tc, test_all_users_waiting_to_send); tcase_add_test(tc, test_find_available_user); From c269a003449d9d1fce873df64e29983b0eaf68a4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 5 Aug 2015 19:33:50 +0200 Subject: [PATCH 55/64] Add support for Android L Build position-indepent executables, required for Android L (5.0+) They also work with kitkat. Add new maketarget "cross-android-old" that builds without PIE for older versions. Include both new and old versions in latest-android.zip. Add arm64. Hopefully solves github PR #14. --- Makefile | 21 +++++++++++++++++++-- README-android.txt | 14 +++++++++----- src/Android.mk | 9 +++++++++ src/android_dns.h | 5 +++++ src/client.c | 2 +- src/dns.c | 6 +++--- 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index a63a603..6f869b3 100644 --- a/Makefile +++ b/Makefile @@ -56,15 +56,32 @@ iodine-latest: @for i in README.md CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done @unix2dos iodine-latest/* +#non-PIE build for old android +cross-android-old: + @(cd src; $(MAKE) base64u.c base64u.h) + @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=old) + +#Position-indepedent build for modern android cross-android: @(cd src; $(MAKE) base64u.c base64u.h) - @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk) + @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=kitkat) iodine-latest-android.zip: iodine-latest @mv iodine-latest iodine-latest-android - @mkdir -p iodine-latest-android/armeabi iodine-latest-android/x86 + @mkdir -p iodine-latest-android/pre-kitkat/armeabi + @mkdir -p iodine-latest-android/pre-kitkat/x86 + @$(MAKE) cross-android-old TARGET_ARCH_ABI=armeabi + @cp src/libs/armeabi/* iodine-latest-android/pre-kitkat/armeabi + @$(MAKE) cross-android-old TARGET_ARCH_ABI=x86 + @cp src/libs/x86/* iodine-latest-android/pre-kitkat/x86 + @rm -rf src/libs src/obj + @mkdir -p iodine-latest-android/armeabi + @mkdir -p iodine-latest-android/arm64-v8a + @mkdir -p iodine-latest-android/x86 @$(MAKE) cross-android TARGET_ARCH_ABI=armeabi @cp src/libs/armeabi/* iodine-latest-android/armeabi + @$(MAKE) cross-android TARGET_ARCH_ABI=arm64-v8a + @cp src/libs/arm64-v8a/* iodine-latest-android/arm64-v8a @$(MAKE) cross-android TARGET_ARCH_ABI=x86 @cp src/libs/x86/* iodine-latest-android/x86 @cp README-android.txt iodine-latest-android diff --git a/README-android.txt b/README-android.txt index f08c6cf..b7e73bb 100644 --- a/README-android.txt +++ b/README-android.txt @@ -13,7 +13,7 @@ Extra README file for Android 2. Find/build a compatible tun.ko for your specific Android kernel 3. Copy tun.ko and the iodine binary to your device: - (Almost all devices need the armeabi binary. Only Intel powered + (Almost all devices need the armeabi binary. Only Intel powered ones need the x86 build.) adb push tun.ko /data/local/tmp @@ -35,11 +35,15 @@ For more information: http://blog.bokhorst.biz/5123 2. Download and unpack the iodine sources 3. Build: - cd src - make base64u.h base64u.c - ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk + cd src + make base64u.h base64u.c + ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=kitkat or run "make cross-android" in the iodine root directory. - To build for other archs, specify TARGET_ARCH_ABI: + To build for other archs, specify TARGET_ARCH_ABI: "make cross-android TARGET_ARCH_ABI=x86" + For older android versions (pre-kitkat), build with "make cross-android" in the + root directory, or manually like above but without the MY_PLATFORM part. + + The iodine binary ends up in src/libs//iodine diff --git a/src/Android.mk b/src/Android.mk index 81136e5..3767ab6 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -20,5 +20,14 @@ LOCAL_SRC_FILES := tun.c dns.c read.c encoding.c login.c base32.c base64.c base6 LOCAL_CFLAGS := -c -DANDROID -DLINUX -DIFCONFIGPATH=\"/system/bin/\" -Wall -DGITREVISION=\"$(HEAD_COMMIT)\" LOCAL_LDLIBS := -lz +#Choose platform level (for PIE support) +ifeq (kitkat, $(strip $(MY_PLATFORM))) +APP_PLATFORM := android-16 +LOCAL_CFLAGS += -fPIE +LOCAL_LDFLAGS += -fPIE -pie +else +APP_PLATFORM := android-3 +endif + include $(BUILD_EXECUTABLE) diff --git a/src/android_dns.h b/src/android_dns.h index 0085af6..5a86e71 100644 --- a/src/android_dns.h +++ b/src/android_dns.h @@ -17,6 +17,9 @@ #ifndef __FIX_ANDROID_H__ #define __FIX_ANDROID_H__ +/* Newer android platforms can have this data already */ +#ifndef C_IN + typedef struct { unsigned id :16; unsigned rd :1; @@ -51,4 +54,6 @@ typedef struct { #define T_TXT 16 #define T_SRV 33 +#endif /* !C_IN */ + #endif diff --git a/src/client.c b/src/client.c index 759f652..38b573b 100644 --- a/src/client.c +++ b/src/client.c @@ -32,10 +32,10 @@ #ifdef WINDOWS32 #include "windows.h" #else +#include #ifdef ANDROID #include "android_dns.h" #endif -#include #ifdef DARWIN #define BIND_8_COMPAT #include diff --git a/src/dns.c b/src/dns.c index 5f187e4..6eecab2 100644 --- a/src/dns.c +++ b/src/dns.c @@ -27,9 +27,6 @@ #ifdef WINDOWS32 #include "windows.h" #else -#ifdef ANDROID -#include "android_dns.h" -#endif #include #ifdef DARWIN #define BIND_8_COMPAT @@ -38,6 +35,9 @@ #include #include #include +#ifdef ANDROID +#include "android_dns.h" +#endif #endif From e5843a91432bdb7ee0eb3b511f931331db61cd05 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 5 Aug 2015 19:54:09 +0200 Subject: [PATCH 56/64] Use english locale for date in latest-file --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6f869b3..6dd964a 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ iodine-latest: @rm -rf iodine-latest* @mkdir -p iodine-latest @echo "Create date: " > iodine-latest/VERSION.txt - @date >> iodine-latest/VERSION.txt + @LANG=en_US date >> iodine-latest/VERSION.txt @echo "Git version: " >> iodine-latest/VERSION.txt @git rev-parse HEAD >> iodine-latest/VERSION.txt @for i in README.md CHANGELOG TODO; do cp $$i iodine-latest/$$i.txt; done From a8a5fbbf0d4f846b1afe2529d881fa5b3bc5dc12 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 5 Aug 2015 20:04:03 +0200 Subject: [PATCH 57/64] Second attempt at PIE binary for new android Github PR #14 --- CHANGELOG | 1 + Makefile | 4 ++-- README-android.txt | 4 ++-- src/Android.mk | 9 --------- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 894ceaa..731df84 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ master: - Add support for IPv6 in the server. Raw mode will be with same protocol as used for login. Traffic inside tunnel is still IPv4. + - Update android build to support 5.0 (Lollipop) and newer. 2014-06-16: 0.7.0 "Kryoptonite" - Partial IPv6 support (#107) diff --git a/Makefile b/Makefile index 6dd964a..4be98d1 100644 --- a/Makefile +++ b/Makefile @@ -59,12 +59,12 @@ iodine-latest: #non-PIE build for old android cross-android-old: @(cd src; $(MAKE) base64u.c base64u.h) - @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=old) + @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_PLATFORM=android-3) #Position-indepedent build for modern android cross-android: @(cd src; $(MAKE) base64u.c base64u.h) - @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=kitkat) + @(cd src; ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_PLATFORM=android-16) iodine-latest-android.zip: iodine-latest @mv iodine-latest iodine-latest-android diff --git a/README-android.txt b/README-android.txt index b7e73bb..8d4a15d 100644 --- a/README-android.txt +++ b/README-android.txt @@ -37,13 +37,13 @@ For more information: http://blog.bokhorst.biz/5123 3. Build: cd src make base64u.h base64u.c - ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk MY_PLATFORM=kitkat + ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_PLATFORM=android-16 or run "make cross-android" in the iodine root directory. To build for other archs, specify TARGET_ARCH_ABI: "make cross-android TARGET_ARCH_ABI=x86" For older android versions (pre-kitkat), build with "make cross-android" in the - root directory, or manually like above but without the MY_PLATFORM part. + root directory, or manually like above but with APP_PLATFORM=android-3 The iodine binary ends up in src/libs//iodine diff --git a/src/Android.mk b/src/Android.mk index 3767ab6..81136e5 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -20,14 +20,5 @@ LOCAL_SRC_FILES := tun.c dns.c read.c encoding.c login.c base32.c base64.c base6 LOCAL_CFLAGS := -c -DANDROID -DLINUX -DIFCONFIGPATH=\"/system/bin/\" -Wall -DGITREVISION=\"$(HEAD_COMMIT)\" LOCAL_LDLIBS := -lz -#Choose platform level (for PIE support) -ifeq (kitkat, $(strip $(MY_PLATFORM))) -APP_PLATFORM := android-16 -LOCAL_CFLAGS += -fPIE -LOCAL_LDFLAGS += -fPIE -pie -else -APP_PLATFORM := android-3 -endif - include $(BUILD_EXECUTABLE) From 9c8a941729ae66b73267b4b1590726b4ad2dfa25 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Fri, 7 Aug 2015 09:54:49 +0200 Subject: [PATCH 58/64] Fix make command for old android --- README-android.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-android.txt b/README-android.txt index 8d4a15d..a096457 100644 --- a/README-android.txt +++ b/README-android.txt @@ -43,7 +43,7 @@ For more information: http://blog.bokhorst.biz/5123 To build for other archs, specify TARGET_ARCH_ABI: "make cross-android TARGET_ARCH_ABI=x86" - For older android versions (pre-kitkat), build with "make cross-android" in the + For older android versions (pre-kitkat), build with "make cross-android-old" in the root directory, or manually like above but with APP_PLATFORM=android-3 The iodine binary ends up in src/libs//iodine From 482d005d11b69b13693228b7d84530bc8f65109f Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Tue, 29 Sep 2015 10:02:19 +0200 Subject: [PATCH 59/64] Add notice about NDIS6 tap driver --- README-win32.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README-win32.txt b/README-win32.txt index de9124b..56e52e6 100644 --- a/README-win32.txt +++ b/README-win32.txt @@ -11,10 +11,11 @@ Extra README file for Win32 related stuff 0. After iodine 0.6, you need Windows XP or newer to run. -1. Install the TAP32 driver +1. Install the TAP driver http://openvpn.net/index.php/open-source/downloads.html - Choose OpenVPN 2.0.9 Windows Installer, when installing you can - select to install only the TAP driver. + Download the OpenVPN TAP driver (under section Tap-windows) + Problems has been reported with the NDIS6 version (9.2x.y), use the + NDIS5 version for now if possible. 2. Have at least one TAP32 interface installed. There are scripts for adding and removing in the OpenVPN bin directory. If you have more than one From 7b1df75e3aad8a9a01cbbf2f2ff377cbc5a1ea4b Mon Sep 17 00:00:00 2001 From: Pascal Ernster Date: Sat, 30 Apr 2016 18:27:15 +0200 Subject: [PATCH 60/64] Fix compilation with systemd>=230 and for older systemd versions without compat-libs --- src/osflags | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osflags b/src/osflags index 6af11aa..eb01101 100755 --- a/src/osflags +++ b/src/osflags @@ -20,6 +20,7 @@ link) FLAGS=""; [ -e /usr/include/selinux/selinux.h ] && FLAGS="$FLAGS -lselinux"; [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS $(pkg-config --libs libsystemd-daemon)"; + [ -e /usr/include/systemd/sd-daemon.h ] && FLAGS="$FLAGS $(pkg-config --libs libsystemd)"; echo $FLAGS; ;; esac From 4987aa536db069c9f687c2c85b325fc49756a0f2 Mon Sep 17 00:00:00 2001 From: Aleksei Fedotov Date: Mon, 9 May 2016 23:04:21 +0300 Subject: [PATCH 61/64] Add support for socket activation by ipv6 socket iodined may accept ipv4 and ipv6 sockets via systemd socket activation, we need to figure out type of sockets. --- src/iodined.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index 659c9a7..2e6f7bf 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -2671,14 +2671,11 @@ main(int argc, char **argv) #ifdef HAVE_SYSTEMD nb_fds = sd_listen_fds(0); - if (nb_fds > 1) { + if (nb_fds < 0) { + warnx("Failed to receive file descriptors from systemd: %s", strerror(-nb_fds)); retval = 1; - warnx("Too many file descriptors received!\n"); goto cleanup; - } else if (nb_fds == 1) { - /* XXX: assume we get IPv4 socket */ - dns_fds.v4fd = SD_LISTEN_FDS_START; - } else { + } else if (nb_fds == 0) { #endif if ((addrfamily == AF_UNSPEC || addrfamily == AF_INET) && (dns_fds.v4fd = open_dns(&dns4addr, dns4addr_len)) < 0) { @@ -2694,6 +2691,25 @@ main(int argc, char **argv) goto cleanup; } #ifdef HAVE_SYSTEMD + } else if (nb_fds <= 2) { + /* systemd may pass up to two sockets, for ip4 and ip6, try to figure out + which is which */ + for (int i = 0; i < nb_fds; i++) { + int fd = SD_LISTEN_FDS_START + i; + if (sd_is_socket(fd, AF_INET, SOCK_DGRAM, -1)) { + dns_fds.v4fd = fd; + } else if (sd_is_socket(fd, AF_INET6, SOCK_DGRAM, -1)) { + dns_fds.v6fd = fd; + } else { + retval = 1; + warnx("Unknown socket %d passed to iodined!\n", fd); + goto cleanup; + } + } + } else { + retval = 1; + warnx("Too many file descriptors received!\n"); + goto cleanup; } #endif From 2edb879845b900a04b05ec555bdbde19f81c4a92 Mon Sep 17 00:00:00 2001 From: Aleksei Fedotov Date: Wed, 11 May 2016 00:15:33 +0300 Subject: [PATCH 62/64] Listen on two different sockets for ipv6 and ipv4 Option BindIPv6Only is needed to restrict ipv6 to sending IPv6 packets only, without it IPv6 socket can be used to send and receive packet to and from an IPv6 address or an IPv4-mapped IPv6 address. --- doc/iodine-server.socket | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/iodine-server.socket b/doc/iodine-server.socket index d6c57b8..485181f 100644 --- a/doc/iodine-server.socket +++ b/doc/iodine-server.socket @@ -3,6 +3,8 @@ Description=Iodine socket [Socket] ListenDatagram=53 +ListenDatagram=0.0.0.0:53 +BindIPv6Only=ipv6-only [Install] WantedBy=sockets.target From 1ad7c05b928b9fb581bc8a50d804241a498daa92 Mon Sep 17 00:00:00 2001 From: Will Szumski Date: Wed, 23 Nov 2016 01:00:11 +0000 Subject: [PATCH 63/64] Do not validate the autodetected IPs of additional address families when using -4 (IPV4 only) and -6 (IPv6 only) flags --- src/iodined.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/iodined.c b/src/iodined.c index 2e6f7bf..c213ec6 100644 --- a/src/iodined.c +++ b/src/iodined.c @@ -1844,10 +1844,10 @@ tunnel(int tun_fd, struct dnsfd *dns_fds, int bind_fd, int max_idle_time) if (FD_ISSET(tun_fd, &fds)) { tunnel_tun(tun_fd, dns_fds); } - if (FD_ISSET(dns_fds->v4fd, &fds)) { + if (dns_fds->v4fd >= 0 && FD_ISSET(dns_fds->v4fd, &fds)) { tunnel_dns(tun_fd, dns_fds->v4fd, dns_fds, bind_fd); } - if (FD_ISSET(dns_fds->v6fd, &fds)) { + if (dns_fds->v6fd >= 0 && FD_ISSET(dns_fds->v6fd, &fds)) { tunnel_dns(tun_fd, dns_fds->v6fd, dns_fds, bind_fd); } if (FD_ISSET(bind_fd, &fds)) { @@ -2592,16 +2592,19 @@ main(int argc, char **argv) fprintf(stderr, "Add more -D switches to set higher debug level.\n"); foreground = 1; } - - dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dns4addr); - if (dns4addr_len < 0) { - warnx("Bad IPv4 address to listen on."); - usage(); + if (addrfamily == AF_UNSPEC || addrfamily == AF_INET) { + dns4addr_len = get_addr(listen_ip4, port, AF_INET, AI_PASSIVE | AI_NUMERICHOST, &dns4addr); + if (dns4addr_len < 0) { + warnx("Bad IPv4 address to listen on."); + usage(); + } } - dns6addr_len = get_addr(listen_ip6, port, AF_INET6, AI_PASSIVE | AI_NUMERICHOST, &dns6addr); - if (dns6addr_len < 0) { - warnx("Bad IPv6 address to listen on."); - usage(); + if (addrfamily == AF_UNSPEC || addrfamily == AF_INET6) { + dns6addr_len = get_addr(listen_ip6, port, AF_INET6, AI_PASSIVE | AI_NUMERICHOST, &dns6addr); + if (dns6addr_len < 0) { + warnx("Bad IPv6 address to listen on."); + usage(); + } } if(bind_enable) { From 68443abd6099c9f7e9be82490cb4b4829172faf8 Mon Sep 17 00:00:00 2001 From: Jes Bodi Klinke Date: Tue, 29 Nov 2016 11:10:38 -0800 Subject: [PATCH 64/64] Fixed non-standard passing of va_list into functions declared with ... --- src/common.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/common.c b/src/common.c index ce6c2aa..f8719df 100644 --- a/src/common.c +++ b/src/common.c @@ -405,12 +405,9 @@ inet_aton(const char *cp, struct in_addr *inp) #endif void -warn(const char *fmt, ...) +vwarn(const char *fmt, va_list list) { - va_list list; - - va_start(list, fmt); - if (fmt) fprintf(stderr, fmt, list); + if (fmt) vfprintf(stderr, fmt, list); #ifndef ANDROID if (errno == 0) { fprintf(stderr, ": WSA error %d\n", WSAGetLastError()); @@ -418,17 +415,32 @@ warn(const char *fmt, ...) fprintf(stderr, ": %s\n", strerror(errno)); } #endif +} + +void +warn(const char *fmt, ...) +{ + va_list list; + + va_start(list, fmt); + vwarn(fmt, list); va_end(list); } +void +vwarnx(const char *fmt, va_list list) +{ + if (fmt) vfprintf(stderr, fmt, list); + fprintf(stderr, "\n"); +} + void warnx(const char *fmt, ...) { va_list list; va_start(list, fmt); - if (fmt) fprintf(stderr, fmt, list); - fprintf(stderr, "\n"); + vwarnx(fmt, list); va_end(list); } @@ -438,7 +450,7 @@ err(int eval, const char *fmt, ...) va_list list; va_start(list, fmt); - warn(fmt, list); + vwarn(fmt, list); va_end(list); exit(eval); } @@ -449,7 +461,7 @@ errx(int eval, const char *fmt, ...) va_list list; va_start(list, fmt); - warnx(fmt, list); + vwarnx(fmt, list); va_end(list); exit(eval); }