Bring head revision up to date with cabal (try #3)

This commit is contained in:
Ivo Timmermans 2000-10-18 20:12:10 +00:00
parent d3ea434b36
commit 30df5e95db
35 changed files with 3091 additions and 2267 deletions

View file

@ -5,5 +5,3 @@ Ivo Timmermans <itimmermans@bigfoot.com>
These files are from other sources: These files are from other sources:
* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from * lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from
the syslog 1.3 sources. the syslog 1.3 sources.
* The files in cipher/blowfish/ are from the SSLeay package by
Eric Young.

View file

@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu
SUBDIRS = m4 intl lib cipher src doc po redhat debian SUBDIRS = m4 intl lib src doc po redhat debian
ACLOCAL_AMFLAGS = ACLOCAL_AMFLAGS =
@ -16,7 +16,7 @@ ChangeLog:
rm -f ChangeLog rm -f ChangeLog
rcs2log -u "zarq Ivo Timmermans itimmermans@bigfoot.com" \ rcs2log -u "zarq Ivo Timmermans itimmermans@bigfoot.com" \
-u "guus Guus Sliepen guus@sliepen.warande.net" | \ -u "guus Guus Sliepen guus@sliepen.warande.net" | \
sed -e 's,/home/CVS/tinc/cabal/,,g' > $@ sed -e 's,/home/CVS/tinc/,,g' > $@
cvs-clean: maintainer-clean cvs-clean: maintainer-clean
for f in $(CVS_CREATED) `find -name Makefile.in` ; do\ for f in $(CVS_CREATED) `find -name Makefile.in` ; do\
@ -25,3 +25,9 @@ cvs-clean: maintainer-clean
deb: deb:
dpkg-buildpackage -rfakeroot dpkg-buildpackage -rfakeroot
rpm: dist
cp $(distdir).tar.gz /usr/src/redhat/SOURCES/
cp redhat/tinc.spec /usr/src/redhat/SOURCES/
cd /usr/src/redhat/SOURCES/
rpm -bi tinc.spec

21
README
View file

@ -4,17 +4,26 @@ Installation instructions may be found in the INSTALL file.
tinc is Copyright (C) 1998,1999,2000 Ivo Timmermans tinc is Copyright (C) 1998,1999,2000 Ivo Timmermans
<itimmermans@bigfoot.com>, Guus Sliepen <guus@sliepen.warande.net> and <itimmermans@bigfoot.com>, Guus Sliepen <guus@sliepen.warande.net> and
others. For a complete list of authors see the AUTHORS file. others. For a complete list of authors see the AUTHORS file.
This product includes software developed by Eric Young (eay@mincom.oz.au)
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at the Free Software Foundation; either version 2 of the License, or (at
your option) any later version. See the file COPYING for more details. your option) any later version. See the file COPYING for more details.
This version of tinc relies on the GNU Multi-Precision Library
(gmp). This library is available from your nearest GNU mirror. Please Requirements
install this first even before trying to run configure. If you don't ------------
do this, configure will (hopefully) mention it to you.
Since 1.0pre3, we use OpenSSL for all cryptographic functions. So you
need to install this library first; grab it from
http://www.openssl.org/. We recommend version 0.9.5 or better. If
this library is not installed on you system, configure will fail. The
manual in doc/tinc.texi contains more detailed information on how to
install this library.
Features
--------
This version of tinc supports multiple virtual networks at once. To This version of tinc supports multiple virtual networks at once. To
use this feature, you may supply a netname via the -n or --net use this feature, you may supply a netname via the -n or --net
@ -29,7 +38,7 @@ In this version, MAC addresses are stripped off before encoding and
sending a packet. When the packet reaches its destination, the MAC sending a packet. When the packet reaches its destination, the MAC
addresses are rebuilt again. They then have the form addresses are rebuilt again. They then have the form
FE:FD:aa:bb:cc:dd. aa, bb, cc and dd are taken from the destination FE:FD:aa:bb:cc:dd. aa, bb, cc and dd are taken from the destination
and source IP address. and source IP address. See the manual for more detailed information.
tincd regenerates its encryption key pairs. It does this on the first tincd regenerates its encryption key pairs. It does this on the first
activity after the keys have expired. This period is adjustable in the activity after the keys have expired. This period is adjustable in the

18
THANKS
View file

@ -2,19 +2,19 @@ I would like to thank
* Hans Bayle (for making some useful coding suggestions and fixing a * Hans Bayle (for making some useful coding suggestions and fixing a
bug or two) bug or two)
* Lubomír Bulej (for the Redhat system init script)
* Wessel Dankers (for the name `tinc' and various suggestions)
* Mads Kiilerich (for finding some bugs and some errors in the * Mads Kiilerich (for finding some bugs and some errors in the
documentation, and for making several suggestions to make it all documentation, and for making several suggestions to make it all
more userfriendly) more userfriendly, and the Redhat package)
* James B. MacLean (for fixing several mission critical bugs, and for * James MacLean (for fixing several mission critical bugs, and for
giving me a few good ideas, and, most of all, for the wonderful giving me a few good ideas, and, most of all, for the wonderful
testing and debugging) testing and debugging)
* Cris van Pelt * Robert van der Meulen (early configuration code)
* Robert van der Meulen * Cris van Pelt (small fixes)
* Sander Smeenk * Enrique Zanardi (for the Spanish translation)
* Tijs van Bakel * Matias Carrasco (for the Spanish translation of the manual)
* Wessel Dankers (for the name `tinc' and being a royal pain in the
ass (je hebt erom gevraagd))
for their help, support and ideas. Thank you guys! for their help, support and ideas. Thank you guys!
And especially Guus Sliepen, for starting this whole project... And especially Guus Sliepen, for starting this whole project...

2
TODO
View file

@ -5,3 +5,5 @@ Things left to do to make cabal superstable:
tree property. tree property.
* Redundancy: multiple ConnectTo lines, if * Redundancy: multiple ConnectTo lines, if
one fails others might be tried. one fails others might be tried.
* Allow connects to hosts that use
nodirectdata.

View file

@ -43,3 +43,13 @@
# include <stdlib.h> # include <stdlib.h>
# undef getopt # undef getopt
#endif #endif
/* Define to the location of the kernel sources */
#undef CONFIG_TINC_KERNELDIR
/* Define to 1 if tun/tap support is enabled and found */
#undef HAVE_TUNTAP
/* Define to the location of if_tun.h */
#undef LINUX_IF_TUN_H

View file

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl $Id: configure.in,v 1.14 2000/06/25 15:42:40 zarq Exp $ dnl $Id: configure.in,v 1.15 2000/10/18 20:12:06 zarq Exp $
AC_INIT(src/tincd.c) AC_INIT(src/tincd.c)
AM_INIT_AUTOMAKE(tinc, 1.0pre3) AM_INIT_AUTOMAKE(tinc, 1.0pre3)
@ -14,7 +14,7 @@ AM_ACLOCAL_INCLUDE(m4)
# in the latter don't make it into the configure-time tests. # in the latter don't make it into the configure-time tests.
AC_DEFINE([_GNU_SOURCE], [__USE_BSD]) AC_DEFINE([_GNU_SOURCE], [__USE_BSD])
ALL_LINGUAS="nl" ALL_LINGUAS="es nl"
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
@ -33,8 +33,7 @@ dnl Checks for libraries.
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h syslog.h unistd.h gmp.h gmp2/gmp.h \ AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h syslog.h unistd.h sys/time.h linux/if_tun.h)
sys/time.h)
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
@ -53,32 +52,38 @@ jm_FUNC_REALLOC
AM_GNU_GETTEXT AM_GNU_GETTEXT
# Check for the GNU Multi Precision Library
libgmp=none
AC_CHECK_LIB(gmp, mpz_powm, [
libgmp=gmp
])
AC_CHECK_LIB(gmp2, mpz_powm, [
libgmp=gmp2
])
AC_CHECK_LIB(gmp3, __gmpz_powm, [
libgmp=gmp3
])
AC_CHECK_LIB(gmp, __gmpz_powm, [
libgmp=gmp
])
if test $libgmp = none; then
AC_MSG_ERROR(libgmp is not installed. Please grab it from your
nearest GNU mirror and install it (see README))
else
LIBS="$LIBS -l$libgmp"
fi
AC_CHECK_LIB(dl, dlopen, [ AC_CHECK_LIB(dl, dlopen, [
LIBS="$LIBS -ldl" LIBS="$LIBS -ldl"
]) ])
AC_OUTPUT([Makefile src/Makefile cipher/Makefile
cipher/blowfish/Makefile doc/Makefile intl/Makefile lib/Makefile dnl Crypto stuff
libcrypto=none
AC_CHECK_LIB(crypto, SHA1_version, [
libcrypto=yes
])
if test $libcrypto = none; then
AC_MSG_ERROR(It seems like OpenSSL is not installed on this system.)
else
LIBS="$LIBS -lcrypto"
fi
dnl Support for SunOS
AC_CHECK_FUNC(socket, [], [
AC_CHECK_LIB(socket, connect)
])
AC_CHECK_FUNC(gethostbyname, [], [
AC_CHECK_LIB(nsl, gethostbyname)
])
dnl Check for TUN/TAP support in the kernel
tinc_TUNTAP
AC_OUTPUT([Makefile src/Makefile
doc/Makefile doc/es/Makefile intl/Makefile lib/Makefile
m4/Makefile po/Makefile.in redhat/Makefile debian/Makefile]) m4/Makefile po/Makefile.in redhat/Makefile debian/Makefile])

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
tinc (1.0pre3-0.1) unstable; urgency=low
* upgraded to upstream version 1.0pre3
-- Ivo Timmermans <itimmermans@bigfoot.com> Sun, 25 Jun 2000 00:00:00 +0200
tinc (1.0pre2-1) unstable; urgency=low tinc (1.0pre2-1) unstable; urgency=low
* postinst creates a file /etc/tinc/nets.boot, containing all networks * postinst creates a file /etc/tinc/nets.boot, containing all networks

4
debian/control vendored
View file

@ -3,11 +3,11 @@ Section: non-US/main
Priority: optional Priority: optional
Maintainer: Ivo Timmermans <itimmermans@bigfoot.com> Maintainer: Ivo Timmermans <itimmermans@bigfoot.com>
Standards-Version: 3.0.1 Standards-Version: 3.0.1
Build-Depends: libc6-dev, libgmp2-dev Build-Depends: libc6-dev, libssl095a-dev, autoconf (>= 2.12), automake,
Package: tinc Package: tinc
Architecture: i386 Architecture: i386
Depends: ${shlibs:Depends}, libgmp2, perl5 Depends: ${shlibs:Depends}, (libssl095a|libssl09), perl5
Description: Virtual Private Network daemon Description: Virtual Private Network daemon
tinc is a daemon with which you can create a virtual private network tinc is a daemon with which you can create a virtual private network
(VPN). One daemon can handle multiple connections, so you can (VPN). One daemon can handle multiple connections, so you can

7
debian/init.d vendored
View file

