Mercurial > hg > quicktun
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
--- /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