changeset 0:65c01f57bdce V2.1.2

Initial commit
author ivo <ivo@UFO-Net.nl>
date Thu, 07 Oct 2010 15:53:01 +0200
parents
children 06be0fd16c60
files build.sh clean.sh debian/build.sh debian/static/DEBIAN/control debian/static/DEBIAN/postinst debian/static/DEBIAN/prerm debian/static/etc/network/if-down.d/quicktun debian/static/etc/network/if-post-down.d/quicktun debian/static/etc/network/if-pre-up.d/quicktun debian/static/etc/network/if-up.d/quicktun include/crypto_box.h include/crypto_box_curve25519salsa20hmacsha512.h include/crypto_box_curve25519xsalsa20poly1305.h lib/libnacl.a src/common.c src/crypto_scalarmult_curve25519.c src/keypair.c src/nacltest.c src/proto.nacl0.c src/proto.nacltai.c src/proto.raw.c src/run.combined.c src/run.debian.c version
diffstat 24 files changed, 1297 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build.sh	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,59 @@
+#!/bin/sh
+echo Cleaning up...
+rm -rf out/ obj/ tmp/
+
+mkdir -p out
+echo Creating source archive...
+tar --transform "s,^\.,quicktun-`cat version`/," -czf "out/quicktun-`cat version`.tgz" . --exclude "./out" --exclude "./lib" --exclude "./debian/data"
+
+mkdir -p obj tmp lib
+
+echo -n Checking for NaCl library...
+if [ ! -e lib/libnacl.a ]; then
+	echo -n building...
+	mkdir tmp/nacl
+	cd tmp/nacl
+	wget -q -O- http://hyperelliptic.org/nacl/nacl-20090405.tar.bz2 | bunzip2 | tar -xf - --strip-components 1
+	./do
+	cd ../../
+	cp tmp/nacl/build/*/lib/*/libnacl.a lib/
+	cp tmp/nacl/build/*/include/*/crypto_box.h include/
+	cp tmp/nacl/build/*/include/*/crypto_box_curve25519salsa20hmacsha512.h include/
+	cp tmp/nacl/build/*/include/*/crypto_box_curve25519xsalsa20poly1305.h include/
+fi
+echo Done.
+
+export CPATH=./include/
+export LIBRARY_PATH=./lib/
+
+echo Building combined binary...
+gcc -c -DCOMBINED_BINARY	src/proto.raw.c		-o obj/proto.raw.o
+gcc -c -DCOMBINED_BINARY	src/crypto_scalarmult_curve25519.c	-o obj/crypto_scalarmult_curve25519.o 
+gcc -c -DCOMBINED_BINARY	src/proto.nacl0.c	-o obj/proto.nacl0.o
+gcc -c -DCOMBINED_BINARY	src/proto.nacltai.c	-o obj/proto.nacltai.o
+gcc -c -DCOMBINED_BINARY	src/run.combined.c	-o obj/run.combined.o
+gcc -c 				src/common.c		-o obj/common.o
+gcc -o out/quicktun.combined obj/common.o obj/run.combined.o obj/proto.raw.o obj/proto.nacl0.o obj/proto.nacltai.o obj/crypto_scalarmult_curve25519.o -lnacl
+
+echo Building single protocol binaries...
+gcc -o out/quicktun.raw		src/proto.raw.c
+gcc -o out/quicktun.nacl0	src/proto.nacl0.c	-lnacl
+gcc -o out/quicktun.nacltai	src/proto.nacltai.c src/crypto_scalarmult_curve25519.c	-lnacl
+gcc -o out/quicktun.keypair	src/keypair.c		-lnacl
+
+echo Building shared libraries...
+gcc -fPIC -shared -Wl,-soname,quicktun.raw -o out/libquicktun.raw src/proto.raw.c
+##gcc -fPIC -shared -Wl,-soname,quicktun.nacl0 -o out/libquicktun.nacl0 src/proto.nacl0.c -lnacl
+
+##echo Building frontends...
+##gcc -o out/quicktun.debian	src/run.debian.c -ldl
+
+if [ -x /usr/bin/dpkg-deb ]; then
+	echo Building debian binary...
+	gcc -c -DCOMBINED_BINARY -DDEBIAN_BINARY src/run.combined.c -o obj/run.debian.o
+	gcc -o out/quicktun.debian obj/common.o obj/run.debian.o obj/proto.raw.o obj/proto.nacl0.o obj/proto.nacltai.o obj/crypto_scalarmult_curve25519.o -lnacl
+	echo -n Building debian package...
+	cd debian
+	./build.sh
+	cd ..
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clean.sh	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+echo Cleaning up...
+rm -r out obj debian/data tmp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/build.sh	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,12 @@
+#!/bin/sh
+VERSION=`cat ../version`-0
+ARCH=`dpkg --print-architecture`
+rm -r data 2>/dev/null
+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
+cp ../out/quicktun.debian data/usr/sbin/
+cp ../out/quicktun.keypair data/usr/sbin/
+fakeroot dpkg-deb --build data quicktun-${VERSION}_${ARCH}.deb
+mv quicktun*.deb ../out/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/DEBIAN/control	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,8 @@
+Package: quicktun
+Version: %VERSION%
+Section: net
+Priority: optional
+Architecture: %ARCHITECTURE%
+Depends: bash, daemon, openvpn, passwd, coreutils
+Maintainer: Ivo Smits <ivo@ucis.nl>
+Description: Very simple, yet secure VPN software
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/DEBIAN/postinst	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,4 @@
+#!/bin/sh
+if [ "$1" = "configure" ]; then
+	/usr/sbin/useradd -d /nonexistent -N -r -s /bin/false quicktun
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/DEBIAN/prerm	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,4 @@
+#!/bin/sh
+if [ "$1" = "upgrade" -o "$1" = "remove" ]; then
+	/usr/sbin/userdel quicktun
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/etc/network/if-down.d/quicktun	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0
+daemon -n "quicktun.${IFACE}" -u quicktun --stop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/etc/network/if-post-down.d/quicktun	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0
+/usr/sbin/openvpn --rmtun --dev "${IFACE}"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/etc/network/if-pre-up.d/quicktun	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0
+/usr/sbin/openvpn --mktun --dev "${IFACE}" --user quicktun
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/static/etc/network/if-up.d/quicktun	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+test -n "${IF_QT_REMOTE_ADDRESS}" || exit 0
+/usr/bin/daemon -n "quicktun.${IFACE}" -u quicktun -i -l daemon.err -b daemon.debug -o daemon.debug /usr/sbin/quicktun.debian
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/crypto_box.h	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,22 @@
+#ifndef crypto_box_H
+#define crypto_box_H
+
+#include "crypto_box_curve25519xsalsa20poly1305.h"
+
+#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_PRIMITIVE "curve25519xsalsa20poly1305"
+#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
+#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/crypto_box_curve25519salsa20hmacsha512.h	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,41 @@
+#ifndef crypto_box_curve25519salsa20hmacsha512_H
+#define crypto_box_curve25519salsa20hmacsha512_H
+
+#define crypto_box_curve25519salsa20hmacsha512_ref_PUBLICKEYBYTES 32
+#define crypto_box_curve25519salsa20hmacsha512_ref_SECRETKEYBYTES 32
+#define crypto_box_curve25519salsa20hmacsha512_ref_BEFORENMBYTES 32
+#define crypto_box_curve25519salsa20hmacsha512_ref_NONCEBYTES 8
+#define crypto_box_curve25519salsa20hmacsha512_ref_ZEROBYTES 32
+#define crypto_box_curve25519salsa20hmacsha512_ref_BOXZEROBYTES 0
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int crypto_box_curve25519salsa20hmacsha512_ref(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519salsa20hmacsha512_ref_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519salsa20hmacsha512_ref_keypair(unsigned char *,unsigned char *);
+extern int crypto_box_curve25519salsa20hmacsha512_ref_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519salsa20hmacsha512_ref_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519salsa20hmacsha512_ref_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#ifdef __cplusplus
+}
+#endif
+
+#define crypto_box_curve25519salsa20hmacsha512 crypto_box_curve25519salsa20hmacsha512_ref
+#define crypto_box_curve25519salsa20hmacsha512_open crypto_box_curve25519salsa20hmacsha512_ref_open
+#define crypto_box_curve25519salsa20hmacsha512_keypair crypto_box_curve25519salsa20hmacsha512_ref_keypair
+#define crypto_box_curve25519salsa20hmacsha512_beforenm crypto_box_curve25519salsa20hmacsha512_ref_beforenm
+#define crypto_box_curve25519salsa20hmacsha512_afternm crypto_box_curve25519salsa20hmacsha512_ref_afternm
+#define crypto_box_curve25519salsa20hmacsha512_open_afternm crypto_box_curve25519salsa20hmacsha512_ref_open_afternm
+#define crypto_box_curve25519salsa20hmacsha512_PUBLICKEYBYTES crypto_box_curve25519salsa20hmacsha512_ref_PUBLICKEYBYTES
+#define crypto_box_curve25519salsa20hmacsha512_SECRETKEYBYTES crypto_box_curve25519salsa20hmacsha512_ref_SECRETKEYBYTES
+#define crypto_box_curve25519salsa20hmacsha512_BEFORENMBYTES crypto_box_curve25519salsa20hmacsha512_ref_BEFORENMBYTES
+#define crypto_box_curve25519salsa20hmacsha512_NONCEBYTES crypto_box_curve25519salsa20hmacsha512_ref_NONCEBYTES
+#define crypto_box_curve25519salsa20hmacsha512_ZEROBYTES crypto_box_curve25519salsa20hmacsha512_ref_ZEROBYTES
+#define crypto_box_curve25519salsa20hmacsha512_BOXZEROBYTES crypto_box_curve25519salsa20hmacsha512_ref_BOXZEROBYTES
+#define crypto_box_curve25519salsa20hmacsha512_IMPLEMENTATION "crypto_box/curve25519salsa20hmacsha512/ref"
+#ifndef crypto_box_curve25519salsa20hmacsha512_ref_VERSION
+#define crypto_box_curve25519salsa20hmacsha512_ref_VERSION "-"
+#endif
+#define crypto_box_curve25519salsa20hmacsha512_VERSION crypto_box_curve25519salsa20hmacsha512_ref_VERSION
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/crypto_box_curve25519xsalsa20poly1305.h	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,41 @@
+#ifndef crypto_box_curve25519xsalsa20poly1305_H
+#define crypto_box_curve25519xsalsa20poly1305_H
+
+#define crypto_box_curve25519xsalsa20poly1305_ref_PUBLICKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_ref_SECRETKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_ref_BEFORENMBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_ref_NONCEBYTES 24
+#define crypto_box_curve25519xsalsa20poly1305_ref_ZEROBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_ref_BOXZEROBYTES 16
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int crypto_box_curve25519xsalsa20poly1305_ref(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_ref_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_ref_keypair(unsigned char *,unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_ref_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_ref_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_ref_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#ifdef __cplusplus
+}
+#endif
+
+#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_ref
+#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_ref_open
+#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_ref_keypair
+#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_ref_beforenm
+#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_ref_afternm
+#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_ref_open_afternm
+#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_ref_PUBLICKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_ref_SECRETKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_ref_BEFORENMBYTES
+#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_ref_NONCEBYTES
+#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ref_ZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_ref_BOXZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/ref"
+#ifndef crypto_box_curve25519xsalsa20poly1305_ref_VERSION
+#define crypto_box_curve25519xsalsa20poly1305_ref_VERSION "-"
+#endif
+#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_ref_VERSION
+
+#endif
Binary file lib/libnacl.a has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,229 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#ifndef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <sys/ioctl.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/if_ether.h>
+#include <poll.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+#define MAX_PACKET_LEN (ETH_FRAME_LEN+4) //Some space for optional packet information
+
+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;
+};
+struct qtsession {
+	struct qtproto protocol;
+	void* protocol_data;
+	int fd_socket;
+	int fd_dev;
+	int remote_float;
+	struct sockaddr_in remote_addr;
+};
+
+#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*, unsigned char*, int);
+#else
+
+char* (*getconf)(const char*) = getenv;
+
+int errorexit(const char* text) {
+	fprintf(stderr, "%s\n", text);
+	return -1;
+}
+int errorexitp(const char* text) {
+	perror(text);
+	return -1;
+}
+
+void print_header() {
+	printf("UCIS QuickTun (c) 2010 Ivo Smits <Ivo@UCIS.nl>\n");
+	printf("More information: http://wiki.qontrol.nl/QuickTun\n");
+}
+
+int init_udp(struct qtsession* session) {
+	char* envval;
+	printf("Initializing UDP socket...\n");
+	int sfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (sfd < 0) return errorexitp("Could not create UDP socket");
+	struct sockaddr_in udpaddr;
+	struct hostent *he;
+	udpaddr.sin_family = AF_INET;
+	udpaddr.sin_addr.s_addr = INADDR_ANY;
+	udpaddr.sin_port = htons(2998);
+	if (envval = getconf("LOCAL_ADDRESS")) {
+		he = gethostbyname(envval);
+		if (!he) return errorexit("bind address lookup failed");
+		else if (!he->h_addr_list[0]) return errorexit("no address to bind to");
+		udpaddr.sin_addr.s_addr = *((unsigned long*)he->h_addr_list[0]);
+		udpaddr.sin_family = he->h_addrtype;
+	}
+	if (envval = getconf("LOCAL_PORT")) {
+		udpaddr.sin_port = htons(atoi(envval));
+	}
+	if (bind(sfd, (struct sockaddr*)&udpaddr, sizeof(struct sockaddr_in))) return errorexitp("Could not bind socket");
+	if (!(envval = getconf("REMOTE_ADDRESS"))) {
+		session->remote_float = 1;
+		//return errorexit("Missing REMOTE_ADDRESS");
+	} else {
+		session->remote_float = 0;
+		he = gethostbyname(envval);
+		if (!he) return errorexit("remote address lookup failed");
+		else if (!he->h_addr_list[0]) return errorexit("no address to connect to");
+		udpaddr.sin_family = he->h_addrtype;
+		udpaddr.sin_addr.s_addr = *((unsigned long*)he->h_addr_list[0]);
+		if (envval = getconf("REMOTE_PORT")) {
+			udpaddr.sin_port = htons(atoi(envval));
+		}
+		if (connect(sfd, (struct sockaddr*)&udpaddr, sizeof(struct sockaddr_in))) return errorexitp("Could not connect socket");
+		session->remote_addr = udpaddr;
+	}
+	session->fd_socket = sfd;
+	return sfd;
+}
+
+int init_tuntap() {
+	char* envval;
+	printf("Initializing tap device...\n");
+	int ttfd; //Tap device file descriptor
+	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 tap device file");
+	if (envval = getconf("INTERFACE")) strcpy(ifr.ifr_name, envval);
+	ifr.ifr_flags = getconf("TUN_MODE") ? IFF_TUN : IFF_TAP;
+	ifr.ifr_flags |= getconf("USE_PI") ? 0 : IFF_NO_PI;
+	if (ioctl(ttfd, TUNSETIFF, (void *)&ifr) < 0) return errorexitp("TUNSETIFF ioctl failed");
+	return ttfd;
+}
+
+void hex2bin(unsigned char* dest, unsigned char* src, 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;
+		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;
+		src++; dest++;
+	}
+}
+
+int qtrun(struct qtproto* p) {
+	struct qtsession session;
+	session.protocol = *p;
+	init_udp(&session);
+	session.fd_dev = init_tuntap();
+
+	char protocol_data[p->protocol_data_size];
+	session.protocol_data = &protocol_data;
+	if (p->init) p->init(&session);
+
+	int sfd = session.fd_socket;
+	int ttfd = session.fd_dev;
+	if (sfd == -1) return -1;
+	if (ttfd == -1) return -1;
+	printf("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;
+
+	struct sockaddr_in recvaddr;
+
+	char buffer_raw_a[p->buffersize_raw];
+	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, -1);
+		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 (fds[0].revents & POLLIN) {
+			if (session.remote_float == 0 || session.remote_float == 2) {
+				len = read(ttfd, buffer_raw + p->offset_raw, p->buffersize_raw);
+				len = p->encode(&session, buffer_raw, buffer_enc, len);
+				if (len < 0) return len;
+				if (session.remote_float == 0) {
+					write(sfd, buffer_enc + p->offset_enc, len);
+				} else {
+					sendto(sfd, buffer_enc + p->offset_enc, len, 0, (struct sockaddr*)&session.remote_addr, sizeof(session.remote_addr));
+				}
+			}
+		}
+		if (fds[1].revents & POLLIN) {
+			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;
+				len = 4;
+				getsockopt(sfd, SOL_SOCKET, SO_ERROR, &out, &len);
+				fprintf(stderr, "End of file on udp socket");
+			} else {
+				len = p->decode(&session, buffer_enc, buffer_raw, len);
+				if (len != 0 && session.remote_float != 0 && (session.remote_addr.sin_addr.s_addr != recvaddr.sin_addr.s_addr || session.remote_addr.sin_port != recvaddr.sin_port)) {
+					fprintf(stderr, "Remote endpoint has changed to %s:%d", inet_ntoa(recvaddr.sin_addr), ntohs(recvaddr.sin_port));
+					session.remote_addr = recvaddr;
+					session.remote_float = 2;
+				}
+				if (len < 0) return len;
+				write(ttfd, buffer_raw + p->offset_raw, len);
+			}
+		}
+	}
+	return 0;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/crypto_scalarmult_curve25519.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,265 @@
+/*
+version 20081011
+Matthew Dempsky
+Public domain.
+Derived from public domain code by D. J. Bernstein.
+*/
+
+//#include "crypto_scalarmult.h"
+
+static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 0;
+  for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; }
+  u += a[31] + b[31]; out[31] = u;
+}
+
+static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 218;
+  for (j = 0;j < 31;++j) {
+    u += a[j] + 65280 - b[j];
+    out[j] = u & 255;
+    u >>= 8;
+  }
+  u += a[31] - b[31];
+  out[31] = u;
+}
+
+static void squeeze(unsigned int a[32])
+{
+  unsigned int j;
+  unsigned int u;
+  u = 0;
+  for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
+  u += a[31]; a[31] = u & 127;
+  u = 19 * (u >> 7);
+  for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
+  u += a[31]; a[31] = u;
+}
+
+static const unsigned int minusp[32] = {
+ 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
+} ;
+
+static void freeze(unsigned int a[32])
+{
+  unsigned int aorig[32];
+  unsigned int j;
+  unsigned int negative;
+
+  for (j = 0;j < 32;++j) aorig[j] = a[j];
+  add(a,a,minusp);
+  negative = -((a[31] >> 7) & 1);
+  for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]);
+}
+
+static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
+{
+  unsigned int i;
+  unsigned int j;
+  unsigned int u;
+
+  for (i = 0;i < 32;++i) {
+    u = 0;
+    for (j = 0;j <= i;++j) u += a[j] * b[i - j];
+    for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j];
+    out[i] = u;
+  }
+  squeeze(out);
+}
+
+static void mult121665(unsigned int out[32],const unsigned int a[32])
+{
+  unsigned int j;
+  unsigned int u;
+
+  u = 0;
+  for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; }
+  u += 121665 * a[31]; out[31] = u & 127;
+  u = 19 * (u >> 7);
+  for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; }
+  u += out[j]; out[j] = u;
+}
+
+static void square(unsigned int out[32],const unsigned int a[32])
+{
+  unsigned int i;
+  unsigned int j;
+  unsigned int u;
+
+  for (i = 0;i < 32;++i) {
+    u = 0;
+    for (j = 0;j < i - j;++j) u += a[j] * a[i - j];
+    for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j];
+    u *= 2;
+    if ((i & 1) == 0) {
+      u += a[i / 2] * a[i / 2];
+      u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
+    }
+    out[i] = u;
+  }
+  squeeze(out);
+}
+
+static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b)
+{
+  unsigned int j;
+  unsigned int t;
+  unsigned int bminus1;
+
+  bminus1 = b - 1;
+  for (j = 0;j < 64;++j) {
+    t = bminus1 & (r[j] ^ s[j]);
+    p[j] = s[j] ^ t;
+    q[j] = r[j] ^ t;
+  }
+}
+
+static void mainloop(unsigned int work[64],const unsigned char e[32])
+{
+  unsigned int xzm1[64];
+  unsigned int xzm[64];
+  unsigned int xzmb[64];
+  unsigned int xzm1b[64];
+  unsigned int xznb[64];
+  unsigned int xzn1b[64];
+  unsigned int a0[64];
+  unsigned int a1[64];
+  unsigned int b0[64];
+  unsigned int b1[64];
+  unsigned int c1[64];
+  unsigned int r[32];
+  unsigned int s[32];
+  unsigned int t[32];
+  unsigned int u[32];
+  unsigned int i;
+  unsigned int j;
+  unsigned int b;
+  int pos;
+
+  for (j = 0;j < 32;++j) xzm1[j] = work[j];
+  xzm1[32] = 1;
+  for (j = 33;j < 64;++j) xzm1[j] = 0;
+
+  xzm[0] = 1;
+  for (j = 1;j < 64;++j) xzm[j] = 0;
+
+  for (pos = 254;pos >= 0;--pos) {
+    b = e[pos / 8] >> (pos & 7);
+    b &= 1;
+    select(xzmb,xzm1b,xzm,xzm1,b);
+    add(a0,xzmb,xzmb + 32);
+    sub(a0 + 32,xzmb,xzmb + 32);
+    add(a1,xzm1b,xzm1b + 32);
+    sub(a1 + 32,xzm1b,xzm1b + 32);
+    square(b0,a0);
+    square(b0 + 32,a0 + 32);
+    mult(b1,a1,a0 + 32);
+    mult(b1 + 32,a1 + 32,a0);
+    add(c1,b1,b1 + 32);
+    sub(c1 + 32,b1,b1 + 32);
+    square(r,c1 + 32);
+    sub(s,b0,b0 + 32);
+    mult121665(t,s);
+    add(u,t,b0);
+    mult(xznb,b0,b0 + 32);
+    mult(xznb + 32,s,u);
+    square(xzn1b,c1);
+    mult(xzn1b + 32,r,work);
+    select(xzm,xzm1,xznb,xzn1b,b);
+  }
+
+  for (j = 0;j < 64;++j) work[j] = xzm[j];
+}
+
+static void recip(unsigned int out[32],const unsigned int z[32])
+{
+  unsigned int z2[32];
+  unsigned int z9[32];
+  unsigned int z11[32];
+  unsigned int z2_5_0[32];
+  unsigned int z2_10_0[32];
+  unsigned int z2_20_0[32];
+  unsigned int z2_50_0[32];
+  unsigned int z2_100_0[32];
+  unsigned int t0[32];
+  unsigned int t1[32];
+  int i;
+
+  /* 2 */ square(z2,z);
+  /* 4 */ square(t1,z2);
+  /* 8 */ square(t0,t1);
+  /* 9 */ mult(z9,t0,z);
+  /* 11 */ mult(z11,z9,z2);
+  /* 22 */ square(t0,z11);
+  /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9);
+
+  /* 2^6 - 2^1 */ square(t0,z2_5_0);
+  /* 2^7 - 2^2 */ square(t1,t0);
+  /* 2^8 - 2^3 */ square(t0,t1);
+  /* 2^9 - 2^4 */ square(t1,t0);
+  /* 2^10 - 2^5 */ square(t0,t1);
+  /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0);
+
+  /* 2^11 - 2^1 */ square(t0,z2_10_0);
+  /* 2^12 - 2^2 */ square(t1,t0);
+  /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0);
+
+  /* 2^21 - 2^1 */ square(t0,z2_20_0);
+  /* 2^22 - 2^2 */ square(t1,t0);
+  /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0);
+
+  /* 2^41 - 2^1 */ square(t1,t0);
+  /* 2^42 - 2^2 */ square(t0,t1);
+  /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); }
+  /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0);
+
+  /* 2^51 - 2^1 */ square(t0,z2_50_0);
+  /* 2^52 - 2^2 */ square(t1,t0);
+  /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0);
+
+  /* 2^101 - 2^1 */ square(t1,z2_100_0);
+  /* 2^102 - 2^2 */ square(t0,t1);
+  /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); }
+  /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0);
+
+  /* 2^201 - 2^1 */ square(t0,t1);
+  /* 2^202 - 2^2 */ square(t1,t0);
+  /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
+  /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0);
+
+  /* 2^251 - 2^1 */ square(t1,t0);
+  /* 2^252 - 2^2 */ square(t0,t1);
+  /* 2^253 - 2^3 */ square(t1,t0);
+  /* 2^254 - 2^4 */ square(t0,t1);
+  /* 2^255 - 2^5 */ square(t1,t0);
+  /* 2^255 - 21 */ mult(out,t1,z11);
+}
+
+int crypto_scalarmult(unsigned char *q,
+  const unsigned char *n,
+  const unsigned char *p)
+{
+  unsigned int work[96];
+  unsigned char e[32];
+  unsigned int i;
+  for (i = 0;i < 32;++i) e[i] = n[i];
+  e[0] &= 248;
+  e[31] &= 127;
+  e[31] |= 64;
+  for (i = 0;i < 32;++i) work[i] = p[i];
+  mainloop(work,e);
+  recip(work + 32,work + 32);
+  mult(work + 64,work,work + 32);
+  freeze(work + 64);
+  for (i = 0;i < 32;++i) q[i] = work[64 + i];
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/keypair.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,54 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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.h"
+#include <time.h>
+
+int main() {
+	print_header();
+
+	unsigned char cpublickey[crypto_box_PUBLICKEYBYTES];
+	unsigned char csecretkey[crypto_box_SECRETKEYBYTES];
+	int i;
+
+	crypto_box_keypair(cpublickey, csecretkey);
+
+	printf("SECRET: ");
+	for (i = 0; i < crypto_box_SECRETKEYBYTES; i++) printf("%02x", csecretkey[i]);
+	printf("\n");
+
+	printf("PUBLIC: ");
+	for (i = 0; i < crypto_box_SECRETKEYBYTES; i++) printf("%02x", csecretkey[i]);
+	printf("\n");
+
+	return 0;
+}
+
+void randombytes(char* bytes) {
+	char* b;
+	srand(time(NULL));
+	for (b = bytes; b < bytes + crypto_box_SECRETKEYBYTES; b++) *b = rand() % 255;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nacltest.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,30 @@
+#include "crypto_box.h"
+
+int main() {
+	unsigned char n[crypto_box_NONCEBYTES];
+	unsigned char m[32+crypto_box_ZEROBYTES];
+	unsigned char c[32+crypto_box_ZEROBYTES];
+
+	unsigned char pk[crypto_box_PUBLICKEYBYTES];
+	unsigned char sk[crypto_box_SECRETKEYBYTES];
+	//crypto_box_keypair(pk, sk);
+	//randombytes(sk,32);
+	sk[0]=1;
+	crypto_scalarmult_curve25519_base(pk,sk);
+
+
+	int r;
+
+	unsigned char* buffer1offset = m + crypto_box_ZEROBYTES;
+
+	strcpy(buffer1offset, "hello world");
+	printf("in=$s\n", buffer1offset);
+	memset(m, 0, crypto_box_ZEROBYTES);
+	r=crypto_box(c, m, 32+crypto_box_ZEROBYTES, n, pk, sk);
+	printf("ret=%d\n", r);
+
+	memset(c, 0, crypto_box_BOXZEROBYTES);
+	r=crypto_box_open(m, c, 32+crypto_box_ZEROBYTES, n, pk, sk);
+	printf("ret=%d\n", r);
+	printf("out=$s\n", buffer1offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto.nacl0.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,101 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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.h"
+
+struct qt_proto_data_nacl0 {
+	unsigned char cnonce[crypto_box_NONCEBYTES], cbefore[crypto_box_BEFORENMBYTES];
+};
+
+/*static unsigned char cnonce[crypto_box_NONCEBYTES], cbefore[crypto_box_BEFORENMBYTES];
+static unsigned char buffer1[MAX_PACKET_LEN+crypto_box_ZEROBYTES], buffer2[MAX_PACKET_LEN+crypto_box_ZEROBYTES];
+static const unsigned char* buffer1offset = buffer1 + crypto_box_ZEROBYTES;
+static const unsigned char* buffer2offset = buffer2 + crypto_box_BOXZEROBYTES;
+static const int overhead                 = crypto_box_BOXZEROBYTES;*/
+
+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_ZEROBYTES);
+	if (crypto_box_afternm(enc, raw, len+crypto_box_ZEROBYTES, d->cnonce, d->cbefore)) return errorexit("Crypto failed");
+	return len + crypto_box_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;
+	int i;
+	if (len < crypto_box_BOXZEROBYTES) {
+		fprintf(stderr, "Short packet received: %d\n", len);
+		return 0;
+	}
+	len -= crypto_box_BOXZEROBYTES;
+	memset(enc, 0, crypto_box_BOXZEROBYTES);
+	if (i = crypto_box_open_afternm(raw, enc, len+crypto_box_ZEROBYTES, d->cnonce, d->cbefore)) {
+		fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i);
+		return 0;
+	}
+	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_NONCEBYTES);
+	unsigned char cpublickey[crypto_box_PUBLICKEYBYTES], csecretkey[crypto_box_SECRETKEYBYTES];
+	if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY");
+	if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length");
+	hex2bin(cpublickey, envval, crypto_box_PUBLICKEYBYTES);
+	if (!(envval = getconf("PRIVATE_KEY"))) return errorexit("Missing PRIVATE_KEY");
+	if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length");
+	hex2bin(csecretkey, envval, crypto_box_SECRETKEYBYTES);
+	crypto_box_beforenm(d->cbefore, cpublickey, csecretkey);
+}
+
+#ifdef COMBINED_BINARY
+	int tunmain_nacl0() {
+#else
+	int tunmain() {
+#endif
+	struct qtproto p = {
+		1,
+		MAX_PACKET_LEN + crypto_box_ZEROBYTES,
+		MAX_PACKET_LEN + crypto_box_BOXZEROBYTES + crypto_box_BOXZEROBYTES,
+		crypto_box_ZEROBYTES,
+		crypto_box_BOXZEROBYTES,
+		encode,
+		decode,
+		init,
+		sizeof(struct qt_proto_data_nacl0),
+	};
+	return qtrun(&p);
+}
+
+#ifndef COMBINED_BINARY
+int main() {
+	print_header();
+	return tunmain();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto.nacltai.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,211 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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.h"
+#include <sys/types.h>
+#include <sys/time.h>
+
+#define uint64 unsigned long long //typedef unsigned long long uint64;
+
+struct tai {
+  uint64 x;
+};
+struct taia {
+  struct tai sec;
+  unsigned long nano; /* 0...999999999 */
+  unsigned long atto; /* 0...999999999 */
+};
+
+struct qt_proto_data_nacltai {
+	unsigned char cenonce[crypto_box_NONCEBYTES], cdnonce[crypto_box_NONCEBYTES];
+	unsigned char cbefore[crypto_box_BEFORENMBYTES];
+	struct taia cdtaip, cdtaic;
+};
+
+#define noncelength sizeof(struct taia)
+#define nonceoffset (crypto_box_NONCEBYTES - noncelength)
+/*static unsigned char cbefore[crypto_box_BEFORENMBYTES];
+static unsigned char buffer1[MAX_PACKET_LEN+crypto_box_ZEROBYTES], buffer2[MAX_PACKET_LEN+crypto_box_ZEROBYTES];
+static const unsigned char* buffer1offset = buffer1 + crypto_box_ZEROBYTES;
+static const unsigned char* buffer2offset = buffer2 + crypto_box_BOXZEROBYTES - noncelength;*/
+static const int overhead                 = crypto_box_BOXZEROBYTES + noncelength;
+
+void tai_pack(char *s, struct tai *t) {
+  uint64 x;
+  x = t->x;
+  s[7] = x & 255; x >>= 8;
+  s[6] = x & 255; x >>= 8;
+  s[5] = x & 255; x >>= 8;
+  s[4] = x & 255; x >>= 8;
+  s[3] = x & 255; x >>= 8;
+  s[2] = x & 255; x >>= 8;
+  s[1] = x & 255; x >>= 8;
+  s[0] = x;
+}
+void tai_unpack(char *s, struct tai *t) {
+  uint64 x;
+  x = (unsigned char) s[0];
+  x <<= 8; x += (unsigned char) s[1];
+  x <<= 8; x += (unsigned char) s[2];
+  x <<= 8; x += (unsigned char) s[3];
+  x <<= 8; x += (unsigned char) s[4];
+  x <<= 8; x += (unsigned char) s[5];
+  x <<= 8; x += (unsigned char) s[6];
+  x <<= 8; x += (unsigned char) s[7];
+  t->x = x;
+}
+void taia_pack(char *s, struct taia *t) {
+  unsigned long x;
+  tai_pack(s,&t->sec);
+  s += 8;
+  x = t->atto;
+  s[7] = x & 255; x >>= 8;
+  s[6] = x & 255; x >>= 8;
+  s[5] = x & 255; x >>= 8;
+  s[4] = x;
+  x = t->nano;
+  s[3] = x & 255; x >>= 8;
+  s[2] = x & 255; x >>= 8;
+  s[1] = x & 255; x >>= 8;
+  s[0] = x;
+} 
+void taia_unpack(char *s, struct taia *t) {
+  unsigned long x;
+  tai_unpack(s,&t->sec);
+  s += 8;
+  x = (unsigned char) s[4];
+  x <<= 8; x += (unsigned char) s[5];
+  x <<= 8; x += (unsigned char) s[6];
+  x <<= 8; x += (unsigned char) s[7];
+  t->atto = x;
+  x = (unsigned char) s[0];
+  x <<= 8; x += (unsigned char) s[1];
+  x <<= 8; x += (unsigned char) s[2];
+  x <<= 8; x += (unsigned char) s[3];
+  t->nano = x;
+}
+
+void taia_now(struct taia *t) {
+  struct timeval now;
+  gettimeofday(&now,(struct timezone *) 0);
+  t->sec.x = 4611686018427387914ULL + (uint64) now.tv_sec;
+  t->nano = 1000 * now.tv_usec + 500;
+  t->atto = 0;
+}
+
+extern crypto_scalarmult_curve25519_base(unsigned char *pk, unsigned char *sk);
+
+static int encode(struct qtsession* sess, char* raw, char* enc, int len) {
+	struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data;
+	memset(raw, 0, crypto_box_ZEROBYTES);
+	taia_now(&d->cdtaic);
+	taia_pack(d->cenonce + nonceoffset, &(d->cdtaic));
+	if (crypto_box_afternm(enc, raw, len + crypto_box_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Crypto failed");
+	memcpy((void*)(enc + crypto_box_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength);
+	len += overhead;
+	return len;
+}
+
+static int decode(struct qtsession* sess, char* enc, char* raw, int len) {
+	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 0;
+	}
+	len -= overhead;
+	taia_unpack((char*)(enc + crypto_box_BOXZEROBYTES - noncelength), &(d->cdtaic));
+	if (d->cdtaic.sec.x <= d->cdtaip.sec.x || d->cdtaic.nano <= d->cdtaip.nano || d->cdtaic.atto <= d->cdtaip.atto) { 
+		fprintf(stderr, "Timestamp going back, ignoring packet\n");
+		return 0;
+	}
+	memcpy(d->cdnonce + nonceoffset, enc + crypto_box_BOXZEROBYTES - noncelength, noncelength);
+	memset(enc, 0, crypto_box_BOXZEROBYTES);
+	if (i = crypto_box_open_afternm(raw, enc, len + crypto_box_ZEROBYTES, d->cdnonce, d->cbefore)) {
+		fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i);
+		return 0;
+	}
+	d->cdtaip = d->cdtaic;
+	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_PUBLICKEYBYTES], cpublickey[crypto_box_PUBLICKEYBYTES], csecretkey[crypto_box_SECRETKEYBYTES];
+	if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY");
+	if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length");
+	hex2bin(cpublickey, envval, crypto_box_PUBLICKEYBYTES);
+	if (!(envval = getconf("PRIVATE_KEY"))) return errorexit("Missing PRIVATE_KEY");
+	if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length");
+	hex2bin(csecretkey, envval, crypto_box_SECRETKEYBYTES);
+	crypto_box_beforenm(d->cbefore, cpublickey, csecretkey);
+
+	memset(d->cenonce, 0, crypto_box_NONCEBYTES);
+	memset(d->cdnonce, 0, crypto_box_NONCEBYTES);
+
+	crypto_scalarmult(cownpublickey, csecretkey);
+
+	if (envval = getenv("TIME_WINDOW")) {
+		taia_now(&d->cdtaip);
+		d->cdtaip.sec.x -= atol(envval);
+	} else {
+		printf("Warning: TIME_WINDOW not set, risking an initial replay attack\n");
+	}
+	if (envval = getenv("ROLE")) {
+		d->cenonce[nonceoffset-1] = atoi(envval) ? 1 : 0;
+	} else {
+		d->cenonce[nonceoffset-1] = memcmp(cpublickey, cownpublickey, crypto_box_PUBLICKEYBYTES) ? 1 : 0;
+	}
+	d->cdnonce[nonceoffset-1] = d->cenonce[nonceoffset-1] ? 0 : 1;
+}
+
+#ifdef COMBINED_BINARY
+	int tunmain_nacltai() {
+#else
+	int tunmain() {
+#endif
+	struct qtproto p = {
+		1,
+		MAX_PACKET_LEN + crypto_box_ZEROBYTES,
+		MAX_PACKET_LEN + crypto_box_ZEROBYTES,
+		crypto_box_ZEROBYTES,
+		crypto_box_BOXZEROBYTES - noncelength,
+		encode,
+		decode,
+		init,
+		sizeof(struct qt_proto_data_nacltai),
+	};
+	return qtrun(&p);
+}
+
+#ifndef COMBINED_BINARY
+int main() {
+	print_header();
+	return tunmain();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/proto.raw.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,62 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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;
+}
+
+#ifdef COMBINED_BINARY
+	int tunmain_raw() {
+#else
+	int tunmain() {
+#endif
+	struct qtproto p = {
+		0,
+		MAX_PACKET_LEN,
+		MAX_PACKET_LEN,
+		0,
+		0,
+		decode,
+		encode,
+		NULL,
+		0,
+	};
+	return qtrun(&p);
+}
+
+#ifndef COMBINED_BINARY
+int main() {
+	print_header();
+	return tunmain();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/run.combined.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,65 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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"
+
+#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() {
+	print_header();
+#ifdef DEBIAN_BINARY
+	getconf = getenvdeb;
+#else
+	getconf = getenv;
+#endif
+	char* envval;
+	if (envval = getconf("PROTOCOL")) {
+		if (strcmp(envval, "raw") == 0) {
+			return tunmain_raw();
+		} else if (strcmp(envval, "nacl0") == 0) {
+			return tunmain_nacl0();
+		} else if (strcmp(envval, "nacltai") == 0) {
+			return tunmain_nacltai();
+		} else {
+			fprintf(stderr, "Unknown protocol specified: %s\n", envval);
+			return -1;
+		}
+	} else if (getconf("PRIVATE_KEY")) {
+		return tunmain_nacl0();
+	} else {
+		return tunmain_raw();
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/run.debian.c	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,73 @@
+/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+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);
+}
+
+int main() {
+	/* Header */
+	printf("UCIS QuickTun (c) 2010 Ivo Smits <Ivo@UCIS.nl>\n");
+	printf("More information: http://wiki.qontrol.nl/QuickTun\n");
+
+	char* lib = NULL;
+	if (getenvdeb("PRIVATE_KEY")) {
+		lib = "libquicltun.nacl0";
+	} else {
+		lib = "libquicltun.raw";
+	}
+
+	void* dl = dlopen(lib, RTLD_LAZY);
+	if (!dl) {
+		fprintf(stderr, "Error: library %s not found: %s\n", lib, dlerror());
+		return -1;
+	}
+	void** getconfig = dlsym(dl, "getconf");
+	if (!dl) {
+		fprintf(stderr, "Error: symbol getconf not found: %s\n", dlerror());
+		return -1;
+	}
+	void* tunmain = dlsym(dl, "tunmain");
+	if (!dl) {
+		fprintf(stderr, "Error: symbol tunmain not found: %s\n", dlerror());
+		return -1;
+	}
+
+	*getconfig = (void*)getenvdeb;
+	((void (*)())tunmain)();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/version	Thu Oct 07 15:53:01 2010 +0200
@@ -0,0 +1,1 @@
+2.1.2