@ -1,7 +1,7 @@
#! /usr/bin/perl -w #! /usr/bin/perl -w
# #
# System startup script for tinc # System startup script for tinc
# $Id: init.d,v 1.14 2000/06/01 20:21:27 guus Exp $ # $Id: init.d,v 1.15 2000/10/18 20:12:06 zarq Exp $
# #
# Based on Lubomir Bulej's Redhat init script. # Based on Lubomir Bulej's Redhat init script.
# #
@ -68,6 +68,7 @@ sub vpn_load {
chomp($VPN); chomp($VPN);
} elsif ( /^[ ]*VpnMask[ =]+([^ \#]+)/i ) { } elsif ( /^[ ]*VpnMask[ =]+([^ \#]+)/i ) {
$VPNMASK=$1; $VPNMASK=$1;
chomp($VPNMASK);
} }
} }
if(!defined($DEV)) { if(!defined($DEV)) {
@ -108,10 +109,8 @@ sub vpn_load {
if(!defined($VPNMASK)) { if(!defined($VPNMASK)) {
$VPNMASK = $MSK; $VPNMASK = $MSK;
$VPNMASK = join(".", unpack('C4', $VPNMASK));
} }
$VPNMASK = pack('C4', split(/\./, $VPNMASK));
$VPNMASK = join(".", unpack('C4', $VPNMASK));
$ADR = join(".", unpack('C4', $ADR)); $ADR = join(".", unpack('C4', $ADR));
$MSK = join(".", unpack('C4', $MSK)); $MSK = join(".", unpack('C4', $MSK));

2
debian/rules vendored
View file

@ -32,7 +32,7 @@ install: build
dh_clean -k dh_clean -k
dh_installdirs dh_installdirs
$(MAKE) install prefix=`pwd`/debian/tmp/usr $(MAKE) install DESTDIR=`pwd`/debian/tmp
mkdir -p `pwd`/debian/tmp/etc/tinc/example mkdir -p `pwd`/debian/tmp/etc/tinc/example
cp doc/tinc.conf.sample `pwd`/debian/tmp/etc/tinc/example/tinc.conf cp doc/tinc.conf.sample `pwd`/debian/tmp/etc/tinc/example/tinc.conf
ln -s /usr/share/doc/tinc/README.Debian `pwd`/debian/tmp/etc/tinc/example/README ln -s /usr/share/doc/tinc/README.Debian `pwd`/debian/tmp/etc/tinc/example/README

View file

@ -1,11 +1,13 @@
## Process this file with automake to get Makefile.in ## Process this file with automake to get Makefile.in
SUBDIRS = es
info_TEXINFOS = tinc.texi info_TEXINFOS = tinc.texi
dyn_MANS = tincd.8 dyn_MANS =
man_aux = $(dyn_MANS:.8=.x) man_aux = $(dyn_MANS:.8=.x)
man_MANS = tinc.conf.5 genauth.8 $(dyn_MANS) man_MANS = tincd.8 tinc.conf.5 genauth.8 $(dyn_MANS)
PERL = @PERL@ PERL = @PERL@
HELP2MAN = help2man HELP2MAN = help2man

View file

@ -59,67 +59,104 @@ one space character.
.PP .PP
.SH "VARIABLES" .SH "VARIABLES"
.PP .PP
Here are all valid variables, listed in alphabetical order: Here are all valid variables, listed in alphabetical order. The default
value, required or optional is given between parentheses.
.TP .TP
\fBConnectPort = \fIport\fR \fBConnectPort\fR = <\fIport\fR> (655)
Connect to the upstream host (given with the \fBConnectTo\fR Connect to the upstream host (given with the \fBConnectTo\fR directive) on
directive) on port \fIport\fR. \fIport\fR may be given in decimal port \fIport\fR. port may be given in decimal (default), octal (when preceded
(default), octal (when preceded by a single zero) or hexadecimal by a single zero) or hexadecimal (prefixed with 0x). \fIport\fR is the port
(prefixed with \fB0x\fR). \fIport\fR is the port number for both the number for both the UDP and the TCP (meta) connections.
UDP and the TCP (meta) connections.
.TP .TP
\fBConnectTo = \fB(\fIIP address\fB|\fIhostname\fB)\fR \fBConnectTo\fR = <\fIIP address|hostname\fR> (optional)
Specifies which host to connect to on startup. If the Specifies which host to connect to on startup. Multiple \fBConnectTo\fR variables
\fBConnectPort\fR variable is omitted, then tinc will try to connect may be specified, if connecting to the first one fails then tinc will try
to port 655. the next one, and so on. It is possible to specify hostnames for dynamic IP
addresses (like those given on dyndns.org), tinc will not cache the resolved
IP address.
If you don't specify a host with \fBConnectTo\fR, tinc won't connect If you don't specify a host with \fBConnectTo\fR, regardless of whether a
at all, and will instead just listen for incoming connections. Only value for \fBConnectPort\fR is given, tinc won't connect at all, and will
the initiator of a tinc VPN should need this. instead just listen for incoming connections.
.TP .TP
\fBKeyExpire = \fIs\fR \fBHostnames\fR = <\fIyes|no\fR> (no)
The secret (and public) key expires after \fIs\fR seconds. The default This option selects whether IP addresses (both real and on the VPN) should
is 3600 seconds, or one hour. be resolved. Since DNS lookups are blocking, it might affect tinc's
efficiency, even stopping the daemon for a few seconds everytime it does
a lookup if your DNS server is not responding.
If you make it shorter, a lot of time and bandwidth is spent This does not affect resolving hostnames to IP addresses from the configuration
negotiating over the new keys. If you make it longer, you make file.
yourself more vulnerable to crackers, because they have more data to
work with. The best value depends on the speed of the link, and the
amount of data that goes over it.
.TP .TP
\fBListenPort = \fIport\fR \fBIndirectData\fR = <\fIyes|no\fR> (no)
Listen on local port \fIport\fR. The computer connecting to this This option specifies whether other tinc daemons besides the one you
daemon should use this number as the argument for his specified with \fBConnectTo\fR can make a direct connection to you. This is
\fBConnectPort\fR. Again, the default is 655. especially useful if you are behind a firewall and it is impossible
to make a connection from the outside to your tinc daemon. Otherwise,
it is best to leave this option out or set it to no.
.TP .TP
\fBMyOwnVPNIP = \fInetwork address\fR[\fB/\fImaskbits\fR] \fBInterface\fR = <\fIdevice\fR> (optional)
The \fInetwork address\fR is the number that the daemon will propagate If you have more than one network interface in your computer, tinc will by
to other daemons on the network when it is identifying itself. Hence default listen on all of them for incoming connections. It is possible to
this will be the file name of the passphrase file that the other end bind tinc to a single interface like eth0 or ppp0 with this variable.
expects to find the passphrase in. .TP
\fBInterfaceIP\fR = <\fIlocal address\fR> (optional)
If your computer has more than one IP address on a single interface (for example
if you are running virtual hosts), tinc will by default listen on all of them for
incoming connections. It is possible to bind tinc to a single IP address with
this variable. It is still possible to listen on several interfaces at the same
time though, if they share the same IP address.
.TP
\fBKeyExpire\fR = <\fIseconds\fR> (3600)
This option controls the time the encryption keys used to encrypt the data
are valid. It is common practice to change keys at regular intervals to
make it even harder for crackers, even though it is thought to be nearly
impossible to crack a single key.
.TP
\fBListenPort\fR = <\fIport\fR> (655)
Listen on local port \fIport\fR. The computer connecting to this daemon should
use this number as the argument for his \fBConnectPort\fR.
.TP
\fBMyOwnVPNIP\fR = <\fIlocal address[/maskbits]\fR> (required)
The \fIlocal address\fR is the number that the daemon will propagate to
other daemons on the network when it is identifying itself. Hence this
will be the file name of the passphrase file that the other end expects
to find the passphrase in.
The local address is the IP address of the tap device, not the real IP
address of the host running tincd. Due to changes in recent kernels, it
is also necessary that you make the ethernet (also known as MAC) address
equal to the IP address (see the example).
\fImaskbits\fR is the number of bits set to 1 in the netmask part. \fImaskbits\fR is the number of bits set to 1 in the netmask part.
.TP .TP
\fBMyVirtualIP = \fInetwork address\fR[\fB/\fImaskbits\fR] \fBMyVirtualIP\fR = <\fIlocal address[/maskbits]>
This is an alias for \fBMyOwnVPNIP\fR. This is an alias for \fBMyOwnVPNIP\fR.
.TP .TP
\fBPassphrases = \fIdirectory\fR \fBPassphrases\fR = <\fIdirectory\fR> (/etc/tinc/NETNAME/passphrases)
The directory where tinc will look for passphrases when someone tries The directory where tinc will look for passphrases when someone tries to
to cennect. Please see the manpage for \fBgenauth\fR(8) for more connect. Please see the manpage for genauth(8) for more information
information about passphrases as used by tinc. about passphrases as used by tinc.
.TP .TP
\fBPingTimeout = \fInumber\fR \fBPingTimeout\fR = <\fIseconds\fR> (5)
The number of seconds of inactivity that tinc will wait before sending The number of seconds of inactivity that tinc will wait before sending a
a probe to the other end. If that other end doesn't answer within that probe to the other end. If that other end doesn't answer within that
same amount of seconds, the connection is terminated, and the others same amount of seconds, the connection is terminated, and the others
will be notified of this. will be notified of this.
.TP .TP
\fBTapDevice = \fIdevice\fR \fBTapDevice\fR = <\fIdevice\fR> (/dev/tap0)
The ethertap device to use. Note that you can only use one device per The ethertap device to use. Note that you can only use one device per
daemon. The info pages of the tinc package contain more information daemon. The info pages of the tinc package contain more information
about configuring an ethertap device for linux. about configuring an ethertap device for Linux.
.TP .TP
\fBNetMask = \fImask\fR \fBTCPonly\fR = <\fIyes|no\fR> (no, experimental)
If this variable is set to yes, then the packets are tunnelled over a TCP
connection instead of a UDP connection. This is especially useful for those
who want to run a tinc daemon from behind a masquerading firewall, or if
UDP packet routing is disabled somehow. This is experimental code,
try this at your own risk.
.TP
\fBVpnMask\fR = <\fImask\fR> (optional)
The mask that defines the scope of the entire VPN. This option is not used The mask that defines the scope of the entire VPN. This option is not used
by the tinc daemon itself, but can be used by startup scripts to configure by the tinc daemon itself, but can be used by startup scripts to configure
the ethertap devices correctly. the ethertap devices correctly.

View file

@ -1,4 +1,5 @@
\input texinfo @c -*-texinfo-*- \input texinfo @c -*-texinfo-*-
@c $Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
@c %**start of header @c %**start of header
@setfilename tinc.info @setfilename tinc.info
@settitle tinc Manual @settitle tinc Manual
@ -12,40 +13,45 @@
This is the info manual for tinc, a Virtual Private Network daemon. This is the info manual for tinc, a Virtual Private Network daemon.
Copyright 1998,199,2000 Ivo Timmermans <itimmermans@@bigfoot.com> Copyright @copyright{} 1998,199,2000 Ivo Timmermans
<itimmermans@@bigfoot.com>, Guus Sliepen <guus@@sliepen.warande.net> and
Wessel Dankers <wsl@@nl.linux.org>.
Permission is granted to make and distribute verbatim $Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
copies of this manual provided the copyright notice and
this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified Permission is granted to make and distribute verbatim copies of this
versions of this manual under the conditions for manual provided the copyright notice and this permission notice are
verbatim copying, provided preserved on all copies.
that the entire resulting derived work is distributed
under the terms of a permission notice identical to this Permission is granted to copy and distribute modified versions of this
one. manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
@end ifinfo @end ifinfo
@titlepage @titlepage
@title tinc Manual @title tinc Manual
@subtitle Setting up a Virtual Private Network with tinc @subtitle Setting up a Virtual Private Network with tinc
@author Ivo Timmermans <itimmermans@@bigfoot.com> @author Ivo Timmermans and Guus Sliepen
@page @page
@vskip 0pt plus 1filll @vskip 0pt plus 1filll
Copyright @copyright{} 1998,1999,2000 Ivo Timmermans <itimmermans@@bigfoot.com> @cindex copyright
Copyright @copyright{} 1998,1999,2000 Ivo Timmermans
<itimmermans@@bigfoot.com>, Guus Sliepen <guus@@sliepen.warande.net> and
Wessel Dankers <wsl@@nl.linux.org>.
Permission is granted to make and distribute verbatim $Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
copies of this manual provided the copyright notice and
this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified Permission is granted to make and distribute verbatim copies of this
versions of this manual under the conditions for manual provided the copyright notice and this permission notice are
verbatim copying, provided preserved on all copies.
that the entire resulting derived work is distributed
under the terms of a permission notice identical to this Permission is granted to copy and distribute modified versions of this
one. manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
@end titlepage @end titlepage
@ -54,8 +60,8 @@ Copyright @copyright{} 1998,1999,2000 Ivo Timmermans <itimmermans@@bigfoot.com>
@menu @menu
* Introduction:: Introduction * Introduction:: Introduction
* Configuring a Linux system:: Before compiling tinc * Installing tinc - preparations::
* Installing tinc:: * Installing tinc - installation::
* Configuring tinc:: * Configuring tinc::
* Running tinc:: * Running tinc::
* Technical information:: * Technical information::
@ -63,12 +69,14 @@ Copyright @copyright{} 1998,1999,2000 Ivo Timmermans <itimmermans@@bigfoot.com>
* Concept Index:: All used terms explained * Concept Index:: All used terms explained
@end menu @end menu
@contents
@c ================================================================== @c ==================================================================
@node Introduction, Configuring a Linux system, Top, Top @node Introduction, Installing tinc - preparations, Top, Top
@chapter Introduction @chapter Introduction
@c straight from the www page @cindex tinc
tinc is a Virtual Private Network (VPN) daemon that uses tunneling and tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
encryption to create a secure private network between hosts on the encryption to create a secure private network between hosts on the
Internet. Internet.
@ -86,12 +94,14 @@ process of tinc itself.
@menu @menu
* VPNs:: Virtual Private Networks in general * VPNs:: Virtual Private Networks in general
* tinc:: about tinc * tinc:: about tinc
* Supported platforms::
@end menu @end menu
@c ================================================================== @c ==================================================================
@node VPNs, tinc, Introduction, Introduction @node VPNs, tinc, Introduction, Introduction
@section Virtual Private Networks @section Virtual Private Networks
@cindex VPN
A Virtual Private Network or VPN is a network that can only be accessed A Virtual Private Network or VPN is a network that can only be accessed
by a few elected computers that participate. This goal is achievable in by a few elected computers that participate. This goal is achievable in
more than just one way. more than just one way.
@ -100,7 +110,7 @@ more than just one way.
Private networks can consist of a single stand-alone ethernet LAN. Or Private networks can consist of a single stand-alone ethernet LAN. Or
even two computers hooked up using a null-modem cable. In these cases, even two computers hooked up using a null-modem cable. In these cases,
it is it is
obvious that the network is @emph{private}, noone can access it from the obvious that the network is @emph{private}, no one can access it from the
outside. But if your computers are linked to the internet, the network outside. But if your computers are linked to the internet, the network
is not private anymore, unless one uses firewalls to block all private is not private anymore, unless one uses firewalls to block all private
traffic. But then, there is no way to send private data to trusted traffic. But then, there is no way to send private data to trusted
@ -131,9 +141,11 @@ that flows over the network.
@c ================================================================== @c ==================================================================
@node tinc, , VPNs, Introduction @node tinc, Supported platforms, VPNs, Introduction
@section tinc @section tinc
@cindex vpnd
@cindex ethertap
I really don't quite remember what got us started, but it must have been I really don't quite remember what got us started, but it must have been
Guus' idea. He wrote a simple implementation (about 50 lines of C) that Guus' idea. He wrote a simple implementation (about 50 lines of C) that
used the @emph{ethertap} device that Linux knows of since somewhere used the @emph{ethertap} device that Linux knows of since somewhere
@ -158,23 +170,101 @@ available too.
@c ================================================================== @c ==================================================================
@node Configuring a Linux system, Installing tinc, Introduction, Top @node Supported platforms, , tinc, Introduction
@chapter Configuring a Linux system @section Supported platforms
This chapter contains information on how a Linux system is configured tinc works on Linux, FreeBSD and Solaris. These are the three platforms
for the use of tinc. that are supported by the universial TUN/TAP device driver, so if
support for other operating systems is added to this driver, perhaps
tinc will run on them as well. Without this driver, tinc will most
likely compile and run, but it will not be able to send or receive data
packets.
@c ==================================================================
@subsection Linux
tinc was first written for Linux running on an intel x86 processor, so
this is the best supported platform. The protocol however, and actually
anything about tinc, has been rewritten to support random byte ordering
and arbitrary word length. So in theory it should run on other
processors that Linux runs on. Take care however, we haven't been able
to really test it yet. If you want to run tinc on another platform than
x86, and want to tell us how it went, please do so.
tinc uses the ethertap device that is provided in the standard kernel
since version 2.1.60, so anything above that (2.2.x, 2.3.x, and the
2.4.0-testx (which is current at the time of this writing) kernel
versions) is able to support tinc.
@c ==================================================================
@subsection FreeBSD
tinc on FreeBSD relies on the universial TUN/TAP driver for its data
acquisition from the kernel. Therefore, tinc suports the same platforms
as this driver. These are: FreeBSD 3.x, 4.x, 5.x.
@c ==================================================================
@subsection Solaris
tinc on Solaris relies on the universial TUN/TAP driver for its data
acquisition from the kernel. Therefore, tinc suports the same platforms
as this driver. These are: Solaris, 2.1.x.
@c
@c
@c
@c
@c
@c
@c Preparing your system
@c
@c
@c
@c
@c
@c ==================================================================
@node Installing tinc - preparations, Installing tinc - installation, Introduction, Top
@chapter Installing tinc: preparations
This chapter contains information on how to prepare your system to
support tinc.
@menu @menu
* Configuring the kernel:: * Configuring the kernel::
* Files Needed:: * Libraries::
* Setting up the devices::
@end menu @end menu
@c ================================================================== @c ==================================================================
@node Configuring the kernel, Files Needed, Configuring a Linux system, Configuring a Linux system @node Configuring the kernel, Libraries, Installing tinc - preparations, Installing tinc - preparations
@section Configuring the kernel @section Configuring the kernel
If you are running Linux, chances are good that your kernel already
supports all the devices that tinc needs for proper operation. For
example, the standard kernel from Redhat Linux already has support for
ethertap and netlink compiled in. Debian users can use the modconf
utility to select the modules. If your Linux distribution supports this
method of selecting devices, look out for something called `ethertap',
and `netlink_dev'. You need both these devices.
If you can install these devices in a similar manner, you may skip this
section.
@menu
* Configuration of the Linux kernel::
* Configuration of the FreeBSD kernel::
* Configuration of the Solaris kernel::
@end menu
@c ==================================================================
@node Configuration of the Linux kernel, Configuration of the FreeBSD kernel, Configuring the kernel, Configuring the kernel
@subsection Configuring the Linux kernel
Since this particular implementation only runs on 2.1 or higher Linux Since this particular implementation only runs on 2.1 or higher Linux
kernels, you should grab one (2.2 is current at this time). A 2.0 port kernels, you should grab one (2.2 is current at this time). A 2.0 port
is not really possible, unless someone tells me someone ported the is not really possible, unless someone tells me someone ported the
@ -185,9 +275,11 @@ new kernel, you should read the
@uref{http://howto.linuxberg.com/LDP/HOWTO/Kernel-HOWTO.html, Kernel @uref{http://howto.linuxberg.com/LDP/HOWTO/Kernel-HOWTO.html, Kernel
HOWTO} first. Do that now! HOWTO} first. Do that now!
Here are the options you have to turn on/off when configuring a new Here are the options you have to turn on when configuring a new
kernel. kernel.
For kernel 2.2.x:
@example @example
Code maturity level options Code maturity level options
[*] Prompt for development and/or incomplete code/drivers [*] Prompt for development and/or incomplete code/drivers
@ -198,6 +290,19 @@ Network device support
<*> Ethertap network tap <*> Ethertap network tap
@end example @end example
For kernel 2.3.x and 2.4.x:
@example
Code maturity level options
[*] Prompt for development and/or incomplete code/drivers
Networking options
[*] Kernel/User netlink socket
<*> Netlink device emulation
Network device support
<*> Universal TUN/TAP device driver support
@end example
Any other options not mentioned here are not relevant to tinc. If you Any other options not mentioned here are not relevant to tinc. If you
decide to build any of these as dynamic kernel modules, it's a good idea decide to build any of these as dynamic kernel modules, it's a good idea
to add these lines to @file{/etc/modules.conf}. to add these lines to @file{/etc/modules.conf}.
@ -207,34 +312,179 @@ alias tap0 ethertap
alias char-major-36 netlink_dev alias char-major-36 netlink_dev
@end example @end example
If you have a 2.4 kernel, you can also choose to use the `Ethertap
network tap' device. This is marked obsolete, because the universal
TUN/TAP driver is a newer implementation that is supposed to be used in
favor of ethertap. For tinc, it doesn't really matter which one you
choose; based on the device file name, tinc will make the right choice
about what protocol to use.
Finally, after having set up other options, build the kernel and boot Finally, after having set up other options, build the kernel and boot
it. Unfortunately it's not possible to insert these modules in a running it. Unfortunately it's not possible to insert these modules in a
kernel. running kernel.
@c ================================================================== @c ==================================================================
@node Files Needed, Setting up the devices, Configuring the kernel, Configuring a Linux system @node Configuration of the FreeBSD kernel, Configuration of the Solaris kernel, Configuration of the Linux kernel, Configuring the kernel
@section Files Needed @subsection Configuring the FreeBSD kernel
@subsubheading Device files This section will contain information on how to configure your FreeBSD
kernel to support the universal TUN/TAP device. For 5.0 and 4.1
systems, this is included in the kernel configuration, for earlier
systems (4.0 and 3.x), you need to install the universal TUN/TAP driver
yourself.
Unfortunately somebody still has to write the text.
@c ==================================================================
@node Configuration of the Solaris kernel, , Configuration of the FreeBSD kernel, Configuring the kernel
@subsection Configuring the Solaris kernel
This section will contain information on how to configure your Solaris
kernel to support the universal TUN/TAP device. You need to install
this driver yourself.
Unfortunately somebody still has to write the text.
@c ==================================================================
@node Libraries, , Configuring the kernel, Installing tinc - preparations
@section Libraries
@cindex requirements
Before you can configure or build tinc, you need to have the OpenSSL
library installed on your system. If you try to configure tinc without
having installed it, configure will give you an error message, and stop.
@menu
* OpenSSL::
@end menu
@c ==================================================================
@node OpenSSL, , Libraries, Libraries
@subsection OpenSSL
@cindex OpenSSL
For all cryptography-related functions, tinc uses the functions provided
by the OpenSSL library. We recommend using version 0.9.5 or 0.9.6 of
this library. Other versions may also work, but we can guarantee
nothing.
If this library is not installed, you wil get an error when configuring
tinc for build. Support for running tinc without having OpenSSL
installed @emph{may} be added in the future.
You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions
of this package.
If you have to install OpenSSL manually, you can get the source code
from @url{http://www.openssl.org/}. Instructions on how to configure,
build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the
default).
@c
@c
@c
@c Installing tinc
@c
@c
@c
@c
@c ==================================================================
@node Installing tinc - installation, Configuring tinc, Installing tinc - preparations, Top
@chapter Installing tinc: installation
If you use Redhat or Debian, you may want to install one of the
precompiled packages for your system. These packages are equipped with
system startup scripts and sample configurations.
If you don't run either of these systems, or you want to compile tinc
for yourself, you can use the source. The source is distributed under
the GNU General Public License (GPL). Download the source from the
@uref{http://tinc.nl.linux.org/download.html, download page}, which has
the checksums of these files listed; you may wish to check these with
md5sum before continuing.
tinc comes in a handy autoconf/automake package, which you can just
treat the same as any other package. Which is just untar it, type
`configure' and then `make'.
More detailed instructions are in the file @file{INSTALL}, which is
included in the source distribution.
@menu
* Building tinc::
* System files::
* Interfaces::
@end menu
@c ==================================================================
@node Building tinc, System files, Installing tinc - installation, Installing tinc - installation
@section Building tinc
Detailed instructions on configuring the source and building tinc can be
found in the file called @file{INSTALL}.
@c ==================================================================
@node System files, Interfaces, Building tinc, Installing tinc - installation
@section System files
Before you can run tinc, you
@menu
* Device files::
* Other files::
@end menu
@c ==================================================================
@node Device files, Other files, System files, System files
@subsection Device files
First, you'll need the special device file(s) that form the interface First, you'll need the special device file(s) that form the interface
between the kernel and the daemon. between the kernel and the daemon.
The permissions for these files have to be such that only the super user
may read/write to this file. You'd want this, because otherwise
eavesdropping would become a bit too easy. This does, however, imply
that you'd have to run tincd as root.
If you use the universal TUN/TAP driver, you have to create the
following device files (unless they already exist):
@example
mknod -m 600 /dev/... c .. ..
chown 0.0 /dev/...
@end example
If you want to have more devices, the device numbers will be .. .. ...
If you use Linux, and you run the new 2.4 kernel using the devfs
filesystem, then the tap device will be automatically generated as
@file{/dev/netlink/tap0}.
If you use Linux and have kernel 2.2.x, you have to make the ethertap
devices:
@example @example
mknod -m 600 /dev/tap0 c 36 16 mknod -m 600 /dev/tap0 c 36 16
chown 0.0 /dev/tap0 chown 0.0 /dev/tap0
@end example @end example
The permissions now will be such that only the super user may read/write Any further ethertap devices have minor device number 16 through 31.
to this file. You'd want this, because otherwise eavesdropping would
become a bit too easy. This does, however, imply that you'd have to run
tincd as root.
If you want to, you may also create more device files, which would be
numbered 0...15, with minor device numbers 16...31. They all should be
owned by root and have permission 600.
@c ==================================================================
@node Other files, , Device files, System files
@subsection Other files
@subsubheading @file{/etc/networks} @subsubheading @file{/etc/networks}
@ -245,6 +495,9 @@ symbolic name. For example:
myvpn 10.0.0.0 myvpn 10.0.0.0
@end example @end example
This has nothing to do with the MyVPNIP configuration variable that will be
discussed later, it is only to make the output of the route command more
legible.
@subsubheading @file{/etc/services} @subsubheading @file{/etc/services}
@ -260,15 +513,15 @@ tinc 655/udp TINC
@c ================================================================== @c ==================================================================
@node Setting up the devices, , Files Needed, Configuring a Linux system @node Interfaces, , System files, Installing tinc - installation
@section Setting up the devices @section Interfaces
Before you can start transmitting data over the tinc tunnel, you must Before you can start transmitting data over the tinc tunnel, you must
set up the ethertap network devices. set up the ethertap network devices.
First, decide which IP addresses you want to have associated with these First, decide which IP addresses you want to have associated with these
devices, and what network mask they must have. You also need these devices, and what network mask they must have. You also need these
numbers when you are going to configure tinc itself. @xref{Configuring numbers when you are going to configure tinc itself. @xref{Configuring
tinc}. tinc}.
It doesn't matter much which part you do first, setting up the network It doesn't matter much which part you do first, setting up the network
@ -282,42 +535,52 @@ after me:
ifconfig tap@emph{n} hw ether fe:fd:@emph{xx}:@emph{xx}:@emph{xx}:@emph{xx} ifconfig tap@emph{n} hw ether fe:fd:@emph{xx}:@emph{xx}:@emph{xx}:@emph{xx}
@end example @end example
The @emph{n} here is the number of the ethertap device you want to The @emph{n} here is the number of the ethertap device you want to use.
use. It should be the same @emph{n} as the one you use for It should be the same @emph{n} as the one you use for
@file{/dev/tap@emph{n}}. The @emph{xx}s are four hexadecimal numbers @file{/dev/tap@emph{n}}. The @emph{xx}s are four hexadecimal numbers
(0--ff). With previous versions of tincd, it didn't matter what they (0--ff). With previous versions of tincd, it didn't matter what they
were. But newer kernels require properly set up ethernet addresses. were. But newer kernels require properly set up ethernet addresses. In
In fact, the old behavior was wrong. It is required that the @emph{xx}s fact, the old behavior was wrong. It is required that the @emph{xx}s
match MyOwnVPNIP. match the numbers of the IP address you will give to the tap device and
to the MyOwnVPNIP configuration (which will be discussed later).
@cindex MAC address
@cindex hardware address
@strong{Tip}: for finding out what the MAC address of the tap interface
should be, you can use the following command:
@example @example
ifconfig tap@emph{n} @emph{IP} netmask @emph{mask} $ printf 'fe:fd:%02x:%02x:%02x:%02x' 10 1 54 1
fe:fd:0a:01:36:01
@end example @end example
This will activate the device with an IP address @emph{IP} with network @cindex ifconfig
mask @emph{mask}. To activate the device, you have to assign an IP address to it. To set
an IP address @emph{IP} with network mask @emph{mask}, do the following:
@example
ifconfig tap@emph{n} @emph{xx}.@emph{xx}.@emph{xx}.@emph{xx} netmask @emph{mask}
@end example
@cindex netmask
The netmask is the mask of the @emph{entire} VPN network, not just your
own subnet. It is the same netmask you will have to specify with the
VpnMask configuration variable.
@c
@c ================================================================== @c
@node Installing tinc, Configuring tinc, Configuring a Linux system, Top @c
@chapter Installing tinc @c
@c Configuring tinc
First download it. This is the @c
@uref{http://tinc.nl.linux.org/download.html, download @c
page}, which has the checksums of these files listed; you may wish to @c
check these with md5sum before continuing. @c
tinc comes in a handy autoconf/automake package, which you can just
treat the same as any other package. Which is just untar it, type
`configure' and then `make'.
More detailed instructions are in the file @file{INSTALL}, which is
included in the source distribution.
@c ================================================================== @c ==================================================================
@node Configuring tinc, Running tinc, Installing tinc, Top @node Configuring tinc, Running tinc, Installing tinc - installation, Top
@chapter Configuring tinc @chapter Configuring tinc
@menu @menu
@ -327,7 +590,6 @@ included in the source distribution.
* Example:: * Example::
@end menu @end menu
@c ================================================================== @c ==================================================================
@node Multiple networks, How connections work, Configuring tinc, Configuring tinc @node Multiple networks, How connections work, Configuring tinc, Configuring tinc
@section Multiple networks @section Multiple networks
@ -395,31 +657,67 @@ out, remember to replace it with at least one space character.
@node Variables, , Configuration file, Configuration file @node Variables, , Configuration file, Configuration file
@subsection Variables @subsection Variables
Here are all valid variables, listed in alphabetical order: Here are all valid variables, listed in alphabetical order. The default
value, required or optional is given between parentheses.
@c straight from the manpage @c straight from the manpage
@table @asis @table @asis
@item ConnectPort = port @item ConnectPort = <port> (655)
Connect to the upstream host (given with the ConnectTo directive) on Connect to the upstream host (given with the ConnectTo directive) on
port port. port may be given in decimal (default), octal (when preceded port port. port may be given in decimal (default), octal (when preceded
by a single zero) or hexadecimal (prefixed with 0x). port is the port by a single zero) or hexadecimal (prefixed with 0x). port is the port
number for both the UDP and the TCP (meta) connections. number for both the UDP and the TCP (meta) connections.
@item ConnectTo = (IP address|hostname) @item ConnectTo = <IP address|hostname> (optional)
Specifies which host to connect to on startup. If the ConnectPort Specifies which host to connect to on startup. Multiple ConnectTo variables
variable is omitted, then tinc will try to connect to port 655. may be specified, if connecting to the first one fails then tinc will try
the next one, and so on. It is possible to specify hostnames for dynamic IP
addresses (like those given on dyndns.org), tinc will not cache the resolved
IP address.
If you don't specify a host with ConnectTo, regardless of whether a If you don't specify a host with ConnectTo, regardless of whether a
value for ConnectPort is given, tinc won't connect at all, and will value for ConnectPort is given, tinc won't connect at all, and will
instead just listen for incoming connections. Only the initiator of a instead just listen for incoming connections.
tinc VPN should need this.
@item ListenPort = port @item Hostnames = <yes|no> (no)
This option selects whether IP addresses (both real and on the VPN) should
be resolved. Since DNS lookups are blocking, it might affect tinc's
efficiency, even stopping the daemon for a few seconds everytime it does
a lookup if your DNS server is not responding.
This does not affect resolving hostnames to IP addresses from the configuration
file.
@item IndirectData = <yes|no> (no)
This option specifies whether other tinc daemons besides the one you
specified with ConnectTo can make a direct connection to you. This is
especially useful if you are behind a firewall and it is impossible
to make a connection from the outside to your tinc daemon. Otherwise,
it is best to leave this option out or set it to no.
@item Interface = <device> (optional)
If you have more than one network interface in your computer, tinc will by
default listen on all of them for incoming connections. It is possible to
bind tinc to a single interface like eth0 or ppp0 with this variable.
@item InterfaceIP = <local address> (optional)
If your computer has more than one IP address on a single interface (for example
if you are running virtual hosts), tinc will by default listen on all of them for
incoming connections. It is possible to bind tinc to a single IP address with
this variable. It is still possible to listen on several interfaces at the same
time though, if they share the same IP address.
@item KeyExpire = <seconds> (3600)
This option controls the time the encryption keys used to encrypt the data
are valid. It is common practice to change keys at regular intervals to
make it even harder for crackers, even though it is thought to be nearly
impossible to crack a single key.
@item ListenPort = <port> (655)
Listen on local port port. The computer connecting to this daemon should Listen on local port port. The computer connecting to this daemon should
use this number as the argument for his ConnectPort. Again, the use this number as the argument for his ConnectPort.
default is 655.
@item MyOwnVPNIP = local address[/maskbits] @item MyOwnVPNIP = <local address[/maskbits]> (required)
The local address is the number that the daemon will propagate to The local address is the number that the daemon will propagate to
other daemons on the network when it is identifying itself. Hence this other daemons on the network when it is identifying itself. Hence this
will be the file name of the passphrase file that the other end expects will be the file name of the passphrase file that the other end expects
@ -432,36 +730,45 @@ equal to the IP address (see the example).
maskbits is the number of bits set to 1 in the netmask part. maskbits is the number of bits set to 1 in the netmask part.
@item MyVirtualIP = local address[/maskbits] @item MyVirtualIP = <local address[/maskbits]>
This is an alias for MyOwnVPNIP. This is an alias for MyOwnVPNIP.
@item Passphrases = directory @item Passphrases = <directory> (/etc/tinc/NETNAME/passphrases)
The directory where tinc will look for passphrases when someone tries to The directory where tinc will look for passphrases when someone tries to
connect. Please see the manpage for genauth(8) for more information connect. Please see the manpage for genauth(8) for more information
about passphrases as used by tinc. about passphrases as used by tinc.
@item PingTimeout = number @item PingTimeout = <seconds> (5)
The number of seconds of inactivity that tinc will wait before sending a The number of seconds of inactivity that tinc will wait before sending a
probe to the other end. If that other end doesn't answer within that probe to the other end. If that other end doesn't answer within that
same amount of seconds, the connection is terminated, and the others same amount of seconds, the connection is terminated, and the others
will be notified of this. will be notified of this.
@item TapDevice = device @item TapDevice = <device> (/dev/tap0)
The ethertap device to use. Note that you can only use one device per The ethertap device to use. Note that you can only use one device per
daemon. The info pages of the tinc package contain more information daemon. The info pages of the tinc package contain more information
about configuring an ethertap device for Linux. about configuring an ethertap device for Linux.
@item VpnMask = mask @item TCPonly = <yes|no> (no, experimental)
If this variable is set to yes, then the packets are tunnelled over a TCP
connection instead of a UDP connection. This is especially useful for those
who want to run a tinc daemon from behind a masquerading firewall, or if
UDP packet routing is disabled somehow. This is experimental code,
try this at your own risk.
@item VpnMask = <mask> (optional)
The mask that defines the scope of the entire VPN. This option is not used The mask that defines the scope of the entire VPN. This option is not used
by the tinc daemon itself, but can be used by startup scripts to configure by the tinc daemon itself, but can be used by startup scripts to configure
the ethertap devices correctly. the ethertap devices correctly.
@end table @end table
@c ================================================================== @c ==================================================================
@node Example, , Configuration file, Configuring tinc @node Example, , Configuration file, Configuring tinc
@section Example @section Example
Imagine the following situation. An A-based company wants to connect Imagine the following situation. An A-based company wants to connect
three branch offices in B, C and D using the internet. All four offices three branch offices in B, C and D using the internet. All four offices
have a 24/7 connection to the internet. have a 24/7 connection to the internet.
@ -483,17 +790,19 @@ need to run tincd, but it must do a port forwarding of TCP&UDP on port
655 (unless otherwise configured). 655 (unless otherwise configured).
In this example, it is assumed that eth0 is the interface that points to In this example, it is assumed that eth0 is the interface that points to
the inner LAN of the office. This could be the same as the interface the inner LAN of the office, although this could also be the same as the
that leads to the internet. interface that leads to the internet. The configuration of the real
interface is also shown as a comment, to give you an idea of how these
example host is set up.
@subsubheading For A @subsubheading For A
@emph{A} would be configured like this: @emph{A} would be configured like this:
@example @example
#ifconfig eth0 10.1.54.1 netmask 255.255.0.0 broadcast 10.1.255.255
ifconfig tap0 hw ether fe:fd:0a:01:36:01 ifconfig tap0 hw ether fe:fd:0a:01:36:01
ifconfig tap0 10.1.54.1 netmask 255.0.0.0 ifconfig tap0 10.1.54.1 netmask 255.0.0.0
ifconfig eth0 10.1.54.1 netmask 255.255.0.0 broadcast 10.1.255.255
@end example @end example
and in /etc/tinc/tinc.conf: and in /etc/tinc/tinc.conf:
@ -507,9 +816,9 @@ VpnMask = 255.0.0.0
@subsubheading For B @subsubheading For B
@example @example
#ifconfig eth0 10.2.43.8 netmask 255.255.0.0 broadcast 10.2.255.255
ifconfig tap0 hw ether fe:fd:0a:02:01:0c ifconfig tap0 hw ether fe:fd:0a:02:01:0c
ifconfig tap0 10.2.1.12 netmask 255.0.0.0 ifconfig tap0 10.2.1.12 netmask 255.0.0.0
ifconfig eth0 10.2.43.8 netmask 255.255.0.0 broadcast 10.2.255.255
@end example @end example
and in /etc/tinc/tinc.conf: and in /etc/tinc/tinc.conf:
@ -528,30 +837,33 @@ connect to this node.
@subsubheading For C @subsubheading For C
@example @example
#ifconfig eth0 10.3.69.254 netmask 255.255.0.0 broadcast 10.3.255.255
ifconfig tap0 hw ether fe:fd:0a:03:45:fe ifconfig tap0 hw ether fe:fd:0a:03:45:fe
ifconfig tap0 10.3.69.254 netmask 255.0.0.0 ifconfig tap0 10.3.69.254 netmask 255.0.0.0
ifconfig eth0 10.3.69.254 netmask 255.255.0.0 broadcast 10.3.255.255
@end example @end example
and in /etc/tinc/A/tinc.conf: and in /etc/tinc/A/tinc.conf:
@example @example
MyVirtualIP = 10.3.69.254/16 MyVirtualIP = 10.3.69.254/16
TapDevice = /dev/tap1
ConnectTo = 1.2.3.4 ConnectTo = 1.2.3.4
ListenPort = 2000 ListenPort = 2000
VpnMask = 255.0.0.0 VpnMask = 255.0.0.0
@end example @end example
C already has another daemon that runs on port 655, so they have to C already has another daemon that runs on port 655, so they have to
reserve another port for tinc. They also use the netname to distinguish reserve another port for tinc. It can connect to other tinc daemons on
the regular port though, so no ConnectPort variable is needed.
They also use the netname to distinguish
between the two. tinc is started with `tincd -n A'. between the two. tinc is started with `tincd -n A'.
@subsubheading For D @subsubheading For D
@example @example
#ifconfig tap0 10.4.3.32 netmask 255.255.0.0 broadcast 10.4.255.255
ifconfig tap0 hw ether fe:fd:0a:04:03:20 ifconfig tap0 hw ether fe:fd:0a:04:03:20
ifconfig tap0 10.4.3.32 netmask 255.0.0.0 ifconfig tap0 10.4.3.32 netmask 255.0.0.0
ifconfig tap0 10.4.3.32 netmask 255.255.0.0 broadcast 10.4.255.255
@end example @end example
and in /etc/tinc/tinc.conf: and in /etc/tinc/tinc.conf:
@ -564,7 +876,8 @@ VpnMask=255.0.0.0
@end example @end example
D will be connecting to C, which has a tincd running for this network on D will be connecting to C, which has a tincd running for this network on
port 2000. Hence they need to put in a ConnectPort. port 2000. Hence they need to put in a ConnectPort, but it doesn't need
to have a different ListenPort.
@subsubheading Authentication @subsubheading Authentication
@ -572,17 +885,17 @@ A, B, C and D all generate a passphrase with genauth 2048, the output is
stored in /etc/tinc/passphrases/local, except for C, where it should be stored in /etc/tinc/passphrases/local, except for C, where it should be
/etc/tinc/A/passphrases/local. /etc/tinc/A/passphrases/local.
A stores a copy of B's passphrase in /etc/tinc/passphrases/10.2.0.0 A stores a copy of B's passphrase in /etc/tinc/passphrases/10.2.1.12
A stores a copy of C's passphrase in /etc/tinc/passphrases/10.3.0.0 A stores a copy of C's passphrase in /etc/tinc/passphrases/10.3.69.254
B stores a copy of A's passphrase in /etc/tinc/passphrases/10.1.0.0 B stores a copy of A's passphrase in /etc/tinc/passphrases/10.1.54.1
C stores a copy of A's passphrase in /etc/tinc/A/passphrases/10.1.0.0 C stores a copy of A's passphrase in /etc/tinc/A/passphrases/10.1.54.1
C stores a copy of D's passphrase in /etc/tinc/A/passphrases/10.4.0.0 C stores a copy of D's passphrase in /etc/tinc/A/passphrases/10.4.3.32
D stores a copy of C's passphrase in /etc/tinc/passphrases/10.3.0.0 D stores a copy of C's passphrase in /etc/tinc/passphrases/10.3.69.254
@subsubheading Starting @subsubheading Starting
@ -810,16 +1123,47 @@ This chapter is a mixture of ideas, reasoning and explanation, please
don't take it too serious. don't take it too serious.
@menu @menu
* Key Types::
* Key Management:: * Key Management::
* Authentication:: * Authentication::
* Protection:: * Protection::
@end menu @end menu
@c ==================================================================
@node Key Types, Key Management, Security, Security
@subsection Key Types
@c FIXME: check if I'm not talking nonsense
There are several types of encryption keys. Tinc uses two of them,
symmetric private keypairs and public/private keypairs.
Public/private keypairs are used in public key cryptography. It enables
someone to send out a public key with which other people can encrypt their
data. The encrypted data now can only be decrypted by the person who has
the private key that matches the public key. So, a public key only allows
@emph{other} people to send encrypted messages to you. This is very useful
in setting up private communications channels. Just send out your public key
and other people can talk to you in a secure way. But how can you know
the other person is who he says he is?
For authentication itself tinc uses symmetric private keypairs, referred
to as a passphrase. The identity of each tinc daemon is defined by it's
passphrase (like you can be identified by your social security number).
Every tinc daemon that is allowed to connect to you has a copy of your
passphrase (hence symmetrical).
It would also be possible to use public/private keypairs for authentication,
so that you could shout out your public key and don't need to keep it
secret (like the passphrase you would have to send to someone else). Also,
no one else has to know a private key from you.
Both forms have their pros and cons, and at the moment tinc just uses passphrases
(which are computationaly more efficient and perhaps in some way more
secure).
@c ================================================================== @c ==================================================================
@node Key Management, Authentication, Security, Security @node Key Management, Authentication, Key Types, Security
@subsection Key Management @subsection Key Management
@c FIXME: recheck @c FIXME change for the current protocol
@cindex Diffie-Hellman @cindex Diffie-Hellman
You can't just send a private encryption key to your peer, because You can't just send a private encryption key to your peer, because
@ -840,10 +1184,6 @@ mod p. This is then sent to B; while B computes g^b mod p, and transmits
this to A, b being generated by B. Both a and b must be smaller than this to A, b being generated by B. Both a and b must be smaller than
p-1. p-1.
These private keys are generated upon startup, and they are not changed
while the connection exists. A possible feature in the future is to
dynamically change the keys, every hour for example.
Both parties then calculate g^ab mod p = k. k is the new, shared, but Both parties then calculate g^ab mod p = k. k is the new, shared, but
still secret key. still secret key.
@ -864,17 +1204,25 @@ system.
We will let A transmit a passphrase that is also known to B encrypted We will let A transmit a passphrase that is also known to B encrypted
with g^a, before A sends this to B. This way, B can check whether A is with g^a, before A sends this to B. This way, B can check whether A is
really A or just someone else. really A or just someone else.
B will never receive the real passphrase though, because it was
encrypted using public/private keypairs. This way there is no way an
imposter could steal A's passphrase.
@cindex passphrase @cindex passphrase
@c ehrmz... but we only use 1024 bits passphrases ourselves? [guus]
This passphrase should be 2304 bits for a symmetric encryption This passphrase should be 2304 bits for a symmetric encryption
system. But since an asymmetric system is more secure, we could do with system. But since an asymmetric system is more secure, we could do with
2048 bits. This only holds if the passphrase is very random. 2048 bits. This only holds if the passphrase is very random.
These passphrases could be stored in a file that is non-readable by These passphrases could be stored in a file that is non-readable by
anyone else but root; e.g. @file{/etc/vpn/passphrases}. anyone else but root; e.g. @file{/etc/tinc/passphrases} with UID 0
and permissions mode 700.
The only thing that needs to be taken care of is how A announces its The only thing that needs to be taken care of is how A can securely send
passphrase to B. a copy of it's passphrase to B if B doesn't have it yet. This could be
done via mail with PGP, but you should be really convinced of the
identity of the person who owns the email address you are sending this to.
Swapping floppy disks in real life might be the best way to do this!
@c ================================================================== @c ==================================================================
@ -884,6 +1232,7 @@ passphrase to B.
Now we have securely hidden our data. But a malicious cracker may still Now we have securely hidden our data. But a malicious cracker may still
bother you by randomly altering the encrypted data he intercepts. bother you by randomly altering the encrypted data he intercepts.
@c FIXME what the hell is this all about? remove? IT
@c ================================================================== @c ==================================================================
@node About us, Concept Index, Technical information, Top @node About us, Concept Index, Technical information, Top

View file

@ -1,8 +1,9 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# $Id: Makefile.am,v 1.3 2000/10/18 20:12:07 zarq Exp $
noinst_LIBRARIES = libvpn.a noinst_LIBRARIES = libvpn.a
INCLUDES = -I. -I$(top_builddir) INCLUDES = -I. -I$(top_builddir) -I$(top_srcdir)/intl
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c

View file

@ -1,6 +1,7 @@
/* /*
utils.c -- gathering of some stupid small functions utils.c -- gathering of some stupid small functions
Copyright (C) 1999 Ivo Timmermans <zarq@iname.com> Copyright (C) 1999,2000 Ivo Timmermans <zarq@iname.com>
2000 Guus Sliepen <guus@sliepen.warande.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -17,10 +18,57 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include "config.h" #include "config.h"
#include <utils.h> #include <utils.h>
#include <syslog.h>
volatile int cp_line; volatile int (cp_line[]) = {0, 0, 0, 0, 0, 0, 0, 0};
volatile char *cp_file; volatile char (*cp_file[]) = {"?", "?", "?", "?", "?", "?", "?", "?"};
volatile int cp_index = 0;
char *hexadecimals = "0123456789ABCDEF";
int charhex2bin(char c)
{
if(isdigit(c))
return c - '0';
else
return toupper(c) - 'A' + 10;
}
void hex2bin(char *src, char *dst, int length)
{
int i;
for(i=0; i<length; i++)
dst[i] = charhex2bin(src[i*2])*16 + charhex2bin(src[i*2+1]);
}
void bin2hex(char *src, char *dst, int length)
{
int i;
for(i=length-1; i>=0; i--)
{
dst[i*2+1] = hexadecimals[(unsigned char)src[i] & 15];
dst[i*2] = hexadecimals[(unsigned char)src[i]>>4];
}
}
char *cp_trace()
{
syslog(LOG_DEBUG, "Checkpoint trace: %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d ...",
cp_file[(cp_index+7)%8], cp_line[(cp_index+7)%8],
cp_file[(cp_index+6)%8], cp_line[(cp_index+6)%8],
cp_file[(cp_index+5)%8], cp_line[(cp_index+5)%8],
cp_file[(cp_index+4)%8], cp_line[(cp_index+4)%8],
cp_file[(cp_index+3)%8], cp_line[(cp_index+3)%8],
cp_file[(cp_index+2)%8], cp_line[(cp_index+2)%8],
cp_file[(cp_index+1)%8], cp_line[(cp_index+1)%8],
cp_file[cp_index], cp_line[cp_index]
);
}

View file

@ -1,6 +1,7 @@
/* /*
utils.h -- header file for utils.c utils.h -- header file for utils.c
Copyright (C) 1999 Ivo Timmermans <zarq@iname.com> Copyright (C) 1999,2000 Ivo Timmermans <zarq@iname.com>
2000 Guus Sliepen <guus@sliepen.warande.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -20,11 +21,27 @@
#ifndef __TINC_UTILS_H__ #ifndef __TINC_UTILS_H__
#define __TINC_UTILS_H__ #define __TINC_UTILS_H__
#include <ctype.h>
enum {
DEBUG_CONNECTIONS = 0,
DEBUG_PROTOCOL,
DEBUG_STATUS,
DEBUG_ERROR,
DEBUG_META
};
#define min(a,b) (((a)<(b))?(a):(b)) #define min(a,b) (((a)<(b))?(a):(b))
#define cp { cp_line = __LINE__; cp_file = __FILE__; } extern volatile int cp_line[];
extern volatile char *cp_file[];
extern volatile int cp_index;
extern volatile int cp_line; #define cp { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 8; }
extern volatile char *cp_file; #define ecp { fprintf(stderr, "Explicit checkpoint in %s line %d\n", __FILE__, __LINE__); }
extern void hex2bin(char *src, char *dst, int length);
extern void bin2hex(char *src, char *dst, int length);
extern char *cp_trace(void);
#endif /* __TINC_UTILS_H__ */ #endif /* __TINC_UTILS_H__ */

View file

@ -1,3 +1,5 @@
#include <sys/types.h>
#ifndef PARAMS #ifndef PARAMS
# if defined PROTOTYPES || (defined __STDC__ && __STDC__) # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
# define PARAMS(Args) Args # define PARAMS(Args) Args

View file

@ -87,8 +87,6 @@ xmalloc (n)
size_t n; size_t n;
{ {
void *p; void *p;
extern char*cp_file;
extern int cp_line;
p = malloc (n); p = malloc (n);
if (p == 0) if (p == 0)

View file

@ -4,10 +4,12 @@
# Package source files # Package source files
lib/pidfile.c lib/pidfile.c
lib/utils.c
src/conf.c src/conf.c
src/encr.c
src/genauth.c src/genauth.c
src/meta.c
src/net.c src/net.c
src/netutl.c src/netutl.c
src/protocol.c src/protocol.c
src/subnet.c
src/tincd.c src/tincd.c

1135
po/nl.po

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
Summary: tinc Virtual Private Network daemon Summary: tinc Virtual Private Network daemon
Name: tinc Name: tinc
Version: 1.0pre2 Version: 1.0pre3
Release: 1 Release: 1
Copyright: GPL Copyright: GPL
Group: System Environment/Daemons Group: System Environment/Daemons

View file

@ -1,17 +1,18 @@
## Produce this file with automake to get Makefile.in ## Produce this file with automake to get Makefile.in
# $Id: Makefile.am,v 1.5 2000/10/18 20:12:08 zarq Exp $
sbin_PROGRAMS = tincd genauth sbin_PROGRAMS = tincd genauth
genauth_SOURCES = genauth.c genauth_SOURCES = genauth.c
tincd_SOURCES = conf.c encr.c net.c netutl.c protocol.c tincd.c tincd_SOURCES = conf.c connlist.c meta.c net.c netutl.c protocol.c subnet.c tincd.c
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/cipher -I$(top_srcdir)/lib INCLUDES = -I$(top_builddir) -I$(top_srcdir)/cipher -I$(top_srcdir)/lib -I$(top_srcdir)/intl
noinst_HEADERS = conf.h encr.h net.h netutl.h protocol.h noinst_HEADERS = conf.h connlist.h meta.h net.h netutl.h protocol.h subnet.h
LIBS = @LIBS@ LIBS = @LIBS@ @INTLLIBS@
tincd_LDADD = $(top_builddir)/cipher/libcipher.la \ tincd_LDADD = \
$(top_builddir)/lib/libvpn.a $(top_builddir)/lib/libvpn.a
genauth_LDADD = $(top_builddir)/lib/libvpn.a genauth_LDADD = $(top_builddir)/lib/libvpn.a

View file

@ -19,52 +19,63 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.c,v 1.9 2000/05/30 11:18:12 zarq Exp $ $Id: conf.c,v 1.10 2000/10/18 20:12:08 zarq Exp $
*/ */
#include "config.h"
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <syslog.h>
#include <xalloc.h> #include <xalloc.h>
#include "conf.h" #include "conf.h"
#include "netutl.h" /* for strtoip */ #include "netutl.h" /* for strtoip */
#include <utils.h> /* for cp */
#include "config.h"
#include "connlist.h"
#include "system.h" #include "system.h"
config_t *config; config_t *config = NULL;
int debug_lvl = 0; int debug_lvl = 0;
int timeout = 0; /* seconds before timeout */ int timeout = 0; /* seconds before timeout */
char *confbase = NULL; /* directory in which all config files are */
char *netname = NULL; /* name of the vpn network */
typedef struct internal_config_t { /* Will be set if HUP signal is received. It will be processed when it is safe. */
char *name; int sighup = 0;
enum which_t which;
int argtype;
} internal_config_t;
/* /*
These are all the possible configurable values These are all the possible configurable values
*/ */
static internal_config_t hazahaza[] = { static internal_config_t hazahaza[] = {
{ "AllowConnect", allowconnect, TYPE_BOOL }, /* Is not used anywhere. Remove? */ /* Main configuration file keywords */
{ "ConnectTo", upstreamip, TYPE_IP }, { "Name", tincname, TYPE_NAME },
{ "ConnectPort", upstreamport, TYPE_INT }, { "ConnectTo", connectto, TYPE_NAME },
{ "ListenPort", listenport, TYPE_INT },
{ "MyOwnVPNIP", myvpnip, TYPE_IP },
{ "MyVirtualIP", myvpnip, TYPE_IP }, /* an alias */
{ "Passphrases", passphrasesdir, TYPE_NAME },
{ "PingTimeout", pingtimeout, TYPE_INT }, { "PingTimeout", pingtimeout, TYPE_INT },
{ "TapDevice", tapdevice, TYPE_NAME }, { "TapDevice", tapdevice, TYPE_NAME },
{ "TapSubnet", tapsubnet, TYPE_IP },
{ "PrivateKey", privatekey, TYPE_NAME },
{ "KeyExpire", keyexpire, TYPE_INT }, { "KeyExpire", keyexpire, TYPE_INT },
{ "VpnMask", vpnmask, TYPE_IP },
{ "Hostnames", resolve_dns, TYPE_BOOL }, { "Hostnames", resolve_dns, TYPE_BOOL },
{ "Interface", interface, TYPE_NAME },
{ "InterfaceIP", interfaceip, TYPE_IP },
/* Host configuration file keywords */
{ "Address", address, TYPE_NAME },
{ "Port", port, TYPE_INT },
{ "PublicKey", publickey, TYPE_NAME },
{ "Subnet", subnet, TYPE_NAME },
{ "RestrictHosts", restricthosts, TYPE_BOOL },
{ "RestrictSubnets", restrictsubnets, TYPE_BOOL },
{ "RestrictAddress", restrictaddress, TYPE_BOOL },
{ "RestrictPort", restrictport, TYPE_BOOL },
{ "IndirectData", indirectdata, TYPE_BOOL },
{ "TCPonly", tcponly, TYPE_BOOL },
{ NULL, 0, 0 } { NULL, 0, 0 }
}; };
@ -74,12 +85,12 @@ static internal_config_t hazahaza[] = {
config_t * config_t *
add_config_val(config_t **cfg, int argtype, char *val) add_config_val(config_t **cfg, int argtype, char *val)
{ {
config_t *p; config_t *p, *r;
char *q; char *q;
cp
p = (config_t*)xmalloc(sizeof(*p)); p = (config_t*)xmalloc(sizeof(*p));
p->data.val = 0; p->data.val = 0;
switch(argtype) switch(argtype)
{ {
case TYPE_INT: case TYPE_INT:
@ -103,46 +114,57 @@ add_config_val(config_t **cfg, int argtype, char *val)
p->data.val = 0; p->data.val = 0;
} }
p->argtype = argtype;
if(p->data.val) if(p->data.val)
{ {
p->next = *cfg; p->next = *cfg;
*cfg = p; *cfg = p;
cp
return p; return p;
} }
else
free(p); {
return NULL; free(p);
cp
return NULL;
}
} }
/* /*
Get variable from a section in a configfile. returns -1 on failure. Parse a configuration file and put the results in the configuration tree
starting at *base.
*/ */
int int read_config_file(config_t **base, const char *fname)
readconfig(const char *fname, FILE *fp)
{ {
char *line, *temp_buf; int err = -1;
FILE *fp;
char line[MAXBUFSIZE]; /* There really should not be any line longer than this... */
char *p, *q; char *p, *q;
int i, lineno = 0; int i, lineno = 0;
config_t *cfg; config_t *cfg;
cp
if((fp = fopen (fname, "r")) == NULL)
{
return -1;
}
line = (char *)xmalloc(80 * sizeof(char));
temp_buf = (char *)xmalloc(80 * sizeof(char));
for(;;) for(;;)
{ {
if(fgets(line, 80, fp) == NULL) if(fgets(line, MAXBUFSIZE, fp) == NULL)
return 0;
while(!index(line, '\n'))
{ {
fgets(temp_buf, (strlen(line)+1) * 80, fp); err = 0;
if(!temp_buf) break;
break; }
strcat(line, temp_buf);
line = (char *)xrealloc(line, (strlen(line)+1) * sizeof(char));
}
lineno++; lineno++;
if(!index(line, '\n'))
{
syslog(LOG_ERR, _("Line %d too long while reading config file %s"), lineno, fname);
break;
}
if((p = strtok(line, "\t\n\r =")) == NULL) if((p = strtok(line, "\t\n\r =")) == NULL)
continue; /* no tokens on this line */ continue; /* no tokens on this line */
@ -155,66 +177,92 @@ readconfig(const char *fname, FILE *fp)
if(!hazahaza[i].name) if(!hazahaza[i].name)
{ {
fprintf(stderr, _("%s: %d: Invalid variable name `%s'.\n"), syslog(LOG_ERR, _("Invalid variable name on line %d while reading config file %s"),
fname, lineno, p); lineno, fname);
return -1; break;
} }
if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#') if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
{ {
fprintf(stderr, _("%s: %d: No value given for `%s'.\n"), fprintf(stderr, _("No value for variable on line %d while reading config file %s"),
fname, lineno, hazahaza[i].name); lineno, fname);
return -1; break;
} }
cfg = add_config_val(&config, hazahaza[i].argtype, q); cfg = add_config_val(base, hazahaza[i].argtype, q);
if(cfg == NULL) if(cfg == NULL)
{ {
fprintf(stderr, _("%s: %d: Invalid value `%s' for variable `%s'.\n"), fprintf(stderr, _("Invalid value for variable on line %d while reading config file %s"),
fname, lineno, q, hazahaza[i].name); lineno, fname);
return -1; break;
} }
cfg->which = hazahaza[i].which; cfg->which = hazahaza[i].which;
if(!config) if(!config)
config = cfg; config = cfg;
} }
}
/*
wrapper function for readconfig
*/
int
read_config_file(const char *fname)
{
FILE *fp;
if((fp = fopen (fname, "r")) == NULL)
{
fprintf(stderr, _("Could not open %s: %s\n"), fname, sys_errlist[errno]);
return 1;
}
if(readconfig(fname, fp))
return -1;
fclose (fp); fclose (fp);
cp
return err;
}
return 0; int read_server_config()
{
char *fname;
int x;
cp
asprintf(&fname, "%s/tinc.conf", confbase);
x = read_config_file(&config, fname);
free(fname);
cp
return x;
} }
/* /*
Look up the value of the config option type Look up the value of the config option type
*/ */
const config_t * const config_t *get_config_val(config_t *p, which_t type)
get_config_val(which_t type)
{ {
config_t *p; cp
for(; p != NULL; p = p->next)
for(p = config; p != NULL; p = p->next)
if(p->which == type) if(p->which == type)
return p; break;
cp
/* Not found */ return p;
return NULL; }
/*
Support for multiple config lines.
Index is used to get a specific value, 0 being the first, 1 the second etc.
*/
const config_t *get_next_config_val(config_t *p, which_t type, int index)
{
cp
for(; p != NULL; p = p->next)
if(p->which == type)
if(--index < 0)
break;
cp
return p;
}
/*
Remove the complete configuration tree.
*/
void clear_config(config_t **base)
{
config_t *p, *next;
cp
for(p = *base; p != NULL; p = next)
{
next = p->next;
if(p->data.ptr && (p->argtype == TYPE_NAME))
{
free(p->data.ptr);
}
free(p);
}
*base = NULL;
cp
} }

View file

@ -17,43 +17,60 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.h,v 1.6 2000/05/30 11:18:12 zarq Exp $ $Id: conf.h,v 1.7 2000/10/18 20:12:08 zarq Exp $
*/ */
#ifndef __TINC_CONF_H__ #ifndef __TINC_CONF_H__
#define __TINC_CONF_H__ #define __TINC_CONF_H__
#define MAXTIMEOUT 900 /* Maximum timeout value for retries. Should this be a configuration option? */
typedef struct ip_mask_t { typedef struct ip_mask_t {
unsigned long ip; unsigned long ip;
unsigned long mask; unsigned long mask;
} ip_mask_t; } ip_mask_t;
typedef union data_t {
unsigned long val;
void *ptr;
ip_mask_t *ip;
} data_t;
typedef enum which_t { typedef enum which_t {
passphrasesdir = 1, tincname = 1,
upstreamip, connectto,
upstreamport,
listenport,
myvpnip,
tapdevice,
allowconnect,
pingtimeout, pingtimeout,
tapdevice,
tapsubnet,
privatekey,
keyexpire, keyexpire,
vpnmask, resolve_dns,
resolve_dns interface,
interfaceip,
address,
port,
publickey,
subnet,
restricthosts,
restrictsubnets,
restrictaddress,
restrictport,
indirectdata,
tcponly,
} which_t; } which_t;
typedef struct config_t { typedef struct config_t {
struct config_t *next; struct config_t *next;
which_t which; which_t which;
data_t data; int argtype;
union data {
unsigned long val;
void *ptr;
ip_mask_t *ip;
struct config_t *next; /* For nested configs! */
} data;
} config_t; } config_t;
typedef struct internal_config_t {
char *name;
enum which_t which;
int argtype;
} internal_config_t;
enum { enum {
stupid_false = 1, stupid_false = 1,
stupid_true stupid_true
@ -69,9 +86,16 @@ enum {
extern config_t *config; extern config_t *config;
extern int debug_lvl; extern int debug_lvl;
extern int timeout; extern int timeout;
extern int upstreamindex;
extern int sighup;
extern char *confbase;
extern char *netname;
extern config_t *add_config_val(config_t **, int, char *); extern config_t *add_config_val(config_t **, int, char *);
extern int read_config_file(const char *); extern int read_config_file(config_t **, const char *);
extern const config_t *get_config_val(which_t type); extern const config_t *get_config_val(config_t *, which_t type);
extern const config_t *get_next_config_val(config_t *, which_t type, int);
extern void clear_config();
extern int read_server_config(void);
#endif /* __TINC_CONF_H__ */ #endif /* __TINC_CONF_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: encr.c,v 1.12 2000/05/31 18:23:06 zarq Exp $ $Id: encr.c,v 1.13 2000/10/18 20:12:08 zarq Exp $
*/ */
#include "config.h" #include "config.h"
@ -61,8 +61,8 @@ int key_inited = 0, encryption_keylen;
mpz_t my_private_key, my_public_key, generator, shared_prime; mpz_t my_private_key, my_public_key, generator, shared_prime;
int my_key_expiry = (time_t)(-1); int my_key_expiry = (time_t)(-1);
static char* mypassphrase; char* mypassphrase;
static int mypassphraselen; int mypassphraselen;
int char_hex_to_bin(int c) int char_hex_to_bin(int c)
{ {
@ -98,18 +98,17 @@ int read_passphrase(char *which, char **out)
cp cp
if((cfg = get_config_val(passphrasesdir)) == NULL) if((cfg = get_config_val(passphrasesdir)) == NULL)
{ {
filename = xmalloc(strlen(confbase)+13+strlen(which)); asprintf(&filename, "%spassphrases/%s", confbase, which);
sprintf(filename, "%spassphrases/%s", confbase, which);
} }
else else
{ {
filename = xmalloc(strlen(cfg->data.ptr)+2+strlen(which)); asprintf(&filename, "%s/%s", (char*)cfg->data.ptr, which);
sprintf(filename, "%s/%s", (char*)cfg->data.ptr, which);
} }
if((f = fopen(filename, "rb")) == NULL) if((f = fopen(filename, "rb")) == NULL)
{ {
syslog(LOG_ERR, _("Could not open %s: %m"), filename); if(debug_lvl > 1)
syslog(LOG_ERR, _("Could not open %s: %m"), filename);
return -1; return -1;
} }
@ -119,12 +118,14 @@ cp
syslog(LOG_ERR, _("Illegal passphrase in %s; size would be %d"), filename, size); syslog(LOG_ERR, _("Illegal passphrase in %s; size would be %d"), filename, size);
return -1; return -1;
} }
size >>= 2; /* bits->nibbles */
pp = xmalloc(size+2); /* Hmz... hackish... strange +1 and +2 stuff... I really like more comments on those alignment thingies! */
fgets(pp, size+1, f);
pp = xmalloc(size/4 + 1); /* Allocate enough for fgets */
fgets(pp, size/4 + 1, f); /* Read passhrase and reserve one byte for end-of-string */
fclose(f); fclose(f);
*out = xmalloc(size); *out = xmalloc(size/8 + 2); /* Allocate enough bytes, +1 for rounding if bits%8 != 0, +1 for 2-byte alignment */
cp cp
return str_hex_to_bin(*out, pp); return str_hex_to_bin(*out, pp);
} }
@ -150,7 +151,8 @@ cp
else else
my_key_expiry = (time_t)(time(NULL) + cfg->data.val); my_key_expiry = (time_t)(time(NULL) + cfg->data.val);
syslog(LOG_NOTICE, _("Generating %d bits keys."), PRIVATE_KEY_BITS); if(debug_lvl > 1)
syslog(LOG_NOTICE, _("Generating %d bits keys"), PRIVATE_KEY_BITS);
if((f = fopen("/dev/urandom", "r")) == NULL) if((f = fopen("/dev/urandom", "r")) == NULL)
{ {
@ -266,7 +268,7 @@ int verify_passphrase(conn_list_t *cl, unsigned char *his_pubkey)
mpz_t pk; mpz_t pk;
unsigned char *out; unsigned char *out;
BF_KEY bf_key; BF_KEY bf_key;
char which[sizeof("123.123.123.123")+1]; char *which;
char *meuk; char *meuk;
cp cp
mpz_init_set_str(pk, his_pubkey, 36); mpz_init_set_str(pk, his_pubkey, 36);
@ -280,7 +282,7 @@ cp
if(key_inited) if(key_inited)
cipher_set_key(&encryption_key, encryption_keylen, text_key); cipher_set_key(&encryption_key, encryption_keylen, text_key);
sprintf(which, IP_ADDR_S, IP_ADDR_V(cl->vpn_ip)); asprintf(&which, IP_ADDR_S, IP_ADDR_V(cl->vpn_ip));
if((pplen = read_passphrase(which, &meuk)) < 0) if((pplen = read_passphrase(which, &meuk)) < 0)
return -1; return -1;
@ -335,12 +337,12 @@ cp
/* We haven't received a key from this host (yet). */ /* We haven't received a key from this host (yet). */
continue; continue;
ek = make_shared_key(p->public_key->key); ek = make_shared_key(p->public_key->key);
free_key(p->key); free_key(p->datakey);
p->key = xmalloc(sizeof(*p->key)); p->datakey = xmalloc(sizeof(*p->datakey));
p->key->length = strlen(ek); p->datakey->length = strlen(ek);
p->key->expiry = p->public_key->expiry; p->datakey->expiry = p->public_key->expiry;
p->key->key = xmalloc(strlen(ek) + 1); p->datakey->key = xmalloc(strlen(ek) + 1);
strcpy(p->key->key, ek); strcpy(p->datakey->key, ek);
} }
cp cp
} }

View file

@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: encr.h,v 1.3 2000/10/18 20:12:08 zarq Exp $
*/ */
#ifndef __TINC_ENCR_H__ #ifndef __TINC_ENCR_H__
@ -30,9 +32,6 @@ extern int my_key_expiry;
extern int security_init(void); extern int security_init(void);
extern void do_bf_encrypt(vpn_packet_t *, real_packet_t *);
extern void do_bf_decrypt(real_packet_t *, vpn_packet_t *);
extern int send_portnumbers(int); extern int send_portnumbers(int);
extern void set_shared_key(char *); extern void set_shared_key(char *);
extern int send_passphrase(conn_list_t *); extern int send_passphrase(conn_list_t *);

View file

@ -1,6 +1,7 @@
/* /*
genauth.c -- generate a random passphrase genauth.c -- generate public/private keypairs
Copyright (C) 1998,1999,2000 Ivo Timmermans <zarq@iname.com> Copyright (C) 1998,1999,2000 Ivo Timmermans <zarq@iname.com>
2000 Guus Sliepen <guus@sliepen.warande.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -16,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: genauth.c,v 1.7 2000/05/31 18:21:27 zarq Exp $ $Id: genauth.c,v 1.8 2000/10/18 20:12:08 zarq Exp $
*/ */
#include "config.h" #include "config.h"
@ -24,20 +25,49 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <openssl/rsa.h>
#include <xalloc.h> #include <xalloc.h>
#include "encr.h"
#include "system.h" #include "system.h"
unsigned char initvec[] = { 0x22, 0x7b, 0xad, 0x55, 0x41, 0xf4, 0x3e, 0xf3 }; #define RSA_PUBLIC_EXPONENT 65535
void indicator(int a, int b, void *p)
{
switch(a)
{
case 0:
fprintf(stderr, ".");
break;
case 1:
fprintf(stderr, "+");
break;
case 2:
fprintf(stderr, "-");
break;
case 3:
switch(b)
{
case 0:
fprintf(stderr, " p\n");
break;
case 1:
fprintf(stderr, " q\n");
break;
default:
fprintf(stderr, "?");
}
break;
default:
fprintf(stderr, "?");
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *fp; int bits;
int bits, c, i, bytes; RSA *key;
unsigned char *p;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR); bindtextdomain (PACKAGE, LOCALEDIR);
@ -51,54 +81,25 @@ int main(int argc, char **argv)
if(!argv[1]) if(!argv[1])
argv[1] = "1024"; argv[1] = "1024";
if(!(bits = atol(argv[1]))) bits = atol(argv[1]);
if(bits<32)
{ {
fprintf(stderr, _("Illegal number: %s\n"), argv[1]); fprintf(stderr, _("Illegal number: %s\n"), argv[1]);
return 1; return 1;
} }
bits = ((bits - 1) | 7) + 1; /* Align to bytes for easy mallocing and reading */
bits = ((bits - 1) | 63) + 1; fprintf(stderr, _("Generating %d bits keys:\n"), bits);
fprintf(stderr, _("Generating %d bits number"), bits);
bytes = bits >> 3;
if((fp = fopen("/dev/urandom", "r")) == NULL) key = RSA_generate_key(bits, RSA_PUBLIC_EXPONENT, indicator, NULL);
{
perror(_("Opening /dev/urandom"));
return 1;
}
p = xmalloc(bytes); fprintf(stderr, _("Done.\n"));
setbuf(stdout, NULL); printf(_("Public key: %s\n"), BN_bn2hex(key->n));
for(i = 0; i < bytes; i++) printf(_("Private key: %s\n"), BN_bn2hex(key->d));
{
c = fgetc(fp);
if(feof(fp))
{
puts("");
fprintf(stderr, _("File was empty!\n"));
}
p[i] = c;
}
fclose(fp);
if(isatty(1))
{
fprintf(stderr, _(": done.\nThe following line should be ENTIRELY copied into a passphrase file:\n"));
printf("%d ", bits);
for(i = 0; i < bytes; i++)
printf("%02x", p[i]);
puts("");
}
else
{
printf("%d ", bits);
for(i = 0; i < bytes; i++)
printf("%02x", p[i]);
puts("");
fprintf(stderr, _(": done.\n"));
}
return 0; return 0;
} }

735
src/net.c

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net.h,v 1.10 2000/10/18 20:12:09 zarq Exp $
*/ */
#ifndef __TINC_NET_H__ #ifndef __TINC_NET_H__
@ -23,7 +25,6 @@
#include <sys/time.h> #include <sys/time.h>
#include "config.h" #include "config.h"
#include "conf.h"
#define MAXSIZE 1700 /* should be a bit more than the MTU for the tapdevice */ #define MAXSIZE 1700 /* should be a bit more than the MTU for the tapdevice */
#define MTU 1600 #define MTU 1600
@ -43,9 +44,29 @@
((unsigned char*)&(x))[1],((unsigned char*)&(x))[0] ((unsigned char*)&(x))[1],((unsigned char*)&(x))[0]
#endif #endif
#define MAXBUFSIZE 2048 /* Probably way too much, but it must fit every possible request. */ #define MAXBUFSIZE 4096 /* Probably way too much, but it must fit every possible request. */
/* flags */
#define INDIRECTDATA 0x0001 /* Used to indicate that this host has to be reached indirect */
#define EXPORTINDIRECTDATA 0x0002 /* Used to indicate uplink that it has to tell others to do INDIRECTDATA */
#define TCPONLY 0x0004 /* Tells sender to send packets over TCP instead of UDP (for firewalls) */
typedef struct mac_t
{
unsigned char x[6];
} mac_t;
typedef unsigned long ipv4_t;
typedef ipv4_t ip_t; /* alias for ipv4_t */
typedef struct ipv6_t
{
unsigned short x[8];
} ipv6_t;
typedef unsigned short port_t;
typedef unsigned long ip_t;
typedef short length_t; typedef short length_t;
typedef struct vpn_packet_t { typedef struct vpn_packet_t {
@ -53,12 +74,6 @@ typedef struct vpn_packet_t {
unsigned char data[MAXSIZE]; unsigned char data[MAXSIZE];
} vpn_packet_t; } vpn_packet_t;
typedef struct real_packet_t {
length_t len; /* the length of the entire packet */
ip_t from; /* where the packet came from */
vpn_packet_t data; /* encrypted vpn_packet_t */
} real_packet_t;
typedef struct passphrase_t { typedef struct passphrase_t {
unsigned short len; unsigned short len;
unsigned char *phrase; unsigned char *phrase;
@ -76,9 +91,15 @@ typedef struct status_bits_t {
int validkey:1; /* 1 if we currently have a valid key for him */ int validkey:1; /* 1 if we currently have a valid key for him */
int waitingforkey:1; /* 1 if we already sent out a request */ int waitingforkey:1; /* 1 if we already sent out a request */
int dataopen:1; /* 1 if we have a valid UDP connection open */ int dataopen:1; /* 1 if we have a valid UDP connection open */
int unused:22; int encryptout:1; /* 1 if we can encrypt outgoing traffic */
int decryptin:1; /* 1 if we have to decrypt incoming traffic */
int unused:18;
} status_bits_t; } status_bits_t;
typedef struct option_bits_t {
int unused:32;
} option_bits_t;
typedef struct queue_element_t { typedef struct queue_element_t {
void *packet; void *packet;
struct queue_element_t *prev; struct queue_element_t *prev;
@ -96,31 +117,6 @@ typedef struct enc_key_t {
time_t expiry; time_t expiry;
} enc_key_t; } enc_key_t;
typedef struct conn_list_t {
ip_t vpn_ip; /* his vpn ip */
ip_t vpn_mask; /* his vpn network address */
ip_t real_ip; /* his real (internet) ip */
char *hostname; /* the hostname of its real ip */
short unsigned int port; /* his portnumber */
int socket; /* our udp vpn socket */
int meta_socket; /* our tcp meta socket */
int protocol_version; /* used protocol */
status_bits_t status; /* status info */
passphrase_t *pp; /* encoded passphrase */
packet_queue_t *sq; /* pending outgoing packets */
packet_queue_t *rq; /* pending incoming packets (they have no
valid key to be decrypted with) */
enc_key_t *public_key; /* the other party's public key */
enc_key_t *key; /* encrypt with this key */
char buffer[MAXBUFSIZE+1]; /* metadata input buffer */
int buflen; /* bytes read into buffer */
int reqlen; /* length of first request in buffer */
time_t last_ping_time; /* last time we saw some activity from the other end */
int want_ping; /* 0 if there's no need to check for activity */
struct conn_list_t *nexthop; /* nearest meta-hop in this direction */
struct conn_list_t *next; /* after all, it's a list of connections */
} conn_list_t;
extern int tap_fd; extern int tap_fd;
extern int total_tap_in; extern int total_tap_in;
@ -128,15 +124,23 @@ extern int total_tap_out;
extern int total_socket_in; extern int total_socket_in;
extern int total_socket_out; extern int total_socket_out;
extern conn_list_t *conn_list; extern char *unknown;
extern conn_list_t *myself;
extern char *request_name[256];
extern char *status_text[10];
#include "connlist.h" /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
extern int str2opt(const char *);
extern char *opt2str(int);
extern int send_packet(ip_t, vpn_packet_t *); extern int send_packet(ip_t, vpn_packet_t *);
extern int setup_network_connections(void); extern int setup_network_connections(void);
extern void close_network_connections(void); extern void close_network_connections(void);
extern void main_loop(void); extern void main_loop(void);
extern int setup_vpn_connection(conn_list_t *); extern int setup_vpn_connection(conn_list_t *);
extern void terminate_connection(conn_list_t *); extern void terminate_connection(conn_list_t *);
extern void flush_queues(conn_list_t*); extern void flush_queues(conn_list_t *);
extern int xrecv(vpn_packet_t *);
extern void add_queue(packet_queue_t **, void *, size_t);
#endif /* __TINC_NET_H__ */ #endif /* __TINC_NET_H__ */

View file

@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.c,v 1.12 2000/05/31 18:23:06 zarq Exp $ $Id: netutl.c,v 1.13 2000/10/18 20:12:09 zarq Exp $
*/ */
#include "config.h" #include "config.h"
@ -33,6 +33,7 @@
#include <utils.h> #include <utils.h>
#include <xalloc.h> #include <xalloc.h>
#include "errno.h"
#include "conf.h" #include "conf.h"
#include "encr.h" #include "encr.h"
#include "net.h" #include "net.h"
@ -40,25 +41,6 @@
#include "system.h" #include "system.h"
/*
look for a connection associated with the given vpn ip,
return its connection structure.
Skips connections that are not activated!
*/
conn_list_t *lookup_conn(ip_t ip)
{
conn_list_t *p = conn_list;
cp
/* Exact match suggested by James B. MacLean */
for(p = conn_list; p != NULL; p = p->next)
if((ip == p->vpn_ip) && p->status.active)
return p;
for(p = conn_list; p != NULL; p = p->next)
if(((ip & p->vpn_mask) == (p->vpn_ip & p->vpn_mask)) && p->status.active)
return p;
cp
return NULL;
}
/* /*
free a queue and all of its elements free a queue and all of its elements
@ -79,91 +61,7 @@ cp
cp cp
} }
/*
free a conn_list_t element and all its pointers
*/
void free_conn_element(conn_list_t *p)
{
cp
if(p->hostname)
free(p->hostname);
if(p->sq)
destroy_queue(p->sq);
if(p->rq)
destroy_queue(p->rq);
free_key(p->public_key);
free_key(p->key);
free(p);
cp
}
/*
remove all marked connections
*/
void prune_conn_list(void)
{
conn_list_t *p, *prev = NULL, *next = NULL;
cp
for(p = conn_list; p != NULL; )
{
next = p->next;
if(p->status.remove)
{
if(prev)
prev->next = next;
else
conn_list = next;
free_conn_element(p);
}
else
prev = p;
p = next;
}
cp
}
/*
creates new conn_list element, and initializes it
*/
conn_list_t *new_conn_list(void)
{
conn_list_t *p = xmalloc(sizeof(*p));
cp
/* initialise all those stupid pointers at once */
memset(p, '\0', sizeof(*p));
p->vpn_mask = (ip_t)(~0L); /* If this isn't done, it would be a
wastebucket for all packets with
unknown destination. */
p->nexthop = p;
cp
return p;
}
/*
free all elements of conn_list
*/
void destroy_conn_list(void)
{
conn_list_t *p, *next;
cp
for(p = conn_list; p != NULL; )
{
next = p->next;
free_conn_element(p);
p = next;
}
conn_list = NULL;
cp
}
/*
look up the name associated with the ip
address `addr'
*/
char *hostlookup(unsigned long addr) char *hostlookup(unsigned long addr)
{ {
char *name; char *name;
@ -175,7 +73,7 @@ cp
in.s_addr = addr; in.s_addr = addr;
lookup_hostname = 0; lookup_hostname = 0;
if((cfg = get_config_val(resolve_dns)) != NULL) if((cfg = get_config_val(config, resolve_dns)) != NULL)
if(cfg->data.val == stupid_true) if(cfg->data.val == stupid_true)
lookup_hostname = 1; lookup_hostname = 1;
@ -184,13 +82,11 @@ cp
if(!lookup_hostname || !host) if(!lookup_hostname || !host)
{ {
name = xmalloc(20); asprintf(&name, "%s", inet_ntoa(in));
sprintf(name, "%s", inet_ntoa(in));
} }
else else
{ {
name = xmalloc(strlen(host->h_name)+20); asprintf(&name, "%s", host->h_name);
sprintf(name, "%s (%s)", host->h_name, inet_ntoa(in));
} }
cp cp
return name; return name;
@ -216,7 +112,7 @@ cp
if(!(h = gethostbyname(p))) if(!(h = gethostbyname(p)))
{ {
fprintf(stderr, _("Error looking up `%s': %s\n"), p, sys_errlist[h_errno]); fprintf(stderr, _("Error looking up `%s': %s\n"), p, strerror(errno));
return NULL; return NULL;
} }
@ -236,17 +132,3 @@ cp
return ip; return ip;
} }
void dump_conn_list(void)
{
conn_list_t *p;
cp
syslog(LOG_DEBUG, _("Connection list:"));
for(p = conn_list; p != NULL; p = p->next)
{
syslog(LOG_DEBUG, " " IP_ADDR_S "/" IP_ADDR_S ": %04x (%d|%d)",
IP_ADDR_V(p->vpn_ip), IP_ADDR_V(p->vpn_mask), p->status,
p->socket, p->meta_socket);
}
cp
}

View file

@ -15,21 +15,17 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.h,v 1.3 2000/10/18 20:12:09 zarq Exp $
*/ */
#ifndef __TINC_NETUTL_H__ #ifndef __TINC_NETUTL_H__
#define __TINC_NETUTL_H__ #define __TINC_NETUTL_H__
#include "net.h" #include "net.h"
#include "conf.h"
extern conn_list_t *lookup_conn(ip_t);
extern void free_conn_element(conn_list_t *);
extern void free_conn_list(conn_list_t*);
extern void prune_conn_list(void);
extern conn_list_t *new_conn_list(void);
extern void destroy_conn_list(void);
extern char *hostlookup(unsigned long); extern char *hostlookup(unsigned long);
extern ip_mask_t *strtoip(char*); extern ip_mask_t *strtoip(char*);
extern void dump_conn_list(void);
#endif /* __TINC_NETUTL_H__ */ #endif /* __TINC_NETUTL_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
/* /*
protocol.h -- header for protocol.c protocol.h -- header for protocol.c
Copyright (C) 1999,2000 Ivo Timmermans <zarq@iname.com> Copyright (C) 1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>,
2000 Guus Sliepen <guus@sliepen.warande.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -15,60 +16,64 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.h,v 1.6 2000/10/18 20:12:09 zarq Exp $
*/ */
#ifndef __TINC_PROTOCOL_H__ #ifndef __TINC_PROTOCOL_H__
#define __TINC_PROTOCOL_H__ #define __TINC_PROTOCOL_H__
#include "net.h" #include "net.h"
#include "subnet.h"
/* Protocol version. Different versions are incompatible,
incompatible version have different protocols.
*/
#define PROT_CURRENT 8
/* Length of the challenge. Since the challenge will also
contain the key for the symmetric cipher, it must be
quite large.
*/
#define CHAL_LENGTH 1024 /* Okay, this is probably waaaaaaaaaaay too large */
/* Request numbers */
enum { enum {
PROT_RESERVED = 0, /* reserved: do not use. */ ALL = -1, /* Guardian for allow_request */
PROT_NOT_IN_USE, ID = 0, CHALLENGE, CHAL_REPLY, ACK,
PROT_TOO_OLD = 2, STATUS, ERROR, TERMREQ,
PROT_3, PING, PONG,
PROT_4, ADD_HOST, DEL_HOST,
PROT_ECHELON, ADD_SUBNET, DEL_SUBNET,
PROT_CURRENT, /* protocol currently in use */ KEY_CHANGED, REQ_KEY, ANS_KEY,
LAST /* Guardian for the highest request number */
}; };
enum { extern int (*request_handlers[])(conn_list_t*);
ACK = 1, /* acknowledged */
AUTH_S_INIT = 10, /* initiate authentication */
AUTH_C_INIT,
AUTH_S_SPP, /* send passphrase */
AUTH_C_SPP,
AUTH_S_SKEY, /* send g^k */
AUTH_C_SKEY,
AUTH_S_SACK, /* send ack */
AUTH_C_RACK, /* waiting for ack */
TERMREQ = 30, /* terminate connection */
PINGTIMEOUT, /* terminate due to ping t.o. */
DEL_HOST, /* forward a termreq to others */
PING = 40, /* ping */
PONG,
ADD_HOST = 60, /* Add new given host to connection list */
BASIC_INFO, /* some basic info follows */
PASSPHRASE, /* encrypted passphrase */
PUBLIC_KEY, /* public key in base-36 */
HOLD = 80, /* don't send any data */
RESUME, /* resume dataflow with new encryption key */
CALCULATE = 100, /* calculate the following numer^privkey and send me the result */
CALC_RES, /* result of the above */
ALMOST_KEY, /* this number^privkey is the shared key */
REQ_KEY = 160, /* request public key */
ANS_KEY, /* answer to such request */
KEY_CHANGED, /* public key has changed */
};
extern int (*request_handlers[256])(conn_list_t*);
extern int send_id(conn_list_t*);
extern int send_challenge(conn_list_t*);
extern int send_chal_reply(conn_list_t*);
extern int send_ack(conn_list_t*);
extern int send_status(conn_list_t*, int, char*);
extern int send_error(conn_list_t*, int, char*);
extern int send_termreq(conn_list_t*);
extern int send_ping(conn_list_t*); extern int send_ping(conn_list_t*);
extern int send_basic_info(conn_list_t *); extern int send_pong(conn_list_t*);
extern int send_termreq(conn_list_t *); extern int send_add_host(conn_list_t*, conn_list_t*);
extern int send_timeout(conn_list_t *); extern int send_del_host(conn_list_t*, conn_list_t*);
extern int send_key_request(ip_t); extern int send_add_subnet(conn_list_t*, conn_list_t*, subnet_t*);
extern void send_key_changed_all(void); extern int send_del_subnet(conn_list_t*, conn_list_t*, subnet_t*);
extern int send_key_changed(conn_list_t*, conn_list_t*);
extern int send_req_key(conn_list_t*, conn_list_t*);
extern int send_ans_key(conn_list_t*, conn_list_t*, char*);
/* Old functions */
extern int send_tcppacket(conn_list_t *, void *, int);
extern int notify_others(conn_list_t *, conn_list_t *, int (*function)(conn_list_t*, conn_list_t*));
#endif /* __TINC_PROTOCOL_H__ */ #endif /* __TINC_PROTOCOL_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: tincd.c,v 1.10 2000/05/31 18:23:06 zarq Exp $ $Id: tincd.c,v 1.11 2000/10/18 20:12:10 zarq Exp $
*/ */
#include "config.h" #include "config.h"
@ -30,6 +30,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <syslog.h> #include <syslog.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>
#ifdef HAVE_SYS_IOCTL_H #ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h> # include <sys/ioctl.h>
@ -43,6 +44,7 @@
#include "encr.h" #include "encr.h"
#include "net.h" #include "net.h"
#include "netutl.h" #include "netutl.h"
#include "protocol.h"
#include "system.h" #include "system.h"
@ -61,10 +63,7 @@ static int kill_tincd = 0;
/* If zero, don't detach from the terminal. */ /* If zero, don't detach from the terminal. */
static int do_detach = 1; static int do_detach = 1;
char *confbase = NULL; /* directory in which all config files are */
char *configfilename = NULL; /* configuration file name */
char *identname; /* program name for syslog */ char *identname; /* program name for syslog */
char *netname = NULL; /* name of the vpn network */
char *pidfilename; /* pid file location */ char *pidfilename; /* pid file location */
static pid_t ppid; /* pid of non-detached part */ static pid_t ppid; /* pid of non-detached part */
char **g_argv; /* a copy of the cmdline arguments */ char **g_argv; /* a copy of the cmdline arguments */
@ -96,7 +95,7 @@ usage(int status)
else else
{ {
printf(_("Usage: %s [option]...\n\n"), program_name); printf(_("Usage: %s [option]...\n\n"), program_name);
printf(_(" -c, --config=FILE Read configuration options from FILE.\n" printf(_(" -c, --config=DIR Read configuration options from DIR.\n"
" -D, --no-detach Don't fork and detach.\n" " -D, --no-detach Don't fork and detach.\n"
" -d Increase debug level.\n" " -d Increase debug level.\n"
" -k, --kill Attempt to kill a running tincd and exit.\n" " -k, --kill Attempt to kill a running tincd and exit.\n"
@ -123,8 +122,8 @@ parse_options(int argc, char **argv, char **envp)
case 0: /* long option */ case 0: /* long option */
break; break;
case 'c': /* config file */ case 'c': /* config file */
configfilename = xmalloc(strlen(optarg)+1); confbase = xmalloc(strlen(optarg)+1);
strcpy(configfilename, optarg); strcpy(confbase, optarg);
break; break;
case 'D': /* no detach */ case 'D': /* no detach */
do_detach = 0; do_detach = 0;
@ -156,7 +155,7 @@ parse_options(int argc, char **argv, char **envp)
void memory_full(int size) void memory_full(int size)
{ {
syslog(LOG_ERR, _("Memory exhausted (last is %s:%d) (couldn't allocate %d bytes); exiting."), cp_file, cp_line, size); syslog(LOG_ERR, _("Memory exhausted (last is %s:%d) (couldn't allocate %d bytes), exiting."), cp_file, cp_line, size);
exit(1); exit(1);
} }
@ -180,7 +179,7 @@ int detach(void)
if(pid) /* parent process */ if(pid) /* parent process */
{ {
signal(SIGTERM, parent_exit); signal(SIGTERM, parent_exit);
sleep(600); /* wait 10 minutes */ // sleep(600); /* wait 10 minutes */
exit(1); exit(1);
} }
} }
@ -210,11 +209,11 @@ int detach(void)
openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON); openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON);
if(debug_lvl > 1) if(debug_lvl > 0)
syslog(LOG_NOTICE, _("tincd %s (%s %s) starting, debug level %d."), syslog(LOG_NOTICE, _("tincd %s (%s %s) starting, debug level %d"),
VERSION, __DATE__, __TIME__, debug_lvl); VERSION, __DATE__, __TIME__, debug_lvl);
else else
syslog(LOG_NOTICE, _("tincd %s starting, debug level %d."), VERSION, debug_lvl); syslog(LOG_NOTICE, _("tincd %s starting"), VERSION, debug_lvl);
xalloc_fail_func = memory_full; xalloc_fail_func = memory_full;
@ -229,7 +228,7 @@ void cleanup_and_exit(int c)
close_network_connections(); close_network_connections();
if(debug_lvl > 0) if(debug_lvl > 0)
syslog(LOG_INFO, _("Total bytes written: tap %d, socket %d; bytes read: tap %d, socket %d."), syslog(LOG_INFO, _("Total bytes written: tap %d, socket %d; bytes read: tap %d, socket %d"),
total_tap_out, total_socket_out, total_tap_in, total_socket_in); total_tap_out, total_socket_out, total_tap_in, total_socket_in);
closelog(); closelog();
@ -291,35 +290,24 @@ int kill_other(void)
*/ */
void make_names(void) void make_names(void)
{ {
if(!configfilename)
{
if(netname)
{
configfilename = xmalloc(strlen(netname)+18+strlen(CONFDIR));
sprintf(configfilename, "%s/tinc/%s/tinc.conf", CONFDIR, netname);
}
else
{
configfilename = xmalloc(17+strlen(CONFDIR));
sprintf(configfilename, "%s/tinc/tinc.conf", CONFDIR);
}
}
if(netname) if(netname)
{ {
pidfilename = xmalloc(strlen(netname)+20); if(!pidfilename)
sprintf(pidfilename, "/var/run/tinc.%s.pid", netname); asprintf(&pidfilename, "/var/run/tinc.%s.pid", netname);
confbase = xmalloc(strlen(netname)+8+strlen(CONFDIR)); if(!confbase)
sprintf(confbase, "%s/tinc/%s/", CONFDIR, netname); asprintf(&confbase, "%s/tinc/%s", CONFDIR, netname);
identname = xmalloc(strlen(netname)+7); if(!identname)
sprintf(identname, "tinc.%s", netname); asprintf(&identname, "tinc.%s", netname);
} }
else else
{ {
pidfilename = "/var/run/tinc.pid"; netname = "bla";
confbase = xmalloc(7+strlen(CONFDIR)); if(!pidfilename)
sprintf(confbase, "%s/tinc/", CONFDIR); pidfilename = "/var/run/tinc.pid";
identname = "tinc"; if(!confbase)
asprintf(&confbase, "%s/tinc", CONFDIR);
if(!identname)
identname = "tinc";
} }
} }
@ -332,17 +320,20 @@ main(int argc, char **argv, char **envp)
bindtextdomain (PACKAGE, LOCALEDIR); bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE); textdomain (PACKAGE);
/* Do some intl stuff right now */
unknown = _("unknown");
parse_options(argc, argv, envp); parse_options(argc, argv, envp);
if(show_version) if(show_version)
{ {
printf(_("%s version %s\n"), PACKAGE, VERSION); printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE, VERSION, __DATE__, __TIME__, PROT_CURRENT);
printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans and others,\n" printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans, Guus Sliepen and others.\n"
"see the AUTHORS file for a complete list.\n\n" "See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n" "and you are welcome to redistribute it under certain conditions;\n"
"see the file COPYING for details.\n\n")); "see the file COPYING for details.\n"));
printf(_("This product includes software developed by Eric Young (eay@mincom.oz.au)\n"));
return 0; return 0;
} }
@ -352,7 +343,7 @@ main(int argc, char **argv, char **envp)
if(geteuid()) if(geteuid())
{ {
fprintf(stderr, _("You must be root to run this program. sorry.\n")); fprintf(stderr, _("You must be root to run this program. Sorry.\n"));
return 1; return 1;
} }
@ -363,7 +354,7 @@ main(int argc, char **argv, char **envp)
if(kill_tincd) if(kill_tincd)
exit(kill_other()); exit(kill_other());
if(read_config_file(configfilename)) if(read_server_config())
return 1; return 1;
setup_signals(); setup_signals();
@ -371,16 +362,32 @@ main(int argc, char **argv, char **envp)
if(detach()) if(detach())
exit(0); exit(0);
/* FIXME: wt* is this suppose to do?
if(security_init()) if(security_init())
return 1; return 1;
*/
for(;;)
{
if(!setup_network_connections())
{
main_loop();
cleanup_and_exit(1);
}
syslog(LOG_ERR, _("Unrecoverable error"));
cp_trace();
if(setup_network_connections()) if(do_detach)
cleanup_and_exit(1); {
syslog(LOG_NOTICE, _("Restarting in %d seconds!"), MAXTIMEOUT);
main_loop(); sleep(MAXTIMEOUT);
}
cleanup_and_exit(1); else
return 1; {
syslog(LOG_ERR, _("Aieee! Not restarting."));
exit(0);
}
}
} }
RETSIGTYPE RETSIGTYPE
@ -402,41 +409,45 @@ sigquit_handler(int a)
RETSIGTYPE RETSIGTYPE
sigsegv_square(int a) sigsegv_square(int a)
{ {
syslog(LOG_NOTICE, _("Got another SEGV signal: not restarting")); syslog(LOG_ERR, _("Got another SEGV signal: not restarting"));
exit(0); exit(0);
} }
RETSIGTYPE RETSIGTYPE
sigsegv_handler(int a) sigsegv_handler(int a)
{ {
if(cp_file) syslog(LOG_ERR, _("Got SEGV signal"));
syslog(LOG_NOTICE, _("Got SEGV signal after %s line %d. Trying to re-execute."), cp_trace();
cp_file, cp_line);
if(do_detach)
{
syslog(LOG_NOTICE, _("Trying to re-execute in 5 seconds..."));
signal(SIGSEGV, sigsegv_square);
close_network_connections();
sleep(5);
remove_pid(pidfilename);
execvp(g_argv[0], g_argv);
}
else else
syslog(LOG_NOTICE, _("Got SEGV signal; trying to re-execute.")); {
syslog(LOG_NOTICE, _("Aieee! Not restarting."));
signal(SIGSEGV, sigsegv_square); exit(0);
}
close_network_connections();
remove_pid(pidfilename);
execvp(g_argv[0], g_argv);
} }
RETSIGTYPE RETSIGTYPE
sighup_handler(int a) sighup_handler(int a)
{ {
if(debug_lvl > 0) if(debug_lvl > 0)
syslog(LOG_NOTICE, _("Got HUP signal")); syslog(LOG_NOTICE, _("Got HUP signal, rereading configuration and restarting"));
close_network_connections(); sighup = 1;
setup_network_connections();
/* FIXME: read config-file and re-establish network connections */
} }
RETSIGTYPE RETSIGTYPE
sigint_handler(int a) sigint_handler(int a)
{ {
if(debug_lvl > 0) if(debug_lvl > 0)
syslog(LOG_NOTICE, _("Got INT signal")); syslog(LOG_NOTICE, _("Got INT signal, exiting"));
cleanup_and_exit(0); cleanup_and_exit(0);
} }
@ -450,18 +461,17 @@ RETSIGTYPE
sigusr2_handler(int a) sigusr2_handler(int a)
{ {
if(debug_lvl > 1) if(debug_lvl > 1)
syslog(LOG_NOTICE, _("Forcing new key generation")); syslog(LOG_NOTICE, _("Got USR2 signal, forcing new key generation"));
/* FIXME: reprogram this.
regenerate_keys(); regenerate_keys();
*/
} }
RETSIGTYPE RETSIGTYPE
sighuh(int a) sighuh(int a)
{ {
if(cp_file) syslog(LOG_WARNING, _("Got unexpected signal %d (%s)"), a, strsignal(a));
syslog(LOG_NOTICE, _("Got unexpected signal (%d) after %s line %d."), cp_trace();
a, cp_file, cp_line);
else
syslog(LOG_NOTICE, _("Got unexpected signal (%d)."), a);
} }
void void
@ -485,7 +495,7 @@ setup_signals(void)
signal(SIGINT, sigint_handler); signal(SIGINT, sigint_handler);
signal(SIGUSR1, sigusr1_handler); signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler); signal(SIGUSR2, sigusr2_handler);
signal(SIGCHLD, parent_exit); // signal(SIGCHLD, parent_exit);
} }
RETSIGTYPE parent_exit(int a) RETSIGTYPE parent_exit(int a)