GUARANTEE THAT THERE WILL BE PROTOCOL COMPATIBILITY BETWEEN DIFFERENT
VERSIONS.
-PROTOCOL COMPATIBILITY WAS BROKEN BETWEEN secnet-0.06 AND secnet-0.07
+PROTOCOL COMPATIBILITY WAS BROKEN BETWEEN secnet-0.06, secnet-0.07 AND
+secnet-0.08 FOR ENDIANNESS FIXES.
* Preparation
config file) which has only one device file (usually /dev/net/tun) and
the other (called 'tun-old') which has many device files (/dev/tun*).
Linux-2.4 has new-style TUN, Linux-2.2, BSD and Solaris have old-style
-TUN. Currently only new-style TUN has been tested with secnet.
+TUN.
** System and network configuration
interface). The other will be for secnet itself. These addresses
could possibly be allocated from the range used by your internal
network: if you do this, you should think about providing appropriate
-proxy-ARP on the machine running secnet for the two addresses.
-Alternatively the addresses could be from some other range - this
-works well if the machine running secnet is the default route out of
-your network.
+proxy-ARP on the internal network interface of the machine running
+secnet (eg. add an entry net/ipv4/conf/eth_whatever/proxy_arp = 1 to
+/etc/sysctl.conf on Debian systems and run sysctl -p). Alternatively
+the addresses could be from some other range - this works well if the
+machine running secnet is the default route out of your network.
http://www.ucam.org/cam-grin/ may be useful.
-Advanced users: secnet's IP address does not _have_ to be in the range
-of networks claimed by your end of the tunnel; it could be in the
-range of networks claimed by the other end. Doing this is confusing,
-but works.
-
* Installation
To install secnet do
$ ./configure
$ make
# make install
+
+If installing for the first time, do
+
# mkdir /etc/secnet
# cp example.conf /etc/secnet/secnet.conf
# cd /etc/secnet
# ssh-keygen -f key -N ""
-(When upgrading, just install the new /usr/local/sbin/secnet; keep
-your current configuration file.)
+[On BSD use
+$ LDFLAGS="-L/usr/local/lib" ./configure
+$ gmake CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib"
+XXX this should eventually be worked out automatically by 'configure'.]
Generate a site file fragment for your site (see below), and submit it
for inclusion in the vpn-sites file. Download the vpn-sites file to
.PHONY: all clean realclean dist install
PACKAGE:=secnet
-VERSION:=0.07
+VERSION:=0.08
@SET_MAKE@
INSTALL:=@INSTALL@
INSTALL_PROGRAM:=@INSTALL_PROGRAM@
-CFLAGS:=@CFLAGS@ @DEFS@ -Wall -I.
+CFLAGS:=@CFLAGS@ @DEFS@ -Wall -I$(srcdir) -I.
LDFLAGS:=@LDFLAGS@
LDLIBS:=@LIBS@
example-sites-file example.conf install.sh linux md5.c md5.h \
modules.c modules.h netlink.c random.c resolver.c rsa.c \
secnet.c secnet.h serpent.c serpent.h serpentsboxes.h \
- site.c transform.c udp.c unaligned.h util.c util.h
+ site.c stamp-h.in transform.c udp.c unaligned.h util.c util.h
%.c: %.y
flex -o$@ $<
%.tab.c: %.y
- bison -d $<
+ bison -d -o $@ $<
all: $(TARGETS)
+# Automatic remaking of configuration files, from autoconf documentation
+${srcdir}/configure: configure.in
+ cd ${srcdir} && autoconf
+
+# autoheader might not change config.h.in, so touch a stamp file.
+${srcdir}/config.h.in: stamp-h.in
+${srcdir}/stamp-h.in: configure.in config.h.top config.h.bot
+ cd ${srcdir} && autoheader
+ echo timestamp > ${srcdir}/stamp-h.in
+
+config.h: stamp-h
+stamp-h: config.h.in config.status
+ ./config.status
+
Makefile: Makefile.in config.status
- $(SHELL) config.status
+ ./config.status
config.status: configure
- $(srcdir)/configure --no-create
-
-config.h: config.h.in config.status
- $(SHELL) config.status
+ ./config.status --recheck
+# End of config file remaking rules
+# Manual dependencies section - XXX use autodep eventually
$(OBJECTS): config.h secnet.h util.h
conffile.o conffile.tab.o conffile.yy.o: conffile.h conffile_internal.h
secnet.c: conffile.h
serpent.o: serpentsboxes.h
conffile.o: modules.h
site.c util.c: unaligned.h
+conffile.yy.c: conffile.fl conffile.tab.c
+conffile.tab.c: conffile.y
+# End of manual dependencies section
secnet: $(OBJECTS)
$(INSTALL_PROGRAM) secnet $(sbindir)/`echo secnet|sed '$(transform)'`
clean:
- $(RM) -f $(srcdir)/*.o $(srcdir)/*~ $(srcdir)/*.yy.c \
- $(srcdir)/*.tab.[ch]
+ $(RM) -f *.o *.yy.c *.tab.[ch] $(TARGETS) core version.c
realclean: clean
- $(RM) -f $(TARGETS) $(srcdir)/Makefile $(srcdir)/config.h \
- $(srcdir)/config.log $(srcdir)/config.status $(srcdir)/config.cache \
- $(srcdir)/Makefile.bak core
+ $(RM) -f *~ Makefile config.h \
+ config.log config.status config.cache \
+ stamp-h Makefile.bak
pfname:=$(PACKAGE)-$(VERSION)
dist:
$(RM) -rf $(pfname)
mkdir $(pfname)
- for i in $(DISTFILES) ; do ln -s ../$$i $(pfname)/ ; done
+ for i in $(DISTFILES) ; do ln -s ../$(srcdir)/$$i $(pfname)/ ; done
tar hcf ../$(pfname).tar $(pfname)
gzip -9f ../$(pfname).tar
$(RM) -rf $(pfname)
-
-conffile.yy.c: conffile.fl conffile.tab.c
-conffile.tab.c: conffile.y
conffile.c: done
-dh.c: change format to binary from decimal string
+dh.c: change format to binary from decimal string (without introducing
+endianness problems)
-netlink.c: done. Test tun-old code.
+netlink.c: done. jdamery reports tun-old code works on Linux-2.2
random.c: test
resolver.c: done
rsa.c: check padding type, change format to binary from decimal string
+(without introducing endianness problems)
secnet.c: done
site.c: the site_incoming() routing could be implemented much more
cleanly using a table. There's still quite a lot of redundancy in this
-file.
+file. Abandon key exchanges when a bad packet is received. Tell
+netlink link is down if it's down and we don't have address for other
+end.
-transform.c: done
+transform.c: done. Needs checking for endianness problems.
udp.c: done
util.c: sort out logging
+
+General: check over MBM's patches for BSD.
/* #define DUMP_PARSE_TREE */
+#include "secnet.h"
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-
-#include "secnet.h"
#include "conffile.h"
#include "conffile_internal.h"
#include "util.h"
/* Define if you have the fl library (-lfl). */
#undef HAVE_LIBFL
+/* Define if you have the getopt library (-lgetopt). */
+#undef HAVE_LIBGETOPT
+
+/* Define if you have the gmp library (-lgmp). */
+#undef HAVE_LIBGMP
+
/* Define if you have the gmp2 library (-lgmp2). */
#undef HAVE_LIBGMP2
+
+/* Define if you have the gnugetopt library (-lgnugetopt). */
+#undef HAVE_LIBGNUGETOPT
/* -*- c -*- */
/* These are from config.h.bot, pasted onto the end of config.h.in. */
fi
+echo $ac_n "checking for mpz_init_set_str in -lgmp""... $ac_c" 1>&6
+echo "configure:1260: checking for mpz_init_set_str in -lgmp" >&5
+ac_lib_var=`echo gmp'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lgmp $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1268 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char mpz_init_set_str();
+
+int main() {
+mpz_init_set_str()
+; return 0; }
+EOF
+if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo gmp | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lgmp $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6
-echo "configure:1260: checking for mpz_init_set_str in -lgmp2" >&5
+echo "configure:1307: checking for mpz_init_set_str in -lgmp2" >&5
ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lgmp2 $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1268 "configure"
+#line 1315 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mpz_init_set_str()
; return 0; }
EOF
-if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6
-echo "configure:1307: checking for yywrap in -lfl" >&5
+echo "configure:1354: checking for yywrap in -lfl" >&5
ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lfl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1315 "configure"
+#line 1362 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6
-echo "configure:1354: checking for adns_init in -ladns" >&5
+echo "configure:1401: checking for adns_init in -ladns" >&5
ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-ladns $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1362 "configure"
+#line 1409 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
adns_init()
; return 0; }
EOF
-if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "$ac_t""no" 1>&6
fi
+echo $ac_n "checking for getopt_long in -lgetopt""... $ac_c" 1>&6
+echo "configure:1448: checking for getopt_long in -lgetopt" >&5
+ac_lib_var=`echo getopt'_'getopt_long | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lgetopt $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1456 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+getopt_long()
+; return 0; }
+EOF
+if { (eval echo configure:1467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo getopt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lgetopt $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6
+echo "configure:1495: checking for getopt_long in -lgnugetopt" >&5
+ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lgnugetopt $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1503 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getopt_long();
+
+int main() {
+getopt_long()
+; return 0; }
+EOF
+if { (eval echo configure:1514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo gnugetopt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lgnugetopt $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
trap '' 1 2 15
cat > confcache <<\EOF
EOF
cat >> $CONFIG_STATUS <<\EOF
-
+echo timestamp >stamp-h
exit 0
EOF
chmod +x $CONFIG_STATUS
AC_CHECK_LIB(getopt,getopt_long)
AC_CHECK_LIB(gnugetopt,getopt_long)
-AC_OUTPUT(Makefile)
+AC_OUTPUT(Makefile,echo timestamp >stamp-h)
* Still in the public domain.
*/
-#include <string.h> /* for memcpy() */
-#include <sys/types.h> /* for stupid systems */
-#include <netinet/in.h> /* for ntohl() */
-
#include "secnet.h"
-#include "config.h"
+#include <string.h> /* for memcpy() */
#include "md5.h"
#ifdef WORDS_BIGENDIAN
-#include "config.h"
#include "secnet.h"
extern init_module resolver_module;
packet to the kernel we check that the tunnel it came over could
reasonably have produced it. */
+#include "secnet.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-
-#include "config.h"
-#include "secnet.h"
#include "util.h"
#ifdef HAVE_LINUX_IF_H
/* $Log$
*/
+#include "secnet.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include "secnet.h"
-
struct rgen_data {
closure_t cl;
struct random_if ops;
extern char version[];
+#include "secnet.h"
#include <stdio.h>
#include <string.h>
#include <getopt.h>
-#include <stdarg.h>
#include <errno.h>
-#include <sys/types.h>
+#include <unistd.h>
#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <netinet/in.h>
#include <arpa/inet.h>
-#include <adns.h>
#include <pwd.h>
-#include "secnet.h"
#include "util.h"
#include "conffile.h"
#include <stdarg.h>
#include <syslog.h>
#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/time.h>
#include <netinet/in.h>
-
typedef char *string_t;
typedef enum {False,True} bool_t;
/* site.c - manage communication with a remote network site */
+#include "secnet.h"
#include <stdio.h>
-#include <sys/mman.h>
+/* MBM asserts the next one is needed for compilation under BSD. */
+#include <sys/socket.h>
-#include "secnet.h"
+#include <sys/mman.h>
#include "util.h"
#include "unaligned.h"
#define SITE_SENTMSG5 7
#define SITE_WAIT 8
+#if 0
static string_t state_name(uint32_t state)
{
switch (state) {
default: return "*bad state*";
}
}
+#endif /* 0 */
#define LABEL_MSG0 0x00020200
#define LABEL_MSG1 0x01010101
/* XXX fix this bit for unaligned access */
st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
- *(uint32_t *)&(st->setupsig[0])=LABEL_MSG1;
- *(uint16_t *)&(st->setupsig[4])=htons(strlen(st->remotename));
+ put_uint32(st->setupsig+0,LABEL_MSG1);
+ put_uint16(st->setupsig+4,strlen(st->remotename));
memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
- *(uint16_t *)&(st->setupsig[6+strlen(st->remotename)])=
- htons(strlen(st->localname));
+ put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
strlen(st->localname));
st->setup_priority=(strcmp(st->localname,st->remotename)>0);
/* CBC: each block is XORed with the previous encrypted block (or the IV)
before being encrypted. */
p=iv;
+#ifdef WORDS_BIGENDIAN
+ /* This counters the byteswap() in the first half of the loop, which in
+ turn counters the byteswap() in the second half of the loop. Ick. */
+ iv[0]=byteswap(iv[0]);
+ iv[1]=byteswap(iv[1]);
+ iv[2]=byteswap(iv[2]);
+ iv[3]=byteswap(iv[3]);
+#endif
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
#ifdef WORDS_BIGENDIAN
+ /* Think of this as byteswap(p[x])^byteswap(n[x]) */
n[0]=byteswap(p[0]^n[0]);
n[1]=byteswap(p[1]^n[1]);
n[2]=byteswap(p[2]^n[2]);
n[3]=p[3]^n[3];
#endif
serpent_encrypt(&ti->cryptkey,n,n);
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(n[0]);
+ n[1]=byteswap(n[1]);
+ n[2]=byteswap(n[2]);
+ n[3]=byteswap(n[3]);
+#endif
p=n;
}
buf_prepend_uint32(buf,ti->cryptiv);
ti->cryptiv++;
-
return 0;
}
return 1;
}
+
/* CBC */
memset(iv,0,16);
iv[0]=buf_unprepend_uint32(buf);
+ /* Assert bufsize is multiple of blocksize */
+ if (buf->size&0xf) {
+ *errmsg="msg not multiple of cipher blocksize";
+ }
serpent_encrypt(&ti->cryptkey,iv,iv);
- /* XXX assert bufsize is multiple of blocksize */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(n[0]);
+ n[1]=byteswap(n[1]);
+ n[2]=byteswap(n[2]);
+ n[3]=byteswap(n[3]);
+#endif
pct[0]=n[0]; pct[1]=n[1]; pct[2]=n[2]; pct[3]=n[3];
serpent_decrypt(&ti->cryptkey,n,n);
#ifdef WORDS_BIGENDIAN
* Packets are offered to registered receivers in turn. Once one
* accepts it, it isn't offered to any more. */
+#include "secnet.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
-#include <sys/types.h>
#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include "secnet.h"
#include "util.h"
static beforepoll_fn udp_beforepoll;
*
*/
-#include "config.h"
+#include "secnet.h"
#include <stdio.h>
-#include <stdarg.h>
#include <string.h>
#include <errno.h>
-#include <syslog.h>
#include <unistd.h>
#include <limits.h>
#include <assert.h>
-#include <sys/types.h>
#include <sys/wait.h>
#include "util.h"
-#include "secnet.h"
#include "unaligned.h"
#define MIN_BUFFER_SIZE 64
#ifndef util_h
#define util_h
-#include <stdlib.h>
-#include <stdint.h>
#include "secnet.h"
-#include "config.h"
#include <gmp.h>
extern uint32_t message_level;