QuickTun-master/0000755000175000017500000000000013043364564013104 5ustar feniofenioQuickTun-master/build.sh0000755000175000017500000000760013043364564014545 0ustar feniofenio#!/bin/sh set -e tar="tar" cc="cc" if [ "$(uname -s)" = "OpenBSD" -o "$(uname -s)" = "FreeBSD" -o "$(uname -s)" = "NetBSD" ]; then echo "Detected *BSD" tar="gtar" export CPATH="/usr/local/include:${CPATH}" elif [ "$(uname -s)" = "SunOS" ]; then echo "Detected SunOS" tar="gtar" CFLAGS="$CFLAGS -DSOLARIS -m64" LDFLAGS="$LDFLAGS -lnsl -lsocket" elif [ "$(uname -s)" = "Darwin" ]; then echo "Detected Mac OS X (Darwin)" CFLAGS="$CFLAGS -arch i686" LDFLAGS="$LDFLAGS -arch i686" fi echo Cleaning up... rm -rf out/ obj/ tmp/ mkdir -p out if [ "$1" != "debian" ]; then echo Creating source archive... $tar --transform "s,^,quicktun-`cat version`/," -czf "out/quicktun-`cat version`.tgz" build.sh clean.sh deb src version --exclude "debian/data" fi mkdir -p obj tmp tmp/include tmp/lib export LIBRARY_PATH="/usr/local/lib/:${LIBRARY_PATH}" echo '#include ' > tmp/libtest1.c echo '#include ' > tmp/libtest2.c if [ "$1" = "debian" ] || $cc -shared -lsodium tmp/libtest1.c -o tmp/libtest 2>/dev/null; then echo Using shared libsodium. echo '#include ' > tmp/include/crypto_box_curve25519xsalsa20poly1305.h echo '#include ' > tmp/include/crypto_scalarmult_curve25519.h export CPATH="./tmp/include/:${CPATH}" export CRYPTLIB="sodium" elif $cc -shared -lnacl tmp/libtest2.c -o tmp/libtest 2>/dev/null; then echo Using shared libnacl. echo '#include ' > tmp/include/crypto_box_curve25519xsalsa20poly1305.h echo '#include ' > tmp/include/crypto_scalarmult_curve25519.h export CPATH="./tmp/include/:${CPATH}" export CRYPTLIB="nacl" else echo Building TweetNaCl... echo 'The TweetNaCl cryptography library is not optimized for performance. Please install libsodium or libnacl before building QuickTun for best performance.' $cc $CFLAGS -shared -fPIC src/tweetnacl.c src/randombytes.c -o tmp/lib/libtweetnacl.a echo '#include ' > tmp/include/crypto_box_curve25519xsalsa20poly1305.h echo '#include ' > tmp/include/crypto_scalarmult_curve25519.h export CPATH="./tmp/include/:${CPATH}" export LIBRARY_PATH="./tmp/lib/:${LIBRARY_PATH}" export CRYPTLIB="tweetnacl" fi CFLAGS="$CFLAGS -DQT_VERSION=\"`cat version`\"" echo Building combined binary... $cc $CFLAGS -c -DCOMBINED_BINARY src/proto.raw.c -o obj/proto.raw.o $cc $CFLAGS -c -DCOMBINED_BINARY src/proto.nacl0.c -o obj/proto.nacl0.o $cc $CFLAGS -c -DCOMBINED_BINARY src/proto.nacltai.c -o obj/proto.nacltai.o $cc $CFLAGS -c -DCOMBINED_BINARY src/proto.salty.c -o obj/proto.salty.o $cc $CFLAGS -c -DCOMBINED_BINARY src/run.combined.c -o obj/run.combined.o $cc $CFLAGS -c src/common.c -o obj/common.o $cc $CFLAGS -o out/quicktun.combined obj/common.o obj/run.combined.o obj/proto.raw.o obj/proto.nacl0.o obj/proto.nacltai.o obj/proto.salty.o -l$CRYPTLIB $LDFLAGS ln out/quicktun.combined out/quicktun echo Building single protocol binaries... $cc $CFLAGS -o out/quicktun.raw src/proto.raw.c $LDFLAGS $cc $CFLAGS -o out/quicktun.nacl0 src/proto.nacl0.c -l$CRYPTLIB $LDFLAGS $cc $CFLAGS -o out/quicktun.nacltai src/proto.nacltai.c -l$CRYPTLIB $LDFLAGS $cc $CFLAGS -o out/quicktun.salty src/proto.salty.c -l$CRYPTLIB $LDFLAGS $cc $CFLAGS -o out/quicktun.keypair src/keypair.c -l$CRYPTLIB $LDFLAGS if [ -f /etc/network/interfaces -o "$1" = "debian" ]; then echo Building debian binary... $cc $CFLAGS -c -DCOMBINED_BINARY -DDEBIAN_BINARY src/run.combined.c -o obj/run.debian.o $cc $CFLAGS -o out/quicktun.debian obj/common.o obj/run.debian.o obj/proto.raw.o obj/proto.nacl0.o obj/proto.nacltai.o obj/proto.salty.o -l$CRYPTLIB $LDFLAGS if [ "$1" != "debian" -a -x /usr/bin/dpkg-deb -a -x /usr/bin/fakeroot ]; then echo -n Building debian package... cd deb ./build.sh cd .. fi fi QuickTun-master/src/0000755000175000017500000000000013043364564013673 5ustar feniofenioQuickTun-master/src/tweetnacl.h0000644000175000017500000004715313043364564016044 0ustar feniofenio//TweetNaCl from https://tweetnacl.cr.yp.to/, public domain. #ifndef TWEETNACL_H #define TWEETNACL_H #define crypto_auth_PRIMITIVE "hmacsha512256" #define crypto_auth crypto_auth_hmacsha512256 #define crypto_auth_verify crypto_auth_hmacsha512256_verify #define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES #define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES #define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION #define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION #define crypto_auth_hmacsha512256_tweet_BYTES 32 #define crypto_auth_hmacsha512256_tweet_KEYBYTES 32 extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); #define crypto_auth_hmacsha512256_tweet_VERSION "-" #define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet #define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify #define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES #define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES #define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION #define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet" #define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" #define crypto_box crypto_box_curve25519xsalsa20poly1305 #define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open #define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair #define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm #define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm #define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm #define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES #define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES #define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES #define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES #define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES #define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES #define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION #define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION #define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32 #define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32 #define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32 #define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24 #define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32 #define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16 extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *); extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *); extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *); extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); #define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-" #define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet #define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open #define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair #define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm #define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm #define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm #define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES #define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES #define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES #define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES #define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES #define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES #define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION #define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet" #define crypto_core_PRIMITIVE "salsa20" #define crypto_core crypto_core_salsa20 #define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES #define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES #define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES #define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES #define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION #define crypto_core_VERSION crypto_core_salsa20_VERSION #define crypto_core_salsa20_tweet_OUTPUTBYTES 64 #define crypto_core_salsa20_tweet_INPUTBYTES 16 #define crypto_core_salsa20_tweet_KEYBYTES 32 #define crypto_core_salsa20_tweet_CONSTBYTES 16 extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); #define crypto_core_salsa20_tweet_VERSION "-" #define crypto_core_salsa20 crypto_core_salsa20_tweet #define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES #define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES #define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES #define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES #define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION #define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet" #define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32 #define crypto_core_hsalsa20_tweet_INPUTBYTES 16 #define crypto_core_hsalsa20_tweet_KEYBYTES 32 #define crypto_core_hsalsa20_tweet_CONSTBYTES 16 extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *); #define crypto_core_hsalsa20_tweet_VERSION "-" #define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet #define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES #define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES #define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES #define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES #define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION #define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet" #define crypto_hashblocks_PRIMITIVE "sha512" #define crypto_hashblocks crypto_hashblocks_sha512 #define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES #define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES #define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION #define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION #define crypto_hashblocks_sha512_tweet_STATEBYTES 64 #define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128 extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); #define crypto_hashblocks_sha512_tweet_VERSION "-" #define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet #define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES #define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES #define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION #define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet" #define crypto_hashblocks_sha256_tweet_STATEBYTES 32 #define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64 extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); #define crypto_hashblocks_sha256_tweet_VERSION "-" #define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet #define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES #define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES #define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION #define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet" #define crypto_hash_PRIMITIVE "sha512" #define crypto_hash crypto_hash_sha512 #define crypto_hash_BYTES crypto_hash_sha512_BYTES #define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION #define crypto_hash_VERSION crypto_hash_sha512_VERSION #define crypto_hash_sha512_tweet_BYTES 64 extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long); #define crypto_hash_sha512_tweet_VERSION "-" #define crypto_hash_sha512 crypto_hash_sha512_tweet #define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES #define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION #define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet" #define crypto_hash_sha256_tweet_BYTES 32 extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long); #define crypto_hash_sha256_tweet_VERSION "-" #define crypto_hash_sha256 crypto_hash_sha256_tweet #define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES #define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION #define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet" #define crypto_onetimeauth_PRIMITIVE "poly1305" #define crypto_onetimeauth crypto_onetimeauth_poly1305 #define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify #define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES #define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES #define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION #define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION #define crypto_onetimeauth_poly1305_tweet_BYTES 16 #define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32 extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *); #define crypto_onetimeauth_poly1305_tweet_VERSION "-" #define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet #define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify #define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES #define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES #define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION #define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet" #define crypto_scalarmult_PRIMITIVE "curve25519" #define crypto_scalarmult crypto_scalarmult_curve25519 #define crypto_scalarmult_base crypto_scalarmult_curve25519_base #define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES #define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES #define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION #define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION #define crypto_scalarmult_curve25519_tweet_BYTES 32 #define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32 extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *); extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *); #define crypto_scalarmult_curve25519_tweet_VERSION "-" #define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet #define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base #define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES #define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES #define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION #define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet" #define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" #define crypto_secretbox crypto_secretbox_xsalsa20poly1305 #define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open #define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES #define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES #define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES #define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES #define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION #define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION #define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32 #define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24 #define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32 #define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16 extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); #define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-" #define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet #define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open #define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES #define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES #define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES #define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES #define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION #define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet" #define crypto_sign_PRIMITIVE "ed25519" #define crypto_sign crypto_sign_ed25519 #define crypto_sign_open crypto_sign_ed25519_open #define crypto_sign_keypair crypto_sign_ed25519_keypair #define crypto_sign_BYTES crypto_sign_ed25519_BYTES #define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES #define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES #define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION #define crypto_sign_VERSION crypto_sign_ed25519_VERSION #define crypto_sign_ed25519_tweet_BYTES 64 #define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32 #define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64 extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *); extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *); #define crypto_sign_ed25519_tweet_VERSION "-" #define crypto_sign_ed25519 crypto_sign_ed25519_tweet #define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open #define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair #define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES #define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES #define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES #define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION #define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet" #define crypto_stream_PRIMITIVE "xsalsa20" #define crypto_stream crypto_stream_xsalsa20 #define crypto_stream_xor crypto_stream_xsalsa20_xor #define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES #define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES #define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION #define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION #define crypto_stream_xsalsa20_tweet_KEYBYTES 32 #define crypto_stream_xsalsa20_tweet_NONCEBYTES 24 extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); #define crypto_stream_xsalsa20_tweet_VERSION "-" #define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet #define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor #define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES #define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES #define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION #define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet" #define crypto_stream_salsa20_tweet_KEYBYTES 32 #define crypto_stream_salsa20_tweet_NONCEBYTES 8 extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); #define crypto_stream_salsa20_tweet_VERSION "-" #define crypto_stream_salsa20 crypto_stream_salsa20_tweet #define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor #define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES #define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES #define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION #define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet" #define crypto_verify_PRIMITIVE "16" #define crypto_verify crypto_verify_16 #define crypto_verify_BYTES crypto_verify_16_BYTES #define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION #define crypto_verify_VERSION crypto_verify_16_VERSION #define crypto_verify_16_tweet_BYTES 16 extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *); #define crypto_verify_16_tweet_VERSION "-" #define crypto_verify_16 crypto_verify_16_tweet #define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES #define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION #define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet" #define crypto_verify_32_tweet_BYTES 32 extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *); #define crypto_verify_32_tweet_VERSION "-" #define crypto_verify_32 crypto_verify_32_tweet #define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES #define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet" #endif QuickTun-master/src/common.c0000644000175000017500000003763613043364564015346 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include #include #include #include #include #include #include #ifndef HAVE_NETINET_IN_H #include #endif #include #include #include #include #include #include #include #include #ifdef linux #include #include #else #define ETH_FRAME_LEN 1514 #include #ifdef SOLARIS #include #include #endif #endif #define MAX_PACKET_LEN (ETH_FRAME_LEN+4) //Some space for optional packet information typedef union { struct sockaddr any; struct sockaddr_in ip4; struct sockaddr_in6 ip6; } sockaddr_any; struct qtsession; struct qtproto { int encrypted; int buffersize_raw; int buffersize_enc; int offset_raw; int offset_enc; int (*encode)(struct qtsession* sess, char* raw, char* enc, int len); int (*decode)(struct qtsession* sess, char* enc, char* raw, int len); int (*init)(struct qtsession* sess); int protocol_data_size; void (*idle)(struct qtsession* sess); }; struct qtsession { struct qtproto protocol; void* protocol_data; int fd_socket; int fd_dev; int remote_float; sockaddr_any remote_addr; int use_pi; int poll_timeout; void (*sendnetworkpacket)(struct qtsession* sess, char* msg, int len); }; #ifdef COMBINED_BINARY extern char* (*getconf)(const char*); extern int errorexit(const char*); extern int errorexitp(const char*); extern void print_header(); extern void hex2bin(unsigned char*, const char*, const int); extern int debug; extern int qtrun(struct qtproto* p); extern int qtprocessargs(int argc, char** argv); #else char* (*getconf)(const char*) = getenv; int debug = 0; static int gargc = 0; static char** gargv = NULL; int errorexit(const char* text) { fprintf(stderr, "%s\n", text); return -1; } int errorexit2(const char* text, const char* error) { fprintf(stderr, "%s: %s\n", text, error); return -1; } int errorexitp(const char* text) { perror(text); return -1; } void print_header() { fprintf(stderr, "UCIS QuickTun "QT_VERSION" (c) 2010-2017 Ivo Smits \n"); fprintf(stderr, "More information: http://wiki.ucis.nl/QuickTun\n"); } static int is_all_zero(void* buf, int size) { int i; char* bb = (char*)buf; for (i = 0; i < size; i++) if (bb[i] != 0) return 0; return 1; } static int sockaddr_is_zero_address(sockaddr_any* sa) { int af = sa->any.sa_family; if (af == AF_INET) return is_all_zero(&sa->ip4.sin_addr, sizeof(struct in_addr)); if (af == AF_INET6) return is_all_zero(&sa->ip6.sin6_addr, sizeof(struct in6_addr)); return is_all_zero(sa, sizeof(sockaddr_any)); } static int sockaddr_set_port(sockaddr_any* sa, int port) { port = htons(port); int af = sa->any.sa_family; if (af == AF_INET) sa->ip4.sin_port = port; else if (af == AF_INET6) sa->ip6.sin6_port = port; else return errorexit("Unknown address family"); return 0; } static int sockaddr_equal(sockaddr_any* a, sockaddr_any* b) { if (a->any.sa_family != b->any.sa_family) return 0; if (a->any.sa_family == AF_INET) return a->ip4.sin_port == b->ip4.sin_port && a->ip4.sin_addr.s_addr == b->ip4.sin_addr.s_addr; if (a->any.sa_family == AF_INET6) return a->ip6.sin6_port == b->ip6.sin6_port && memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(struct in6_addr)) == 0 && a->ip6.sin6_scope_id == b->ip6.sin6_scope_id; return memcmp(a, b, sizeof(sockaddr_any)) == 0; } static void sockaddr_to_string(sockaddr_any* sa, char* str, int strbuflen) { if (sa->any.sa_family == AF_INET) { if (!inet_ntop(AF_INET, &sa->ip4.sin_addr, str, strbuflen)) str[0] = 0; int i = strlen(str); snprintf(str + i, strbuflen - i, ":%u", ntohs(sa->ip4.sin_port)); } else if (sa->any.sa_family == AF_INET6) { if (!inet_ntop(AF_INET6, &sa->ip6.sin6_addr, str, strbuflen)) str[0] = 0; int i = strlen(str); snprintf(str + i, strbuflen - i, "%%%d:%u", sa->ip6.sin6_scope_id, ntohs(sa->ip6.sin6_port)); } else { strncpy(str, "Unknown AF", strbuflen); } str[strbuflen - 1] = 0; } static int init_udp(struct qtsession* session) { char* envval; fprintf(stderr, "Initializing UDP socket...\n"); struct addrinfo *ai_local = NULL, *ai_remote = NULL; unsigned short af = 0; int ret; if ((envval = getconf("LOCAL_ADDRESS"))) { if ((ret = getaddrinfo(envval, NULL, NULL, &ai_local))) return errorexit2("getaddrinfo(LOCAL_ADDRESS)", gai_strerror(ret)); if (!ai_local) return errorexit("LOCAL_ADDRESS lookup failed"); if (ai_local->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved LOCAL_ADDRESS is too big"); af = ai_local->ai_family; } if ((envval = getconf("REMOTE_ADDRESS"))) { if ((ret = getaddrinfo(envval, NULL, NULL, &ai_remote))) return errorexit2("getaddrinfo(REMOTE_ADDRESS)", gai_strerror(ret)); if (!ai_remote) return errorexit("REMOTE_ADDRESS lookup failed"); if (ai_remote->ai_addrlen > sizeof(sockaddr_any)) return errorexit("Resolved REMOTE_ADDRESS is too big"); if (af && af != ai_remote->ai_family) return errorexit("Address families do not match"); af = ai_remote->ai_family; } if (!af) af = AF_INET; int sa_size = sizeof(sockaddr_any); if (af == AF_INET) sa_size = sizeof(struct sockaddr_in); else if (af == AF_INET6) sa_size = sizeof(struct sockaddr_in6); int sfd = socket(af, SOCK_DGRAM, IPPROTO_UDP); if (sfd < 0) return errorexitp("Could not create UDP socket"); sockaddr_any udpaddr; memset(&udpaddr, 0, sizeof(udpaddr)); udpaddr.any.sa_family = af; if (ai_local) memcpy(&udpaddr, ai_local->ai_addr, ai_local->ai_addrlen); int port = 2998; if ((envval = getconf("LOCAL_PORT"))) port = atoi(envval); if (sockaddr_set_port(&udpaddr, port)) return -1; if (bind(sfd, &udpaddr.any, sa_size)) return errorexitp("Could not bind socket"); memset(&udpaddr, 0, sizeof(udpaddr)); udpaddr.any.sa_family = af; if (ai_remote) memcpy(&udpaddr, ai_remote->ai_addr, ai_remote->ai_addrlen); if (!ai_remote || sockaddr_is_zero_address(&udpaddr)) { session->remote_float = 1; } else { session->remote_float = getconf("REMOTE_FLOAT") ? 1 : 0; port = 2998; if ((envval = getconf("REMOTE_PORT"))) port = atoi(envval); if (sockaddr_set_port(&udpaddr, port)) return -1; session->remote_addr = udpaddr; if (session->remote_float) { session->remote_float = 2; } else { if (connect(sfd, &udpaddr.any, sa_size)) return errorexitp("Could not connect socket"); } } if (ai_local) freeaddrinfo(ai_local); if (ai_remote) freeaddrinfo(ai_remote); session->fd_socket = sfd; return sfd; } static int init_tuntap(struct qtsession* session) { char* envval; fprintf(stderr, "Initializing tun/tap device...\n"); int ttfd; //Tap device file descriptor int tunmode = 0; if ((envval = getconf("TUN_MODE"))) tunmode = atoi(envval); session->use_pi = 0; if (tunmode && (envval = getconf("USE_PI"))) session->use_pi = atoi(envval); #if defined(__linux__) struct ifreq ifr; //required for tun/tap setup memset(&ifr, 0, sizeof(ifr)); if ((ttfd = open("/dev/net/tun", O_RDWR)) < 0) return errorexitp("Could not open tun/tap device file"); if ((envval = getconf("INTERFACE"))) strcpy(ifr.ifr_name, envval); ifr.ifr_flags = tunmode ? IFF_TUN : IFF_TAP; if (!session->use_pi) ifr.ifr_flags |= IFF_NO_PI; if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed"); #elif defined SOLARIS int ip_fd = -1, if_fd = -1, ppa = 0; if ((ttfd = open("/dev/tun", O_RDWR)) < 0) return errorexitp("Could not open tun device file"); if ((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) return errorexitp("Could not open /dev/ip"); if ((envval = getconf("INTERFACE"))) { while (*envval && !isdigit((int)*envval)) envval++; ppa = atoi(envval); } if ((ppa = ioctl(ttfd, TUNNEWPPA, ppa)) < 0) return errorexitp("Could not assign new PPA"); if ((if_fd = open("/dev/tun", O_RDWR, 0)) < 0) return errorexitp("Could not open tun device file again"); if (ioctl(if_fd, I_PUSH, "ip") < 0) return errorexitp("Could not push IP module"); if (ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0) return errorexitp("Could not set PPA"); if (ioctl(ip_fd, I_LINK, if_fd) < 0) return errorexitp("Could not link TUN device to IP"); #else if (!(envval = getconf("INTERFACE"))) envval = "/dev/tun0"; if ((ttfd = open(envval, O_RDWR)) < 0) return errorexitp("Could not open tun device file"); if (tunmode) { int i = IFF_POINTOPOINT | IFF_MULTICAST; ioctl(ttfd, TUNSIFMODE, &i); #if defined(__OpenBSD__) if (!session->use_pi) session->use_pi = 2; #else i = session->use_pi ? 1 : 0; ioctl(ttfd, TUNSIFHEAD, &i); #endif } #endif if ((envval = getconf("TUN_UP_SCRIPT"))) system(envval); session->fd_dev = ttfd; return ttfd; } bool hex2bin(unsigned char* dest, const char* src, const int count) { int i; for (i = 0; i < count; i++) { if (*src >= '0' && *src <= '9') *dest = *src - '0'; else if (*src >= 'a' && * src <='f') *dest = *src - 'a' + 10; else if (*src >= 'A' && * src <='F') *dest = *src - 'A' + 10; else return false; src++; *dest = *dest << 4; if (*src >= '0' && *src <= '9') *dest += *src - '0'; else if (*src >= 'a' && *src <= 'f') *dest += *src - 'a' + 10; else if (*src >= 'A' && *src <= 'F') *dest += *src - 'A' + 10; else return false; src++; dest++; } return true; } static int drop_privileges() { char* envval; struct passwd *pw = NULL; if ((envval = getconf("SETUID"))) { pw = getpwnam(envval); if (!pw) return errorexitp("getpwnam"); } if ((envval = getconf("CHROOT"))) { if (chroot(envval)) return errorexitp("chroot"); if (chdir("/")) return errorexitp("chdir /"); } if (pw) { if (setgroups(0, NULL) == -1) return errorexitp("setgroups"); if (setgid(pw->pw_gid) == -1) return errorexitp("setgid"); if (setuid(pw->pw_uid) == -1) return errorexitp("setuid"); } return 0; } static void qtsendnetworkpacket(struct qtsession* session, char* msg, int len) { if (session->remote_float == 0) { len = write(session->fd_socket, msg, len); } else if (session->remote_float == 2) { int sa_size = sizeof(sockaddr_any); if (session->remote_addr.any.sa_family == AF_INET) sa_size = sizeof(struct sockaddr_in); else if (session->remote_addr.any.sa_family == AF_INET6) sa_size = sizeof(struct sockaddr_in6); len = sendto(session->fd_socket, msg, len, 0, (struct sockaddr*)&session->remote_addr, sa_size); } } int qtrun(struct qtproto* p) { if (getconf("DEBUG")) debug = 1; struct qtsession session; session.poll_timeout = -1; session.protocol = *p; if (init_udp(&session) < 0) return -1; int sfd = session.fd_socket; session.sendnetworkpacket = qtsendnetworkpacket; if (init_tuntap(&session) < 0) return -1; int ttfd = session.fd_dev; char protocol_data[p->protocol_data_size]; memset(protocol_data, 0, p->protocol_data_size); session.protocol_data = protocol_data; if (p->init && p->init(&session) < 0) return -1; if (drop_privileges() < 0) return -1; fprintf(stderr, "The tunnel is now operational!\n"); struct pollfd fds[2]; fds[0].fd = ttfd; fds[0].events = POLLIN; fds[1].fd = sfd; fds[1].events = POLLIN; int pi_length = 0; if (session.use_pi == 2) pi_length = 4; char buffer_raw_a[p->buffersize_raw + pi_length]; char buffer_enc_a[p->buffersize_enc]; char* buffer_raw = buffer_raw_a; char* buffer_enc = buffer_enc_a; while (1) { int len = poll(fds, 2, session.poll_timeout); if (len < 0) return errorexitp("poll error"); else if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) return errorexit("poll error on tap device"); else if (fds[1].revents & (POLLHUP | POLLNVAL)) return errorexit("poll error on udp socket"); if (len == 0 && p->idle) p->idle(&session); if (fds[0].revents & POLLIN) { len = read(ttfd, buffer_raw + p->offset_raw, p->buffersize_raw + pi_length); if (len < pi_length) return errorexit("read packet smaller than header from tun device"); if (session.remote_float == 0 || session.remote_float == 2) { len = p->encode(&session, buffer_raw + pi_length, buffer_enc, len - pi_length); if (len < 0) return len; if (len == 0) continue; //encoding is not yet possible qtsendnetworkpacket(&session, buffer_enc + p->offset_enc, len); } } if (fds[1].revents & POLLERR) { int out; socklen_t slen = sizeof(out); getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &slen); fprintf(stderr, "Received error %d on udp socket\n", out); } if (fds[1].revents & POLLIN) { sockaddr_any recvaddr; socklen_t recvaddr_len = sizeof(recvaddr); if (session.remote_float == 0) { len = read(sfd, buffer_enc + p->offset_enc, p->buffersize_enc); } else { len = recvfrom(sfd, buffer_enc + p->offset_enc, p->buffersize_enc, 0, (struct sockaddr*)&recvaddr, &recvaddr_len); } if (len < 0) { int out; socklen_t slen = sizeof(out); getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &slen); fprintf(stderr, "Received end of file on udp socket (error %d)\n", out); } else { len = p->decode(&session, buffer_enc, buffer_raw + pi_length, len); if (len < 0) continue; if (session.remote_float != 0 && !sockaddr_equal(&session.remote_addr, &recvaddr)) { char epname[INET6_ADDRSTRLEN + 1 + 2 + 1 + 5]; //addr%scope:port sockaddr_to_string(&recvaddr, epname, sizeof(epname)); fprintf(stderr, "Remote endpoint has changed to %s\n", epname); session.remote_addr = recvaddr; session.remote_float = 2; } if (len > 0 && session.use_pi == 2) { int ipver = (buffer_raw[p->offset_raw + pi_length] >> 4) & 0xf; int pihdr = 0; #if defined linux if (ipver == 4) pihdr = 0x0000 | (0x0008 << 16); //little endian: flags and protocol are swapped else if (ipver == 6) pihdr = 0x0000 | (0xdd86 << 16); #else if (ipver == 4) pihdr = htonl(AF_INET); else if (ipver == 6) pihdr = htonl(AF_INET6); #endif *(int*)(buffer_raw + p->offset_raw) = pihdr; } if (len > 0) write(ttfd, buffer_raw + p->offset_raw, len + pi_length); } } } return 0; } static char* getconfcmdargs(const char* name) { int i; for (i = 1; i < gargc - 2; i++) { if (strcmp(gargv[i], "-c")) continue; if (strcmp(gargv[i + 1], name)) continue; return gargv[i + 2]; } return NULL; } int qtprocessargs(int argc, char** argv) { int i; for (i = 1; i < argc; i++) { char* a = argv[i]; if (!strcmp(a, "-h") || !strcmp(a, "--help")) { printf("Please read the documentation at http://wiki.ucis.nl/QuickTun\n"); return 0; } else if (!strcmp(a, "-v") || !strcmp(a, "--version")) { printf("UCIS QuickTun "QT_VERSION"\n"); return 0; } else if (!strcmp(a, "-c")) { gargc = argc; gargv = argv; getconf = getconfcmdargs; i += 2; } else { return errorexit("Unexpected command line argument"); } } return 1; } #endif QuickTun-master/src/proto.nacl0.c0000644000175000017500000001242613043364564016203 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include "common.c" #include "crypto_box_curve25519xsalsa20poly1305.h" struct qt_proto_data_nacl0 { unsigned char cnonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES], cbefore[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; }; static int encode(struct qtsession* sess, char* raw, char* enc, int len) { struct qt_proto_data_nacl0* d = (struct qt_proto_data_nacl0*)sess->protocol_data; memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES); if (crypto_box_curve25519xsalsa20poly1305_afternm((unsigned char*)enc, (unsigned char*)raw, len+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cnonce, d->cbefore)) return errorexit("Crypto failed"); return len + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; } static int decode(struct qtsession* sess, char* enc, char* raw, int len) { struct qt_proto_data_nacl0* d = (struct qt_proto_data_nacl0*)sess->protocol_data; if (len < crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES) { fprintf(stderr, "Short packet received: %d\n", len); return -1; } len -= crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES); if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc, len+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cnonce, d->cbefore)) { fprintf(stderr, "Decryption failed len=%d\n", len); return -1; } return len; } static int init(struct qtsession* sess) { char* envval; struct qt_proto_data_nacl0* d = (struct qt_proto_data_nacl0*)sess->protocol_data; printf("Initializing cryptography...\n"); memset(d->cnonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); unsigned char cpublickey[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES], csecretkey[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES]; if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY"); if (strlen(envval) != 2*crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length"); hex2bin(cpublickey, envval, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES); if ((envval = getconf("PRIVATE_KEY"))) { if (strlen(envval) != 2*crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length"); hex2bin(csecretkey, envval, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else if ((envval = getconf("PRIVATE_KEY_FILE"))) { FILE* pkfile = fopen(envval, "rb"); if (!pkfile) return errorexitp("Could not open PRIVATE_KEY_FILE"); char pktextbuf[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES * 2]; const size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile); if (pktextsize == crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) { memcpy(csecretkey, pktextbuf, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else if (pktextsize == 2 * crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) { hex2bin(csecretkey, pktextbuf, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else { return errorexit("PRIVATE_KEY length"); } fclose(pkfile); } else { return errorexit("Missing PRIVATE_KEY"); } if (crypto_box_curve25519xsalsa20poly1305_beforenm(d->cbefore, cpublickey, csecretkey)) return errorexit("Encryption key calculation failed"); return 0; } struct qtproto qtproto_nacl0 = { 1, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES, encode, decode, init, sizeof(struct qt_proto_data_nacl0), }; #ifndef COMBINED_BINARY int main(int argc, char** argv) { print_header(); int rc = qtprocessargs(argc, argv); if (rc <= 0) return rc; return qtrun(&qtproto_nacl0); } #endif QuickTun-master/src/proto.salty.c0000644000175000017500000004710613043364564016345 0ustar feniofenio/* Copyright 2013 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ /* QuickTun Salty protocol A curve25519xsalsa20poly1305 based VPN protocol providing encryption, authentication and PFS. The Salty protocol is stateful; each side of the connection keeps track of the current and previous state of the local and remote encoder for minimal overhead and little to none packet loss during key transitions. Wire format: 3 bit flags + 29 bit time + 16 byte checksum + encrypted data flag 7 = 0 flag 6 = sender key id flag 5 = recipient key id 8 bit flags + 64 bit time + 16 byte checksum + encrypted data flag 7 = 1 encrypted data = 8 bit flags + 32 byte sender key + 24 byte sender nonce + 32 byte recipient key + 24 byte recipient nonce + 64 bit last received and accepted control timestamp flag 7 = 0 flag 6 = sender key id flag 5 = recipient key id flag 4 = is acknowledgment Key update (begin): Generate new key pair and nonce (last 4 bytes in nonce should be 0) Set ]> = Set ]> = Send key update: sender key id = !, sender key = .Public, nonce = , recipient key id = , recipient key = , recipient nonce = Key update received: Set = sender key id Set = sender key Set = sender nonce If exists then Set ]> = decoder(, , ) If exists then Set ]> = decoder(, , ) If == recipient key && == recipient nonce If recipient key id == then If encoder exists then Set encodenonce = encoder.Nonce Else Set encodenonce = ]> Set encoder(, , encodenonce) Else if recipient key id == ! && is set Set = Set = ! Set = NULL Set encoder(, , ) If ! is acknowledgment then Send key update: sender key id = , sender key = , nonce = ], recipient key id = , recipient key = , recipient nonce = Else Send key update: sender key id = , sender key = , nonce = ], recipient key id = , recipient key = , recipient nonce = On startup: Begin key update Every 1 minute: If is set: Send key update: sender key id = , sender key = , nonce = ], recipient key id = , recipient key = , recipient nonce = Every 10 minutes: Begin key update (if any packets have been sent with current key) When sending packet: If and are set: If packets sent with this key == (1<<29)-1 Switch to or drop packet If packets sent with this key > (1<<28) If is set: Send key update: sender key id = !, sender key = .Public, nonce = , recipient key id = , recipient key = , recipient nonce = Else Begin key update Else If is set: Send key update: sender key id = !, sender key = .Public, nonce = , recipient key id = , recipient key = , recipient nonce = Else Begin key update When receiving packet: if flag 0 == 1 If time <= then Ignore packet Decrypt packet Set = time Key update received Else Use decoder decstate[recipient key id][sender key id] Find index and value of lowest value in recenttimes as mintime and mintimeidx If time <= mintime then Ignore packet Decode packet Set recenttimes[mintimeidx] = time Write packet to tunnel */ #include "common.c" #include "crypto_box_curve25519xsalsa20poly1305.h" #include "crypto_scalarmult_curve25519.h" #include #include #include #include #define NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES #define BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES #define PRIVATEKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES #define PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES typedef unsigned int uint32; typedef unsigned long long uint64; struct qt_proto_data_salty_decstate { unsigned char remotekey[PUBLICKEYBYTES]; unsigned char nonce[NONCEBYTES]; unsigned char sharedkey[BEFORENMBYTES]; uint32 timestamps[5]; }; struct qt_proto_data_salty_keyset { unsigned char privatekey[PRIVATEKEYBYTES]; unsigned char publickey[PUBLICKEYBYTES]; unsigned char sharedkey[BEFORENMBYTES]; unsigned char nonce[NONCEBYTES]; }; struct qt_proto_data_salty { time_t lastkeyupdate, lastkeyupdatesent; unsigned char controlkey[BEFORENMBYTES]; int controlroles; uint64 controldecodetime; uint64 controlencodetime; struct qt_proto_data_salty_keyset* dataencoder; struct qt_proto_data_salty_keyset datalocalkeys[2]; int datalocalkeyid; int datalocalkeynextid; int dataremotekeyid; unsigned char dataremotekey[PUBLICKEYBYTES]; unsigned char dataremotenonce[NONCEBYTES]; struct qt_proto_data_salty_decstate datadecoders[4]; }; static void encodeuint32(char* b, uint32 v) { b[0] = (v >> 24) & 255; b[1] = (v >> 16) & 255; b[2] = (v >> 8) & 255; b[3] = (v >> 0) & 255; } static uint32 decodeuint32(char* sb) { unsigned char* b = (unsigned char*)sb; return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; } static void encodeuint64(unsigned char* b, uint64 v) { b[0] = (v >> 56) & 255; b[1] = (v >> 48) & 255; b[2] = (v >> 40) & 255; b[3] = (v >> 32) & 255; b[4] = (v >> 24) & 255; b[5] = (v >> 16) & 255; b[6] = (v >> 8) & 255; b[7] = (v >> 0) & 255; } static uint64 decodeuint64(char* sb) { unsigned char* b = (unsigned char*)sb; return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | (uint64)b[7]; } static int devurandomfd = -1; static void dumphex(char* lbl, unsigned char* buffer, int len) { fprintf(stderr, "%s: ", lbl); for (; len > 0; len--, buffer++) fprintf(stderr, "%02x", *buffer); fprintf(stderr, "\n"); } static bool randombytes(unsigned char* buffer, int len) { if (devurandomfd == -1) devurandomfd = open("/dev/urandom", O_RDONLY); if (devurandomfd == -1) return false; while (len > 0) { int got = read(devurandomfd, buffer, len); if (got < 0) return false; buffer += got; len -= got; } return true; } static void initdecoder(struct qt_proto_data_salty_decstate* d, unsigned char rkey[], unsigned char lkey[], unsigned char nonce[]) { memcpy(d->remotekey, rkey, PUBLICKEYBYTES); memcpy(d->nonce, nonce, NONCEBYTES); memset(d->timestamps, 0, 5 * sizeof(uint32)); if (debug) dumphex("INIT DECODER SK", lkey, 32); if (debug) dumphex("INIT DECODER RK", rkey, 32); if (crypto_box_curve25519xsalsa20poly1305_beforenm(d->sharedkey, rkey, lkey)) { errorexit("Encryption key calculation failed"); abort(); } } static void sendkeyupdate(struct qtsession* sess, bool ack) { struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; unsigned char buffer[32 + (1 + 32 + 24 + 32 + 24 + 8)]; int keyid = (d->datalocalkeynextid == -1) ? d->datalocalkeyid : d->datalocalkeynextid; if (debug) fprintf(stderr, "Sending key update nlkid=%d, rkid=%d, ack=%d\n", keyid, d->dataremotekeyid, ack); buffer[32] = (0 << 7) | (keyid << 6) | (d->dataremotekeyid << 5) | (ack ? (1 << 4) : (0 << 4)); memcpy(buffer + 32 + 1, d->datalocalkeys[keyid].publickey, 32); memcpy(buffer + 32 + 1 + 32, d->datalocalkeys[keyid].nonce, 24); memcpy(buffer + 32 + 1 + 32 + 24, d->dataremotekey, 32); memcpy(buffer + 32 + 1 + 32 + 24 + 32, d->dataremotenonce, 24); encodeuint64(buffer + 32 + 1 + 32 + 24 + 32 + 24, d->controldecodetime); memset(buffer, 0, 32); d->controlencodetime++; unsigned char nonce[24]; memset(nonce, 0, 24); nonce[0] = d->controlroles & 1; encodeuint64(nonce + 16, d->controlencodetime); unsigned char encbuffer[32 + 1 + 32 + 24 + 32 + 24 + 8]; if (crypto_box_curve25519xsalsa20poly1305_afternm(encbuffer, buffer, 32 + (1 + 32 + 24 + 32 + 24 + 8), nonce, d->controlkey)) return; memcpy(encbuffer + 16 - 8, nonce + 16, 8); encbuffer[16 - 1 - 8] = 0x80; if (sess->sendnetworkpacket) sess->sendnetworkpacket(sess, (char*)encbuffer + 16 - 1 - 8, 1 + 8 + 16 + (1 + 32 + 24 + 32 + 24 + 8)); d->lastkeyupdatesent = time(NULL); } static bool beginkeyupdate(struct qtsession* sess) { struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; d->datalocalkeynextid = (d->datalocalkeyid + 1) % 2; if (debug) fprintf(stderr, "Beginning key update nlkid=%d, rkid=%d\n", d->datalocalkeynextid, d->dataremotekeyid); struct qt_proto_data_salty_keyset* enckey = &d->datalocalkeys[d->datalocalkeynextid]; if (!randombytes(enckey->nonce, 20)) return false; if (!randombytes(enckey->privatekey, PRIVATEKEYBYTES)) return false; crypto_scalarmult_curve25519_base(enckey->publickey, enckey->privatekey); memset(enckey->nonce + 20, 0, 4); if (debug) dumphex("New public key", enckey->publickey, 32); if (debug) dumphex("New base nonce", enckey->nonce, 24); initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | d->datalocalkeynextid], d->dataremotekey, enckey->privatekey, d->dataremotenonce); sendkeyupdate(sess, false); d->lastkeyupdate = time(NULL); return true; } static void beginkeyupdateifnecessary(struct qtsession* sess) { struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; time_t t = time(NULL); if (t - d->lastkeyupdate > 300) { beginkeyupdate(sess); } else if (d->datalocalkeynextid != -1 && t - d->lastkeyupdatesent > 1) { sendkeyupdate(sess, false); } } static int init(struct qtsession* sess) { struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; char* envval; printf("Initializing cryptography...\n"); unsigned char cpublickey[PUBLICKEYBYTES], csecretkey[PRIVATEKEYBYTES]; if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY"); if (strlen(envval) != 2*PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length"); hex2bin(cpublickey, envval, PUBLICKEYBYTES); if ((envval = getconf("PRIVATE_KEY"))) { if (strlen(envval) != 2 * PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length"); hex2bin(csecretkey, envval, PRIVATEKEYBYTES); } else if ((envval = getconf("PRIVATE_KEY_FILE"))) { FILE* pkfile = fopen(envval, "rb"); if (!pkfile) return errorexitp("Could not open PRIVATE_KEY_FILE"); char pktextbuf[PRIVATEKEYBYTES * 2]; const size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile); if (pktextsize == PRIVATEKEYBYTES) { memcpy(csecretkey, pktextbuf, PRIVATEKEYBYTES); } else if (pktextsize == 2 * PRIVATEKEYBYTES) { hex2bin(csecretkey, pktextbuf, PRIVATEKEYBYTES); } else { return errorexit("PRIVATE_KEY length"); } fclose(pkfile); } else { return errorexit("Missing PRIVATE_KEY"); } if (crypto_box_curve25519xsalsa20poly1305_beforenm(d->controlkey, cpublickey, csecretkey)) return errorexit("Encryption key calculation failed"); unsigned char cownpublickey[PUBLICKEYBYTES]; crypto_scalarmult_curve25519_base(cownpublickey, csecretkey); int role = memcmp(cownpublickey, cpublickey, PUBLICKEYBYTES); d->controlroles = (role == 0) ? 0 : ((role > 0) ? 1 : 2); d->controldecodetime = 0; d->controlencodetime = ((uint64)time(NULL)) << 8; d->datalocalkeyid = 0; d->datalocalkeynextid = -1; d->dataremotekeyid = 0; beginkeyupdate(sess); d->datalocalkeyid = d->datalocalkeynextid; sess->poll_timeout = 5000; return 0; } static int encode(struct qtsession* sess, char* raw, char* enc, int len) { beginkeyupdateifnecessary(sess); struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; struct qt_proto_data_salty_keyset* e = d->dataencoder; if (!e) { if (debug) fprintf(stderr, "Discarding outgoing packet of %d bytes because encoder is not available\n", len); return 0; } if (debug) fprintf(stderr, "Encoding packet of %d bytes from %p to %p\n", len, raw, enc); //Check if nonce has exceeded half of maximum value (key update) or has exceeded maximum value (drop packet) if (e->nonce[20] & 0xF0) { if (d->datalocalkeynextid == -1) { beginkeyupdate(sess); } else { sendkeyupdate(sess, false); } if (e->nonce[20] & 0xE0) return 0; } //Increment nonce in big endian int i; for (i = NONCEBYTES - 1; i >= 0 && ++e->nonce[i] == 0; i--) ; if (e->nonce[20] & 0xE0) return 0; if (debug) dumphex("ENCODE KEY", e->sharedkey, 32); memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES); if (crypto_box_curve25519xsalsa20poly1305_afternm((unsigned char*)enc, (unsigned char*)raw, len + 32, e->nonce, e->sharedkey)) return errorexit("Encryption failed"); enc[12] = (e->nonce[20] & 0x1F) | (0 << 7) | (d->datalocalkeyid << 6) | (d->dataremotekeyid << 5); enc[13] = e->nonce[21]; enc[14] = e->nonce[22]; enc[15] = e->nonce[23]; if (debug) fprintf(stderr, "Encoded packet of %d bytes to %d bytes\n", len, len + 16 + 4); return len + 16 + 4; } static int decode(struct qtsession* sess, char* enc, char* raw, int len) { beginkeyupdateifnecessary(sess); int i; struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data; if (len < 1) { fprintf(stderr, "Short packet received: %d\n", len); return -1; } int flags = (unsigned char)enc[12]; if (!(flags & 0x80)) { //<12 byte padding>|<4 byte timestamp> if (len < 4 + 16) { fprintf(stderr, "Short data packet received: %d\n", len); return -1; } struct qt_proto_data_salty_decstate* dec = &d->datadecoders[(flags >> 5) & 0x03]; uint32 ts = decodeuint32(enc + 12) & 0x1FFFFFFF; if (debug) fprintf(stderr, "Decoding data packet of %d bytes with timestamp %u and flags %d\n", len, ts, flags & 0xE0); int ltsi = 0; uint32 ltsv = 0xFFFFFFFF; for (i = 0; i < 5; i++) { uint32 v = dec->timestamps[i]; if (ts == v) { fprintf(stderr, "Duplicate data packet received: %u\n", ts); return -1; } if (v < ltsv) { ltsi = i; ltsv = v; } } if (ts <= ltsv) { fprintf(stderr, "Late data packet received: %u\n", ts); return -1; } dec->nonce[20] = enc[12] & 0x1F; dec->nonce[21] = enc[13]; dec->nonce[22] = enc[14]; dec->nonce[23] = enc[15]; memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES); if (debug) dumphex("DECODE KEY", dec->sharedkey, 32); if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc, len - 4 + 16, dec->nonce, dec->sharedkey)) { fprintf(stderr, "Decryption of data packet failed len=%d\n", len); return -1; } dec->timestamps[ltsi] = ts; return len - 16 - 4; } else { //<12 byte padding>|<1 byte flags><8 byte timestamp> if (len < 9 + 16 + 1 + 32 + 24 + 32 + 24 + 8) { fprintf(stderr, "Short control packet received: %d\n", len); return -1; } uint64 ts = decodeuint64(enc + 13); if (debug) fprintf(stderr, "Decoding control packet of %d bytes with timestamp %llu and flags %d\n", len, ts, flags); if (ts <= d->controldecodetime) { fprintf(stderr, "Late control packet received: %llu < %llu\n", ts, d->controldecodetime); return -1; } unsigned char cnonce[NONCEBYTES]; memset(cnonce, 0, 24); cnonce[0] = (d->controlroles >> 1) & 1; memcpy(cnonce + 16, enc + 13, 8); memset(enc + 12 + 1 + 8 - 16, 0, 16); if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc + 12 + 1 + 8 - 16, len - 1 - 8 + 16, cnonce, d->controlkey)) { fprintf(stderr, "Decryption of control packet failed len=%d\n", len); return -1; } d->controldecodetime = ts; int dosendkeyupdate = 0; //<32 byte padding><1 byte flags><32 byte sender key><24 byte sender nonce><32 byte recipient key><24 byte recipient nonce><8 byte timestamp> int cflags = (unsigned char)raw[32]; d->dataremotekeyid = (cflags >> 6) & 0x01; int lkeyid = (cflags >> 5) & 0x01; if ((cflags & (1 << 4)) == 0) dosendkeyupdate |= 1; memcpy(d->dataremotekey, raw + 32 + 1, 32); memcpy(d->dataremotenonce, raw + 32 + 1 + 32, 24); uint64 lexpectts = decodeuint64(raw + 32 + 1 + 32 + 24 + 32 + 24); if (lexpectts > d->controlencodetime) { fprintf(stderr, "Remote expects newer control timestamp (%llu > %llu), moving forward.\n", lexpectts, d->controlencodetime); d->controlencodetime = lexpectts; } struct qt_proto_data_salty_keyset* enckey = &d->datalocalkeys[lkeyid]; if (memcmp(enckey->publickey, raw + 32 + 1 + 32 + 24, 32) || memcmp(enckey->nonce, raw + 32 + 1 + 32 + 24 + 32, 20)) { dosendkeyupdate |= 2; lkeyid = -1; } initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | 0x00], d->dataremotekey, d->datalocalkeys[0].privatekey, d->dataremotenonce); initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | 0x01], d->dataremotekey, d->datalocalkeys[1].privatekey, d->dataremotenonce); if (lkeyid != -1 && lkeyid == d->datalocalkeynextid) { d->datalocalkeyid = lkeyid; d->datalocalkeynextid = -1; } if (lkeyid == d->datalocalkeyid) { if (crypto_box_curve25519xsalsa20poly1305_beforenm(enckey->sharedkey, d->dataremotekey, enckey->privatekey)) { errorexit("Encryption key calculation failed"); abort(); } d->dataencoder = enckey; } if (debug) fprintf(stderr, "Decoded control packet: rkid=%d, lkid=%d, ack=%d, lkvalid=%d, uptodate=%d\n", d->dataremotekeyid, (cflags >> 5) & 0x01, (cflags >> 4) & 0x01, lkeyid != -1, d->datalocalkeynextid == -1); if (d->datalocalkeynextid != -1) dosendkeyupdate |= 2; if (dosendkeyupdate) sendkeyupdate(sess, (dosendkeyupdate & 2) == 0); return 0; } } static void idle(struct qtsession* sess) { beginkeyupdateifnecessary(sess); } struct qtproto qtproto_salty = { 1, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - 4, encode, decode, init, sizeof(struct qt_proto_data_salty), idle, }; #ifndef COMBINED_BINARY int main(int argc, char** argv) { print_header(); int rc = qtprocessargs(argc, argv); if (rc <= 0) return rc; return qtrun(&qtproto_salty); } #endif QuickTun-master/src/run.combined.c0000644000175000017500000000556113043364564016431 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include "common.c" extern struct qtproto qtproto_raw; extern struct qtproto qtproto_nacl0; extern struct qtproto qtproto_nacltai; extern struct qtproto qtproto_salty; #ifdef DEBIAN_BINARY char* getenvdeb(const char* name) { char tmp[1024] = "IF_QT_"; if (strcmp(name, "INTERFACE") == 0) return getenv("IFACE"); if (strlen(tmp) + strlen(name) >= 1024) { fprintf(stderr, "Error: prefixed environment variable name is too long"); return NULL; } strcat(tmp, name); return getenv(tmp); } #endif int main(int argc, char** argv) { print_header(); #ifdef DEBIAN_BINARY getconf = getenvdeb; #else getconf = getenv; #endif int rc = qtprocessargs(argc, argv); if (rc <= 0) return rc; char* envval; if ((envval = getconf("PROTOCOL"))) { if (strcmp(envval, "raw") == 0) { return qtrun(&qtproto_raw); } else if (strcmp(envval, "nacl0") == 0) { return qtrun(&qtproto_nacl0); } else if (strcmp(envval, "nacltai") == 0) { return qtrun(&qtproto_nacltai); } else if (strcmp(envval, "salty") == 0) { return qtrun(&qtproto_salty); } else { return errorexit("Unknown PROTOCOL specified"); } } else if (getconf("PRIVATE_KEY")) { fprintf(stderr, "Warning: PROTOCOL not specified, using insecure nacl0 protocol\n"); return qtrun(&qtproto_nacl0); } else { fprintf(stderr, "Warning: PROTOCOL not specified, using insecure raw protocol\n"); return qtrun(&qtproto_raw); } } QuickTun-master/src/proto.nacltai.c0000644000175000017500000002024613043364564016620 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include "common.c" #include "crypto_box_curve25519xsalsa20poly1305.h" #include "crypto_scalarmult_curve25519.h" #include #include struct packedtaia { unsigned char buffer[16]; }; struct qt_proto_data_nacltai { unsigned char cenonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES]; unsigned char cdnonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES]; unsigned char cbefore[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; struct packedtaia cdtailog[5]; }; #define noncelength 16 #define nonceoffset (crypto_box_curve25519xsalsa20poly1305_NONCEBYTES - noncelength) static const int overhead = crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + noncelength; static void taia_now_packed(unsigned char* b, int secoffset) { struct timeval now; gettimeofday(&now, NULL); u_int64_t sec = 4611686018427387914ULL + (u_int64_t)now.tv_sec + secoffset; b[0] = (sec >> 56) & 0xff; b[1] = (sec >> 48) & 0xff; b[2] = (sec >> 40) & 0xff; b[3] = (sec >> 32) & 0xff; b[4] = (sec >> 24) & 0xff; b[5] = (sec >> 16) & 0xff; b[6] = (sec >> 8) & 0xff; b[7] = (sec >> 0) & 0xff; u_int32_t nano = 1000 * now.tv_usec + 500; b[8] = (nano >> 24) & 0xff; b[9] = (nano >> 16) & 0xff; b[10] = (nano >> 8) & 0xff; b[11] = (nano >> 0) & 0xff; if (++b[15] == 0 && ++b[14] == 0 && ++b[13] == 0) ++b[12]; } //Packet format: <16 bytes taia packed timestamp><16 bytes checksum> static int encode(struct qtsession* sess, char* raw, char* enc, int len) { if (debug) fprintf(stderr, "Encoding packet of %d bytes from %p to %p\n", len, raw, enc); struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES); taia_now_packed(d->cenonce + nonceoffset, 0); if (crypto_box_curve25519xsalsa20poly1305_afternm((unsigned char*)enc, (unsigned char*)raw, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Encryption failed"); memcpy((void*)(enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength); len += overhead; if (debug) fprintf(stderr, "Encoded packet of %d bytes from %p to %p\n", len, raw, enc); return len; } static int decode(struct qtsession* sess, char* enc, char* raw, int len) { if (debug) fprintf(stderr, "Decoding packet of %d bytes from %p to %p\n", len, enc, raw); struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; int i; if (len < overhead) { fprintf(stderr, "Short packet received: %d\n", len); return -1; } len -= overhead; struct packedtaia* tailog = &d->cdtailog[0]; struct packedtaia* taiold = tailog; for (i = 0; i < 5; i++) { if (memcmp(enc, tailog, 16) == 0) { fprintf(stderr, "Duplicate timestamp received\n"); return -1; } if (memcmp(tailog, taiold, 16) < 0) taiold = tailog; tailog++; } if (memcmp(enc, taiold, 16) <= 0) { fprintf(stderr, "Timestamp going back, ignoring packet\n"); return -1; } memcpy(d->cdnonce + nonceoffset, enc, noncelength); memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES); if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cdnonce, d->cbefore)) { fprintf(stderr, "Decryption failed len=%d\n", len); return -1; } memcpy(taiold, d->cdnonce + nonceoffset, 16); if (debug) fprintf(stderr, "Decoded packet of %d bytes from %p to %p\n", len, enc, raw); return len; } static int init(struct qtsession* sess) { struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; char* envval; printf("Initializing cryptography...\n"); unsigned char cownpublickey[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES], cpublickey[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES], csecretkey[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES]; if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY"); if (strlen(envval) != 2*crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length"); hex2bin(cpublickey, envval, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES); if ((envval = getconf("PRIVATE_KEY"))) { if (strlen(envval) != 2*crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length"); hex2bin(csecretkey, envval, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else if ((envval = getconf("PRIVATE_KEY_FILE"))) { FILE* pkfile = fopen(envval, "rb"); if (!pkfile) return errorexitp("Could not open PRIVATE_KEY_FILE"); char pktextbuf[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES * 2]; const size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile); if (pktextsize == crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) { memcpy(csecretkey, pktextbuf, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else if (pktextsize == 2 * crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) { hex2bin(csecretkey, pktextbuf, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES); } else { return errorexit("PRIVATE_KEY length"); } fclose(pkfile); } else { return errorexit("Missing PRIVATE_KEY"); } if (crypto_box_curve25519xsalsa20poly1305_beforenm(d->cbefore, cpublickey, csecretkey)) return errorexit("Encryption key calculation failed"); memset(d->cenonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); memset(d->cdnonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); memset(d->cdtailog, 0, 5 * 16); crypto_scalarmult_curve25519_base(cownpublickey, csecretkey); if ((envval = getconf("TIME_WINDOW"))) { struct packedtaia* tailog = d->cdtailog; taia_now_packed((unsigned char*)&tailog[0], -atol(envval)); tailog[4] = tailog[3] = tailog[2] = tailog[1] = tailog[0]; } else { fprintf(stderr, "Warning: TIME_WINDOW not set, risking an initial replay attack\n"); } int role = memcmp(cownpublickey, cpublickey, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES); if ((envval = getconf("ROLE"))) role = atoi(envval) ? 1 : -1; role = (role == 0) ? 0 : ((role > 0) ? 1 : 2); d->cenonce[nonceoffset-1] = role & 1; d->cdnonce[nonceoffset-1] = (role >> 1) & 1; return 0; } struct qtproto qtproto_nacltai = { 1, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength, encode, decode, init, sizeof(struct qt_proto_data_nacltai), }; #ifndef COMBINED_BINARY int main(int argc, char** argv) { print_header(); int rc = qtprocessargs(argc, argv); if (rc <= 0) return rc; return qtrun(&qtproto_nacltai); } #endif QuickTun-master/src/tweetnacl.c0000644000175000017500000004047213043364564016034 0ustar feniofenio//TweetNaCl from https://tweetnacl.cr.yp.to/, public domain. #include "tweetnacl.h" #define FOR(i,n) for (i = 0;i < n;++i) #define sv static void typedef unsigned char u8; typedef unsigned long u32; typedef unsigned long long u64; typedef long long i64; typedef i64 gf[16]; extern void randombytes(u8 *,u64); static const u8 _0[16], _9[32] = {9}; static const gf gf0, gf1 = {1}, _121665 = {0xDB41,1}, D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203}, D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406}, X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169}, Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666}, I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83}; static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); } static u32 ld32(const u8 *x) { u32 u = x[3]; u = (u<<8)|x[2]; u = (u<<8)|x[1]; return (u<<8)|x[0]; } static u64 dl64(const u8 *x) { u64 i,u=0; FOR(i,8) u=(u<<8)|x[i]; return u; } sv st32(u8 *x,u32 u) { int i; FOR(i,4) { x[i] = u; u >>= 8; } } sv ts64(u8 *x,u64 u) { int i; for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; } } static int vn(const u8 *x,const u8 *y,int n) { u32 i,d = 0; FOR(i,n) d |= x[i]^y[i]; return (1 & ((d - 1) >> 8)) - 1; } int crypto_verify_16(const u8 *x,const u8 *y) { return vn(x,y,16); } int crypto_verify_32(const u8 *x,const u8 *y) { return vn(x,y,32); } sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h) { u32 w[16],x[16],y[16],t[4]; int i,j,m; FOR(i,4) { x[5*i] = ld32(c+4*i); x[1+i] = ld32(k+4*i); x[6+i] = ld32(in+4*i); x[11+i] = ld32(k+16+4*i); } FOR(i,16) y[i] = x[i]; FOR(i,20) { FOR(j,4) { FOR(m,4) t[m] = x[(5*j+4*m)%16]; t[1] ^= L32(t[0]+t[3], 7); t[2] ^= L32(t[1]+t[0], 9); t[3] ^= L32(t[2]+t[1],13); t[0] ^= L32(t[3]+t[2],18); FOR(m,4) w[4*j+(j+m)%4] = t[m]; } FOR(m,16) x[m] = w[m]; } if (h) { FOR(i,16) x[i] += y[i]; FOR(i,4) { x[5*i] -= ld32(c+4*i); x[6+i] -= ld32(in+4*i); } FOR(i,4) { st32(out+4*i,x[5*i]); st32(out+16+4*i,x[6+i]); } } else FOR(i,16) st32(out + 4 * i,x[i] + y[i]); } int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) { core(out,in,k,c,0); return 0; } int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c) { core(out,in,k,c,1); return 0; } static const u8 sigma[16] = "expand 32-byte k"; int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k) { u8 z[16],x[64]; u32 u,i; if (!b) return 0; FOR(i,16) z[i] = 0; FOR(i,8) z[i] = n[i]; while (b >= 64) { crypto_core_salsa20(x,z,k,sigma); FOR(i,64) c[i] = (m?m[i]:0) ^ x[i]; u = 1; for (i = 8;i < 16;++i) { u += (u32) z[i]; z[i] = u; u >>= 8; } b -= 64; c += 64; if (m) m += 64; } if (b) { crypto_core_salsa20(x,z,k,sigma); FOR(i,b) c[i] = (m?m[i]:0) ^ x[i]; } return 0; } int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k) { return crypto_stream_salsa20_xor(c,0,d,n,k); } int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k) { u8 s[32]; crypto_core_hsalsa20(s,n,k,sigma); return crypto_stream_salsa20(c,d,n+16,s); } int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) { u8 s[32]; crypto_core_hsalsa20(s,n,k,sigma); return crypto_stream_salsa20_xor(c,m,d,n+16,s); } sv add1305(u32 *h,const u32 *c) { u32 j,u = 0; FOR(j,17) { u += h[j] + c[j]; h[j] = u & 255; u >>= 8; } } static const u32 minusp[17] = { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 } ; int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k) { u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17]; FOR(j,17) r[j]=h[j]=0; FOR(j,16) r[j]=k[j]; r[3]&=15; r[4]&=252; r[7]&=15; r[8]&=252; r[11]&=15; r[12]&=252; r[15]&=15; while (n > 0) { FOR(j,17) c[j] = 0; for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j]; c[j] = 1; m += j; n -= j; add1305(h,c); FOR(i,17) { x[i] = 0; FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]); } FOR(i,17) h[i] = x[i]; u = 0; FOR(j,16) { u += h[j]; h[j] = u & 255; u >>= 8; } u += h[16]; h[16] = u & 3; u = 5 * (u >> 2); FOR(j,16) { u += h[j]; h[j] = u & 255; u >>= 8; } u += h[16]; h[16] = u; } FOR(j,17) g[j] = h[j]; add1305(h,minusp); s = -(h[16] >> 7); FOR(j,17) h[j] ^= s & (g[j] ^ h[j]); FOR(j,16) c[j] = k[j + 16]; c[16] = 0; add1305(h,c); FOR(j,16) out[j] = h[j]; return 0; } int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k) { u8 x[16]; crypto_onetimeauth(x,m,n,k); return crypto_verify_16(h,x); } int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) { int i; if (d < 32) return -1; crypto_stream_xor(c,m,d,n,k); crypto_onetimeauth(c + 16,c + 32,d - 32,c); FOR(i,16) c[i] = 0; return 0; } int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) { int i; u8 x[32]; if (d < 32) return -1; crypto_stream(x,32,n,k); if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1; crypto_stream_xor(m,c,d,n,k); FOR(i,32) m[i] = 0; return 0; } sv set25519(gf r, const gf a) { int i; FOR(i,16) r[i]=a[i]; } sv car25519(gf o) { int i; i64 c; FOR(i,16) { o[i]+=(1LL<<16); c=o[i]>>16; o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15); o[i]-=c<<16; } } sv sel25519(gf p,gf q,int b) { i64 t,i,c=~(b-1); FOR(i,16) { t= c&(p[i]^q[i]); p[i]^=t; q[i]^=t; } } sv pack25519(u8 *o,const gf n) { int i,j,b; gf m,t; FOR(i,16) t[i]=n[i]; car25519(t); car25519(t); car25519(t); FOR(j,2) { m[0]=t[0]-0xffed; for(i=1;i<15;i++) { m[i]=t[i]-0xffff-((m[i-1]>>16)&1); m[i-1]&=0xffff; } m[15]=t[15]-0x7fff-((m[14]>>16)&1); b=(m[15]>>16)&1; m[14]&=0xffff; sel25519(t,m,1-b); } FOR(i,16) { o[2*i]=t[i]&0xff; o[2*i+1]=t[i]>>8; } } static int neq25519(const gf a, const gf b) { u8 c[32],d[32]; pack25519(c,a); pack25519(d,b); return crypto_verify_32(c,d); } static u8 par25519(const gf a) { u8 d[32]; pack25519(d,a); return d[0]&1; } sv unpack25519(gf o, const u8 *n) { int i; FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8); o[15]&=0x7fff; } sv A(gf o,const gf a,const gf b) { int i; FOR(i,16) o[i]=a[i]+b[i]; } sv Z(gf o,const gf a,const gf b) { int i; FOR(i,16) o[i]=a[i]-b[i]; } sv M(gf o,const gf a,const gf b) { i64 i,j,t[31]; FOR(i,31) t[i]=0; FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j]; FOR(i,15) t[i]+=38*t[i+16]; FOR(i,16) o[i]=t[i]; car25519(o); car25519(o); } sv S(gf o,const gf a) { M(o,a,a); } sv inv25519(gf o,const gf i) { gf c; int a; FOR(a,16) c[a]=i[a]; for(a=253;a>=0;a--) { S(c,c); if(a!=2&&a!=4) M(c,c,i); } FOR(a,16) o[a]=c[a]; } sv pow2523(gf o,const gf i) { gf c; int a; FOR(a,16) c[a]=i[a]; for(a=250;a>=0;a--) { S(c,c); if(a!=1) M(c,c,i); } FOR(a,16) o[a]=c[a]; } int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p) { u8 z[32]; i64 x[80],r,i; gf a,b,c,d,e,f; FOR(i,31) z[i]=n[i]; z[31]=(n[31]&127)|64; z[0]&=248; unpack25519(x,p); FOR(i,16) { b[i]=x[i]; d[i]=a[i]=c[i]=0; } a[0]=d[0]=1; for(i=254;i>=0;--i) { r=(z[i>>3]>>(i&7))&1; sel25519(a,b,r); sel25519(c,d,r); A(e,a,c); Z(a,a,c); A(c,b,d); Z(b,b,d); S(d,e); S(f,a); M(a,c,a); M(c,b,e); A(e,a,c); Z(a,a,c); S(b,a); Z(c,d,f); M(a,c,_121665); A(a,a,d); M(c,c,a); M(a,d,f); M(d,b,x); S(b,e); sel25519(a,b,r); sel25519(c,d,r); } FOR(i,16) { x[i+16]=a[i]; x[i+32]=c[i]; x[i+48]=b[i]; x[i+64]=d[i]; } inv25519(x+32,x+32); M(x+16,x+16,x+32); pack25519(q,x+16); return 0; } int crypto_scalarmult_base(u8 *q,const u8 *n) { return crypto_scalarmult(q,n,_9); } int crypto_box_keypair(u8 *y,u8 *x) { randombytes(x,32); return crypto_scalarmult_base(y,x); } int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x) { u8 s[32]; crypto_scalarmult(s,x,y); return crypto_core_hsalsa20(k,_0,s,sigma); } int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k) { return crypto_secretbox(c,m,d,n,k); } int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k) { return crypto_secretbox_open(m,c,d,n,k); } int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x) { u8 k[32]; crypto_box_beforenm(k,y,x); return crypto_box_afternm(c,m,d,n,k); } int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x) { u8 k[32]; crypto_box_beforenm(k,y,x); return crypto_box_open_afternm(m,c,d,n,k); } static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); } static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); } static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); } static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); } static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); } static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); } static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); } static const u64 K[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; int crypto_hashblocks(u8 *x,const u8 *m,u64 n) { u64 z[8],b[8],a[8],w[16],t; int i,j; FOR(i,8) z[i] = a[i] = dl64(x + 8 * i); while (n >= 128) { FOR(i,16) w[i] = dl64(m + 8 * i); FOR(i,80) { FOR(j,8) b[j] = a[j]; t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16]; b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]); b[3] += t; FOR(j,8) a[(j+1)%8] = b[j]; if (i%16 == 15) FOR(j,16) w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]); } FOR(i,8) { a[i] += z[i]; z[i] = a[i]; } m += 128; n -= 128; } FOR(i,8) ts64(x+8*i,z[i]); return n; } static const u8 iv[64] = { 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 } ; int crypto_hash(u8 *out,const u8 *m,u64 n) { u8 h[64],x[256]; u64 i,b = n; FOR(i,64) h[i] = iv[i]; crypto_hashblocks(h,m,n); m += n; n &= 127; m -= n; FOR(i,256) x[i] = 0; FOR(i,n) x[i] = m[i]; x[n] = 128; n = 256-128*(n<112); x[n-9] = b >> 61; ts64(x+n-8,b<<3); crypto_hashblocks(h,x,n); FOR(i,64) out[i] = h[i]; return 0; } sv add(gf p[4],gf q[4]) { gf a,b,c,d,t,e,f,g,h; Z(a, p[1], p[0]); Z(t, q[1], q[0]); M(a, a, t); A(b, p[0], p[1]); A(t, q[0], q[1]); M(b, b, t); M(c, p[3], q[3]); M(c, c, D2); M(d, p[2], q[2]); A(d, d, d); Z(e, b, a); Z(f, d, c); A(g, d, c); A(h, b, a); M(p[0], e, f); M(p[1], h, g); M(p[2], g, f); M(p[3], e, h); } sv cswap(gf p[4],gf q[4],u8 b) { int i; FOR(i,4) sel25519(p[i],q[i],b); } sv pack(u8 *r,gf p[4]) { gf tx, ty, zi; inv25519(zi, p[2]); M(tx, p[0], zi); M(ty, p[1], zi); pack25519(r, ty); r[31] ^= par25519(tx) << 7; } sv scalarmult(gf p[4],gf q[4],const u8 *s) { int i; set25519(p[0],gf0); set25519(p[1],gf1); set25519(p[2],gf1); set25519(p[3],gf0); for (i = 255;i >= 0;--i) { u8 b = (s[i/8]>>(i&7))&1; cswap(p,q,b); add(q,p); add(p,p); cswap(p,q,b); } } sv scalarbase(gf p[4],const u8 *s) { gf q[4]; set25519(q[0],X); set25519(q[1],Y); set25519(q[2],gf1); M(q[3],X,Y); scalarmult(p,q,s); } int crypto_sign_keypair(u8 *pk, u8 *sk) { u8 d[64]; gf p[4]; int i; randombytes(sk, 32); crypto_hash(d, sk, 32); d[0] &= 248; d[31] &= 127; d[31] |= 64; scalarbase(p,d); pack(pk,p); FOR(i,32) sk[32 + i] = pk[i]; return 0; } static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; sv modL(u8 *r,i64 x[64]) { i64 carry,i,j; for (i = 63;i >= 32;--i) { carry = 0; for (j = i - 32;j < i - 12;++j) { x[j] += carry - 16 * x[i] * L[j - (i - 32)]; carry = (x[j] + 128) >> 8; x[j] -= carry << 8; } x[j] += carry; x[i] = 0; } carry = 0; FOR(j,32) { x[j] += carry - (x[31] >> 4) * L[j]; carry = x[j] >> 8; x[j] &= 255; } FOR(j,32) x[j] -= carry * L[j]; FOR(i,32) { x[i+1] += x[i] >> 8; r[i] = x[i] & 255; } } sv reduce(u8 *r) { i64 x[64],i; FOR(i,64) x[i] = (u64) r[i]; FOR(i,64) r[i] = 0; modL(r,x); } int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk) { u8 d[64],h[64],r[64]; i64 i,j,x[64]; gf p[4]; crypto_hash(d, sk, 32); d[0] &= 248; d[31] &= 127; d[31] |= 64; *smlen = n+64; FOR(i,n) sm[64 + i] = m[i]; FOR(i,32) sm[32 + i] = d[32 + i]; crypto_hash(r, sm+32, n+32); reduce(r); scalarbase(p,r); pack(sm,p); FOR(i,32) sm[i+32] = sk[i+32]; crypto_hash(h,sm,n + 64); reduce(h); FOR(i,64) x[i] = 0; FOR(i,32) x[i] = (u64) r[i]; FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j]; modL(sm + 32,x); return 0; } static int unpackneg(gf r[4],const u8 p[32]) { gf t, chk, num, den, den2, den4, den6; set25519(r[2],gf1); unpack25519(r[1],p); S(num,r[1]); M(den,num,D); Z(num,num,r[2]); A(den,r[2],den); S(den2,den); S(den4,den2); M(den6,den4,den2); M(t,den6,num); M(t,t,den); pow2523(t,t); M(t,t,num); M(t,t,den); M(t,t,den); M(r[0],t,den); S(chk,r[0]); M(chk,chk,den); if (neq25519(chk, num)) M(r[0],r[0],I); S(chk,r[0]); M(chk,chk,den); if (neq25519(chk, num)) return -1; if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]); M(r[3],r[0],r[1]); return 0; } int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk) { int i; u8 t[32],h[64]; gf p[4],q[4]; *mlen = -1; if (n < 64) return -1; if (unpackneg(q,pk)) return -1; FOR(i,n) m[i] = sm[i]; FOR(i,32) m[i+32] = pk[i]; crypto_hash(h,m,n); reduce(h); scalarmult(p,q,h); scalarbase(q,sm + 32); add(p,q); pack(t,p); n -= 64; if (crypto_verify_32(sm, t)) { FOR(i,n) m[i] = 0; return -1; } FOR(i,n) m[i] = sm[i + 64]; *mlen = n; return 0; } QuickTun-master/src/keypair.c0000644000175000017500000001024113043364564015501 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include "common.c" #include "crypto_box_curve25519xsalsa20poly1305.h" #include "crypto_scalarmult_curve25519.h" #include #include int main(int argc, char** argv) { print_header(); unsigned char cpublickey[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES]; unsigned char csecretkey[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES]; int input_mode = 0; //0=generate random, 1=read from argument int output_mode = 0; //0=human readable, 1=space separated, 2=concatenated binary int i; for (i = 1; i < argc; i++) { char* a = argv[i]; if (!strcmp(a, "-h") || !strcmp(a, "--help")) { printf("Please read the documentation at http://wiki.ucis.nl/QuickTun\n"); return 0; } else if (!strcmp(a, "-v") || !strcmp(a, "--version")) { printf("UCIS QuickTun "QT_VERSION"\n"); return 0; } else if (!strcmp(a, "-i")) { i++; if (i >= argc) return errorexit("Missing argument for -i"); if (!hex2bin(csecretkey, argv[i], crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES)) return errorexit("Invalid secret key argument"); input_mode = 1; } else if (!strcmp(a, "-f")) { int len = fread(csecretkey, 1, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES, stdin); if (len < crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES) return errorexitp("Error or end of file on STDIN"); input_mode = 1; } else if (!strcmp(a, "-o")) { i++; a = argv[i]; if (i >= argc) return errorexit("Missing argument for -o"); if (!strcmp(a, "human")) output_mode = 0; else if (!strcmp(a, "space")) output_mode = 1; else if (!strcmp(a, "bin")) output_mode = 2; else return errorexit("Invalid argument specified for -o"); } else { return errorexit("Unexpected command line argument"); } } if (input_mode == 0) { crypto_box_curve25519xsalsa20poly1305_keypair(cpublickey, csecretkey); } else { crypto_scalarmult_curve25519_base(cpublickey, csecretkey); } if (output_mode == 2) { fwrite(csecretkey, 1, crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES, stdout); fwrite(cpublickey, 1, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES, stdout); } else if (output_mode == 1) { for (i = 0; i < crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; i++) printf("%02x", csecretkey[i]); printf(" "); for (i = 0; i < crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; i++) printf("%02x", cpublickey[i]); printf("\n"); } else { printf("SECRET: "); for (i = 0; i < crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; i++) printf("%02x", csecretkey[i]); printf("\n"); printf("PUBLIC: "); for (i = 0; i < crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; i++) printf("%02x", cpublickey[i]); printf("\n"); } return 0; } QuickTun-master/src/randombytes.c0000644000175000017500000000107313043364564016367 0ustar feniofenio/* randombytes/devurandom.h version 20080713 D. J. Bernstein Public domain. */ #include #include #include #include static int fd = -1; void randombytes(unsigned char *x,unsigned long long xlen) { int i; if (fd == -1) { for (;;) { fd = open("/dev/urandom",O_RDONLY); if (fd != -1) break; sleep(1); } } while (xlen > 0) { if (xlen < 1048576) i = xlen; else i = 1048576; i = read(fd,x,i); if (i < 1) { sleep(1); continue; } x += i; xlen -= i; } } QuickTun-master/src/proto.raw.c0000644000175000017500000000401413043364564015771 0ustar feniofenio/* Copyright 2010 Ivo Smits . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Ivo Smits.*/ #include "common.c" static int encode(struct qtsession* sess, char* raw, char* enc, int len) { memcpy(enc, raw, len); return len; } static int decode(struct qtsession* sess, char* enc, char* raw, int len) { memcpy(raw, enc, len); return len; } struct qtproto qtproto_raw = { 0, MAX_PACKET_LEN, MAX_PACKET_LEN, 0, 0, decode, encode, NULL, 0, }; #ifndef COMBINED_BINARY int main(int argc, char** argv) { print_header(); int rc = qtprocessargs(argc, argv); if (rc <= 0) return rc; return qtrun(&qtproto_raw); } #endif QuickTun-master/deb/0000755000175000017500000000000013043364564013636 5ustar feniofenioQuickTun-master/deb/build.sh0000755000175000017500000000133513043364564015276 0ustar feniofenio#!/bin/sh set -e VERSION=`cat ../version`-0 ARCH=`dpkg --print-architecture` rm -r data 2>/dev/null || true cp -r static data mkdir -p data/usr data/usr/sbin data/DEBIAN sed "s/%ARCHITECTURE%/${ARCH}/" -i data/DEBIAN/control sed "s/%VERSION%/${VERSION}/" -i data/DEBIAN/control if [ -n "${NACL_SHARED}" ]; then sed "s/\\(Depends: .*\\)/\\1, libnacl | libnacl-ref | libnacl-build/" -i data/DEBIAN/control fi cp ../out/quicktun.raw data/usr/sbin/ cp ../out/quicktun.nacl0 data/usr/sbin/ cp ../out/quicktun.nacltai data/usr/sbin/ cp ../out/quicktun.debian data/usr/sbin/ cp ../out/quicktun.keypair data/usr/sbin/ cp ../out/quicktun data/usr/sbin/ fakeroot dpkg-deb --build data quicktun-${VERSION}_${ARCH}.deb mv quicktun*.deb ../out/ QuickTun-master/deb/static/0000755000175000017500000000000013043364564015125 5ustar feniofenioQuickTun-master/deb/static/DEBIAN/0000755000175000017500000000000013043364564016047 5ustar feniofenioQuickTun-master/deb/static/DEBIAN/prerm0000755000175000017500000000010613043364564017117 0ustar feniofenio#!/bin/sh if [ "$1" = "remove" ]; then /usr/sbin/userdel quicktun fi QuickTun-master/deb/static/DEBIAN/postinst0000755000175000017500000000025313043364564017660 0ustar feniofenio#!/bin/sh if [ "$1" = "configure" ]; then if ! getent passwd quicktun >/dev/null; then /usr/sbin/useradd -d /nonexistent -N -r -s /bin/false -g nogroup quicktun fi fi QuickTun-master/deb/static/DEBIAN/control0000644000175000017500000000041713043364564017454 0ustar feniofenioPackage: quicktun Version: %VERSION% Section: net Priority: optional Architecture: %ARCHITECTURE% Depends: bash, daemon, iproute (>= 20100519-1) | iproute2 | openvpn, passwd, coreutils Maintainer: Ivo Smits Description: Very simple, yet secure VPN software QuickTun-master/deb/static/etc/0000755000175000017500000000000013043364564015700 5ustar feniofenioQuickTun-master/deb/static/etc/network/0000755000175000017500000000000013043364564017371 5ustar feniofenioQuickTun-master/deb/static/etc/network/if-pre-up.d/0000755000175000017500000000000013043364564021417 5ustar feniofenioQuickTun-master/deb/static/etc/network/if-pre-up.d/quicktun0000755000175000017500000000117313043364564023212 0ustar feniofenio#!/bin/sh test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0 test -z "${IF_QT_NO_PRECREATE}" || exit 0 if [ -n "${IF_QT_TUN_MODE}" ] && [ "${IF_QT_TUN_MODE}" = "1" ]; then DEVTYPE="tun" else DEVTYPE="tap" fi if [ -x /usr/sbin/openvpn ]; then /usr/sbin/openvpn --mktun --dev "${IFACE}" --dev-type "${DEVTYPE}" --user quicktun elif [ -x /sbin/ip ] && /sbin/ip tuntap 2>&1 >/dev/null; then /sbin/ip tuntap add dev "${IFACE}" mode "${DEVTYPE}" user quicktun elif [ -x /usr/sbin/tunctl ]; then /usr/sbin/tunctl -u quicktun -t "${IFACE}" else echo "Unable to pre-create tun/tap interface. Run QuickTun as root by setting QT_NO_PRECREATE." fi QuickTun-master/deb/static/etc/network/if-post-down.d/0000755000175000017500000000000013043364564022141 5ustar feniofenioQuickTun-master/deb/static/etc/network/if-post-down.d/quicktun0000755000175000017500000000074613043364564023741 0ustar feniofenio#!/bin/sh test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0 test -z "${IF_QT_NO_PRECREATE}" || exit 0 if [ -x /usr/sbin/openvpn ]; then /usr/sbin/openvpn --rmtun --dev "${IFACE}" elif [ -x /sbin/ip ] && /sbin/ip tuntap 2>&1 >/dev/null; then if [ -n "${IF_QT_TUN_MODE}" ] && [ "${IF_QT_TUN_MODE}" = "1" ]; then DEVTYPE="tun" else DEVTYPE="tap" fi /sbin/ip tuntap del dev "${IFACE}" mode "${DEVTYPE}" elif [ -x /usr/sbin/tunctl ]; then /usr/sbin/tunctl -d "${IFACE}" fi QuickTun-master/deb/static/etc/network/if-up.d/0000755000175000017500000000000013043364564020633 5ustar feniofenioQuickTun-master/deb/static/etc/network/if-up.d/quicktun0000755000175000017500000000041413043364564022423 0ustar feniofenio#!/bin/sh test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0 if [ -z "${IF_QT_NO_PRECREATE}" ]; then RUNUSER="quicktun" else RUNUSER="root" fi /usr/bin/daemon -n "quicktun.${IFACE}" -u "${RUNUSER}" -i -l daemon.err -b daemon.debug -o daemon.debug /usr/sbin/quicktun.debian QuickTun-master/deb/static/etc/network/if-down.d/0000755000175000017500000000000013043364564021156 5ustar feniofenioQuickTun-master/deb/static/etc/network/if-down.d/quicktun0000755000175000017500000000031513043364564022746 0ustar feniofenio#!/bin/sh test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0 if [ -z "${IF_QT_NO_PRECREATE}" ]; then RUNUSER="quicktun" else RUNUSER="root" fi daemon -n "quicktun.${IFACE}" -u "${RUNUSER}" --stop QuickTun-master/.hgtags0000644000175000017500000000006013043364564014356 0ustar feniofenioe0bd3a4993c220ee7df6ddc3477edeadd712cbcb V2.2.5 QuickTun-master/clean.sh0000755000175000017500000000007513043364564014527 0ustar feniofenio#!/bin/sh echo Cleaning up... rm -rf out obj debian/data tmp QuickTun-master/version0000644000175000017500000000000613043364564014510 0ustar feniofenio2.2.6