From 8a6f278fd2606c0a8f133f05df83b2649eacf6c3 Mon Sep 17 00:00:00 2001 From: Vilbrekin Date: Wed, 22 Aug 2012 10:46:24 +0200 Subject: [PATCH 01/11] Basic patch for android cross-compilation. Commented non-existing functions in android NDK. Prefix scripts execution with shell binary to allow execution on no-exec mount points. Everyything is currently hard coded, while it should use pre-compiler variables... --- src/process.c | 10 ++++++++++ src/tincd.c | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/process.c b/src/process.c index f33355ce..41a1468d 100644 --- a/src/process.c +++ b/src/process.c @@ -376,6 +376,16 @@ bool execute_script(const char *name, char **envp) { free(scriptname); return true; } + else + { + // Ugly hard-code allowing execution of scripts on android without execution flag (such as on /sdcard) + free(scriptname); + len = xasprintf(&scriptname, "/system/bin/sh \"%s/%s\"", confbase, name); + if(len < 0) + { + return false; + } + } #endif ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); diff --git a/src/tincd.c b/src/tincd.c index 4f03db6f..7b74cd6c 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -467,8 +467,9 @@ static bool drop_privs() { "initgroups", strerror(errno)); return false; } - endgrent(); - endpwent(); + // Not supported in android NDK + //endgrent(); + //endpwent(); } if (do_chroot) { tzset(); /* for proper timestamps in logs */ From f2570c1b7f5813e087c867cf002f36f0c09b5cfa Mon Sep 17 00:00:00 2001 From: Vilbrekin Date: Sat, 25 Aug 2012 19:14:00 +0200 Subject: [PATCH 02/11] Replace hard-code with new ScriptsInterpreter configuration property. This new setting allows choosing a custom script interpreter used for the various tinc callbacks. If none is specified, the script itself is called as executable (as before). This is particularly useful when storing tinc configuration and script on a mount point with no-exec attribute. --- src/process.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/process.c b/src/process.c index 41a1468d..a6822268 100644 --- a/src/process.c +++ b/src/process.c @@ -358,6 +358,7 @@ bool execute_script(const char *name, char **envp) { int status, len; char *scriptname; int i; + char *aInterpreter = NULL; #ifndef HAVE_MINGW len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); @@ -376,17 +377,21 @@ bool execute_script(const char *name, char **envp) { free(scriptname); return true; } - else +#endif + + // Custom scripts interpreter + if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &aInterpreter)) { - // Ugly hard-code allowing execution of scripts on android without execution flag (such as on /sdcard) + // Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard) free(scriptname); - len = xasprintf(&scriptname, "/system/bin/sh \"%s/%s\"", confbase, name); + len = xasprintf(&scriptname, "%s \"%s/%s\"", aInterpreter, confbase, name); if(len < 0) { + free(aInterpreter); return false; } } -#endif + free(aInterpreter); ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); From c6720f1a608d19c722d8601fab1048773dbad59b Mon Sep 17 00:00:00 2001 From: Vilbrekin Date: Sat, 25 Aug 2012 19:59:26 +0200 Subject: [PATCH 03/11] Add basic .gitignore file, cleaning (most) files generated by autotools. --- .gitignore | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f45f7a68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +Makefile +Makefile.* +*.o +*.a +/config.* +/src/tincd +/autom4te.cache +/aclocal.m4 +/compile +/configure +/depcomp +/install-sh +/missing +INSTALL +.deps +stamp-h1 +/src/device.c From afe4bf62eccab76c75e5a661fb2c16f1391a8417 Mon Sep 17 00:00:00 2001 From: Vilbrekin Date: Sat, 25 Aug 2012 20:01:11 +0200 Subject: [PATCH 04/11] Use __ANDROID__ define rather than dirty hard-code to allow android NDK cross-compilation. --- src/tincd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tincd.c b/src/tincd.c index 7b74cd6c..566031a3 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -467,9 +467,11 @@ static bool drop_privs() { "initgroups", strerror(errno)); return false; } - // Not supported in android NDK - //endgrent(); - //endpwent(); +#ifndef __ANDROID__ +// Not supported in android NDK + endgrent(); + endpwent(); +#endif } if (do_chroot) { tzset(); /* for proper timestamps in logs */ From f421a640777bd9484c59fa6feacadcf3e05d4b44 Mon Sep 17 00:00:00 2001 From: Vilbrekin Date: Sat, 25 Aug 2012 20:32:38 +0200 Subject: [PATCH 05/11] Android cross-compilation instructions. --- README.android | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 README.android diff --git a/README.android b/README.android new file mode 100644 index 00000000..6fffe418 --- /dev/null +++ b/README.android @@ -0,0 +1,20 @@ +Quick how-o cross compile tinc for android (done from $HOME/android/): + +- Download android NDK and setup local ARM toolchain: +wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 +tar xfj android-ndk-r8b-linux-x86.tar.bz2 +./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain + +- Download and cross-compile openSSL for ARM: +wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz +tar xfz openssl-1.0.1c.tar.gz +cd openssl-1.0.1c +./Configure dist +make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib + +- Clone and cross-compile tinc: +git clone git://tinc-vpn.org/tinc +cd tinc +autoreconf -fsi +CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ +make -j5 From 66e702d90d83977dc089736d7e4146330bc5df28 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 24 Sep 2012 14:02:07 +0200 Subject: [PATCH 06/11] Attribution for Vil Brekin and some code style cleanups. --- THANKS | 1 + src/process.c | 24 ++++++++++-------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/THANKS b/THANKS index 9c02e933..8da657c8 100644 --- a/THANKS +++ b/THANKS @@ -44,6 +44,7 @@ We would like to thank the following people for their contributions to tinc: * Teemu Kiviniemi * Timothy Redaelli * Tonnerre Lombard +* Vil Brekin * Wessel Dankers * Wouter van Heyst diff --git a/src/process.c b/src/process.c index a6822268..262b092c 100644 --- a/src/process.c +++ b/src/process.c @@ -358,7 +358,7 @@ bool execute_script(const char *name, char **envp) { int status, len; char *scriptname; int i; - char *aInterpreter = NULL; + char *interpreter = NULL; #ifndef HAVE_MINGW len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name); @@ -379,19 +379,15 @@ bool execute_script(const char *name, char **envp) { } #endif - // Custom scripts interpreter - if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &aInterpreter)) - { - // Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard) - free(scriptname); - len = xasprintf(&scriptname, "%s \"%s/%s\"", aInterpreter, confbase, name); - if(len < 0) - { - free(aInterpreter); - return false; - } - } - free(aInterpreter); + // Custom scripts interpreter + if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &interpreter)) { + // Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard) + free(scriptname); + len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name); + free(interpreter); + if(len < 0) + return false; + } ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name); From 72f08932cf6f1ac0cfb837d377b423207e8c671a Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 24 Sep 2012 14:56:00 +0200 Subject: [PATCH 07/11] Don't ignore Makefile.am. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f45f7a68..ac663e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ Makefile -Makefile.* +Makefile.in *.o *.a /config.* From fac5593f44e47f3bd4f4b425ada38ab49fbe3b42 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 27 Sep 2012 17:19:02 +0200 Subject: [PATCH 08/11] Fix links in documenation. --- doc/tinc.conf.5.in | 2 +- doc/tinc.texi | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index fec70e61..935321ab 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -766,7 +766,7 @@ its connection to the virtual network device. .Sh SEE ALSO .Xr tincd 8 , .Pa http://www.tinc-vpn.org/ , -.Pa http://www.linuxdoc.org/LDP/nag2/ . +.Pa http://www.tldp.org/LDP/nag2/ . .Pp The full documentation for diff --git a/doc/tinc.texi b/doc/tinc.texi index cd972dec..57bff665 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -186,7 +186,7 @@ packets. @cindex release For an up to date list of supported platforms, please check the list on our website: -@uref{http://www.tinc-vpn.org/platforms}. +@uref{http://www.tinc-vpn.org/platforms/}. @c @c @@ -470,7 +470,7 @@ system startup scripts and sample configurations. If you cannot use one of the precompiled packages, or you want to compile tinc for yourself, you can use the source. The source is distributed under the GNU General Public License (GPL). Download the source from the -@uref{http://www.tinc-vpn.org/download, download page}, which has +@uref{http://www.tinc-vpn.org/download/, download page}, which has the checksums of these files listed; you may wish to check these with md5sum before continuing. @@ -511,7 +511,7 @@ The documentation that comes along with your distribution will tell you how to d In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools from @uref{http://developer.apple.com/tools/macosxtools.html} and -a recent version of Fink from @uref{http://fink.sourceforge.net/}. +a recent version of Fink from @uref{http://www.finkproject.org/}. After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo. @@ -639,7 +639,7 @@ you will not find the answers in this documentation. Make sure you have an adequate understanding of networks in general. @cindex Network Administrators Guide A good resource on networking is the -@uref{http://www.linuxdoc.org/LDP/nag2/, Linux Network Administrators Guide}. +@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. If you have everything clearly pictured in your mind, proceed in the following order: @@ -1221,7 +1221,7 @@ MAC addresses are notated like 0:1a:2b:3c:4d:5e. Prefixlength is the number of bits set to 1 in the netmask part; for example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes /22. This conforms to standard CIDR notation as described in -@uref{ftp://ftp.isi.edu/in-notes/rfc1519.txt, RFC1519} +@uref{http://www.ietf.org/rfc/rfc1519.txt, RFC1519} @cindex Subnet weight A Subnet can be given a weight to indicate its priority over identical Subnets From 5a161e86cf35351f5274d7a8e17fef4630b40686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Schu=CC=88rrer?= Date: Sun, 30 Sep 2012 02:04:55 +0200 Subject: [PATCH 09/11] Output details of encryption errors --- src/protocol_auth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 4c721a44..d5b702d9 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -244,8 +244,8 @@ bool send_metakey(connection_t *c) { */ if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) { - logger(LOG_ERR, "Error during encryption of meta key for %s (%s)", - c->name, c->hostname); + logger(LOG_ERR, "Error during encryption of meta key for %s (%s) %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -313,8 +313,8 @@ bool metakey_h(connection_t *c) { /* Decrypt the meta key */ if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ - logger(LOG_ERR, "Error during decryption of meta key for %s (%s)", - c->name, c->hostname); + logger(LOG_ERR, "Error during decryption of meta key for %s (%s) %s", + c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } From 3bd810ea79d6933839ddac4a2cf1445c51947d38 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 30 Sep 2012 13:45:39 +0200 Subject: [PATCH 10/11] =?UTF-8?q?Attribution=20for=20Martin=20Sch=C3=BCrre?= =?UTF-8?q?r.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- THANKS | 1 + src/protocol_auth.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/THANKS b/THANKS index 8da657c8..42b1c0aa 100644 --- a/THANKS +++ b/THANKS @@ -27,6 +27,7 @@ We would like to thank the following people for their contributions to tinc: * Mark Glines * Markus Goetz * Martin Kihlgren +* Martin Schürrer * Matias Carrasco * Max Rijevski * Menno Smits diff --git a/src/protocol_auth.c b/src/protocol_auth.c index d5b702d9..0ef54682 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -244,7 +244,7 @@ bool send_metakey(connection_t *c) { */ if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) { - logger(LOG_ERR, "Error during encryption of meta key for %s (%s) %s", + logger(LOG_ERR, "Error during encryption of meta key for %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } @@ -313,7 +313,7 @@ bool metakey_h(connection_t *c) { /* Decrypt the meta key */ if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ - logger(LOG_ERR, "Error during decryption of meta key for %s (%s) %s", + logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } From c4940a5c888d85b4c477b6face5e9a618e64718d Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 30 Sep 2012 13:45:47 +0200 Subject: [PATCH 11/11] Add strict checks to hex to binary conversions. The main goal is to catch misuse of the obsolete PrivateKey and PublicKey statements. --- lib/utils.c | 10 ++++++---- lib/utils.h | 2 +- src/net_setup.c | 15 ++++++++++++--- src/protocol_auth.c | 15 ++++++++++++--- src/protocol_key.c | 8 +++++++- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/utils.c b/lib/utils.c index 405097bb..3b221f59 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -32,11 +32,13 @@ static int charhex2bin(char c) { return toupper(c) - 'A' + 10; } - -void hex2bin(char *src, char *dst, int length) { - int i; - for(i = 0; i < length; i++) +bool hex2bin(char *src, char *dst, int length) { + for(int i = 0; i < length; i++) { + if(!isxdigit(src[i * 2]) || !isxdigit(src[i * 2 + 1])) + return false; dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]); + } + return true; } void bin2hex(char *src, char *dst, int length) { diff --git a/lib/utils.h b/lib/utils.h index f6ff7052..2e4fcf86 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -21,7 +21,7 @@ #ifndef __TINC_UTILS_H__ #define __TINC_UTILS_H__ -extern void hex2bin(char *src, char *dst, int length); +extern bool hex2bin(char *src, char *dst, int length); extern void bin2hex(char *src, char *dst, int length); #ifdef HAVE_MINGW diff --git a/src/net_setup.c b/src/net_setup.c index eec438a8..a28ab7ad 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -66,7 +66,10 @@ bool read_rsa_public_key(connection_t *c) { /* First, check for simple PublicKey statement */ if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) { - BN_hex2bn(&c->rsa_key->n, key); + if(BN_hex2bn(&c->rsa_key->n, key) != strlen(key)) { + logger(LOG_ERR, "Invalid PublicKey for %s!", c->name); + return false; + } BN_hex2bn(&c->rsa_key->e, "FFFF"); free(key); return true; @@ -169,8 +172,14 @@ static bool read_rsa_private_key(void) { } myself->connection->rsa_key = RSA_new(); // RSA_blinding_on(myself->connection->rsa_key, NULL); - BN_hex2bn(&myself->connection->rsa_key->d, key); - BN_hex2bn(&myself->connection->rsa_key->n, pubkey); + if(BN_hex2bn(&myself->connection->rsa_key->d, key) != strlen(key)) { + logger(LOG_ERR, "Invalid PrivateKey for myself!"); + return false; + } + if(BN_hex2bn(&myself->connection->rsa_key->n, pubkey) != strlen(pubkey)) { + logger(LOG_ERR, "Invalid PublicKey for myself!"); + return false; + } BN_hex2bn(&myself->connection->rsa_key->e, "FFFF"); free(key); free(pubkey); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 0ef54682..3bd34a01 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -308,7 +308,10 @@ bool metakey_h(connection_t *c) { /* Convert the challenge from hexadecimal back to binary */ - hex2bin(buffer, buffer, len); + if(!hex2bin(buffer, buffer, len)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key"); + return false; + } /* Decrypt the meta key */ @@ -426,7 +429,10 @@ bool challenge_h(connection_t *c) { /* Convert the challenge from hexadecimal back to binary */ - hex2bin(buffer, c->mychallenge, len); + if(!hex2bin(buffer, c->mychallenge, len)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHALLENGE", c->name, c->hostname, "invalid challenge"); + return false; + } c->allow_request = CHAL_REPLY; @@ -480,7 +486,10 @@ bool chal_reply_h(connection_t *c) { /* Convert the hash to binary format */ - hex2bin(hishash, hishash, c->outdigest->md_size); + if(!hex2bin(hishash, hishash, c->outdigest->md_size)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash"); + return false; + } /* Calculate the hash from the challenge we sent */ diff --git a/src/protocol_key.c b/src/protocol_key.c index 1a184fb8..f2f317de 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -240,10 +240,16 @@ bool ans_key_h(connection_t *c) { return send_request(to->nexthop->connection, "%s", c->buffer); } + /* Don't use key material until every check has passed. */ + from->status.validkey = false; + /* Update our copy of the origin's packet key */ from->outkey = xrealloc(from->outkey, strlen(key) / 2); from->outkeylength = strlen(key) / 2; - hex2bin(key, from->outkey, from->outkeylength); + if(!hex2bin(key, from->outkey, from->outkeylength)) { + logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key"); + return true; + } /* Check and lookup cipher and digest algorithms */