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:
* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from
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
SUBDIRS = m4 intl lib cipher src doc po redhat debian
SUBDIRS = m4 intl lib src doc po redhat debian
ACLOCAL_AMFLAGS =
@ -16,7 +16,7 @@ ChangeLog:
rm -f ChangeLog
rcs2log -u "zarq Ivo Timmermans itimmermans@bigfoot.com" \
-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
for f in $(CVS_CREATED) `find -name Makefile.in` ; do\
@ -25,3 +25,9 @@ cvs-clean: maintainer-clean
deb:
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
<itimmermans@bigfoot.com>, Guus Sliepen <guus@sliepen.warande.net> and
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
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
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
install this first even before trying to run configure. If you don't
do this, configure will (hopefully) mention it to you.
Requirements
------------
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
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
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
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
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
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
documentation, and for making several suggestions to make it all
more userfriendly)
* James B. MacLean (for fixing several mission critical bugs, and for
more userfriendly, and the Redhat package)
* James MacLean (for fixing several mission critical bugs, and for
giving me a few good ideas, and, most of all, for the wonderful
testing and debugging)
* Cris van Pelt
* Robert van der Meulen
* Sander Smeenk
* Tijs van Bakel
* Wessel Dankers (for the name `tinc' and being a royal pain in the
ass (je hebt erom gevraagd))
* Robert van der Meulen (early configuration code)
* Cris van Pelt (small fixes)
* Enrique Zanardi (for the Spanish translation)
* Matias Carrasco (for the Spanish translation of the manual)
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...

2
TODO
View file

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

View file

@ -43,3 +43,13 @@
# include <stdlib.h>
# undef getopt
#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 $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)
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.
AC_DEFINE([_GNU_SOURCE], [__USE_BSD])
ALL_LINGUAS="nl"
ALL_LINGUAS="es nl"
dnl Checks for programs.
AC_PROG_CC
@ -33,8 +33,7 @@ dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h syslog.h unistd.h gmp.h gmp2/gmp.h \
sys/time.h)
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h syslog.h unistd.h sys/time.h linux/if_tun.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@ -53,32 +52,38 @@ jm_FUNC_REALLOC
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, [
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])

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
* 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
Maintainer: Ivo Timmermans <itimmermans@bigfoot.com>
Standards-Version: 3.0.1
Build-Depends: libc6-dev, libgmp2-dev
Build-Depends: libc6-dev, libssl095a-dev, autoconf (>= 2.12), automake,
Package: tinc
Architecture: i386
Depends: ${shlibs:Depends}, libgmp2, perl5
Depends: ${shlibs:Depends}, (libssl095a|libssl09), perl5
Description: Virtual Private Network daemon
tinc is a daemon with which you can create a virtual private network
(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
#
# 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.
#
@ -68,6 +68,7 @@ sub vpn_load {
chomp($VPN);
} elsif ( /^[ ]*VpnMask[ =]+([^ \#]+)/i ) {
$VPNMASK=$1;
chomp($VPNMASK);
}
}
if(!defined($DEV)) {
@ -108,10 +109,8 @@ sub vpn_load {
if(!defined($VPNMASK)) {
$VPNMASK = $MSK;
$VPNMASK = join(".", unpack('C4', $VPNMASK));
}
$VPNMASK = pack('C4', split(/\./, $VPNMASK));
$VPNMASK = join(".", unpack('C4', $VPNMASK));
$ADR = join(".", unpack('C4', $ADR));
$MSK = join(".", unpack('C4', $MSK));

2
debian/rules vendored
View file

@ -32,7 +32,7 @@ install: build
dh_clean -k
dh_installdirs
$(MAKE) install prefix=`pwd`/debian/tmp/usr
$(MAKE) install DESTDIR=`pwd`/debian/tmp
mkdir -p `pwd`/debian/tmp/etc/tinc/example
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

View file

@ -1,11 +1,13 @@
## Process this file with automake to get Makefile.in
SUBDIRS = es
info_TEXINFOS = tinc.texi
dyn_MANS = tincd.8
dyn_MANS =
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@
HELP2MAN = help2man

View file

@ -59,67 +59,104 @@ one space character.
.PP
.SH "VARIABLES"
.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
\fBConnectPort = \fIport\fR
Connect to the upstream host (given with the \fBConnectTo\fR
directive) on port \fIport\fR. \fIport\fR may be given in decimal
(default), octal (when preceded by a single zero) or hexadecimal
(prefixed with \fB0x\fR). \fIport\fR is the port number for both the
UDP and the TCP (meta) connections.
\fBConnectPort\fR = <\fIport\fR> (655)
Connect to the upstream host (given with the \fBConnectTo\fR directive) on
port \fIport\fR. port may be given in decimal (default), octal (when preceded
by a single zero) or hexadecimal (prefixed with 0x). \fIport\fR is the port
number for both the UDP and the TCP (meta) connections.
.TP
\fBConnectTo = \fB(\fIIP address\fB|\fIhostname\fB)\fR
Specifies which host to connect to on startup. If the
\fBConnectPort\fR variable is omitted, then tinc will try to connect
to port 655.
\fBConnectTo\fR = <\fIIP address|hostname\fR> (optional)
Specifies which host to connect to on startup. Multiple \fBConnectTo\fR variables
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 \fBConnectTo\fR, tinc won't connect
at all, and will instead just listen for incoming connections. Only
the initiator of a tinc VPN should need this.
If you don't specify a host with \fBConnectTo\fR, regardless of whether a
value for \fBConnectPort\fR is given, tinc won't connect at all, and will
instead just listen for incoming connections.
.TP
\fBKeyExpire = \fIs\fR
The secret (and public) key expires after \fIs\fR seconds. The default
is 3600 seconds, or one hour.
\fBHostnames\fR = <\fIyes|no\fR> (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.
If you make it shorter, a lot of time and bandwidth is spent
negotiating over the new keys. If you make it longer, you make
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.
This does not affect resolving hostnames to IP addresses from the configuration
file.
.TP
\fBListenPort = \fIport\fR
Listen on local port \fIport\fR. The computer connecting to this
daemon should use this number as the argument for his
\fBConnectPort\fR. Again, the default is 655.
\fBIndirectData\fR = <\fIyes|no\fR> (no)
This option specifies whether other tinc daemons besides the one you
specified with \fBConnectTo\fR 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.
.TP
\fBMyOwnVPNIP = \fInetwork address\fR[\fB/\fImaskbits\fR]
The \fInetwork 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.
\fBInterface\fR = <\fIdevice\fR> (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.
.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.
.TP
\fBMyVirtualIP = \fInetwork address\fR[\fB/\fImaskbits\fR]
\fBMyVirtualIP\fR = <\fIlocal address[/maskbits]>
This is an alias for \fBMyOwnVPNIP\fR.
.TP
\fBPassphrases = \fIdirectory\fR
The directory where tinc will look for passphrases when someone tries
to cennect. Please see the manpage for \fBgenauth\fR(8) for more
information about passphrases as used by tinc.
\fBPassphrases\fR = <\fIdirectory\fR> (/etc/tinc/NETNAME/passphrases)
The directory where tinc will look for passphrases when someone tries to
connect. Please see the manpage for genauth(8) for more information
about passphrases as used by tinc.
.TP
\fBPingTimeout = \fInumber\fR
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
\fBPingTimeout\fR = <\fIseconds\fR> (5)
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
same amount of seconds, the connection is terminated, and the others
will be notified of this.
.TP
\fBTapDevice = \fIdevice\fR
\fBTapDevice\fR = <\fIdevice\fR> (/dev/tap0)
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
about configuring an ethertap device for linux.
about configuring an ethertap device for Linux.
.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
by the tinc daemon itself, but can be used by startup scripts to configure
the ethertap devices correctly.

View file

@ -1,4 +1,5 @@
\input texinfo @c -*-texinfo-*-
@c $Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
@c %**start of header
@setfilename tinc.info
@settitle tinc Manual
@ -12,40 +13,45 @@
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
copies of this manual provided the copyright notice and
this permission notice are preserved on all copies.
$Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
Permission is granted to copy and distribute modified
versions of this 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.
Permission is granted to make and distribute verbatim 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 versions of this
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
@titlepage
@title tinc Manual
@subtitle Setting up a Virtual Private Network with tinc
@author Ivo Timmermans <itimmermans@@bigfoot.com>
@author Ivo Timmermans and Guus Sliepen
@page
@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
copies of this manual provided the copyright notice and
this permission notice are preserved on all copies.
$Id: tinc.texi,v 1.9 2000/10/18 20:12:06 zarq Exp $
Permission is granted to copy and distribute modified
versions of this 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.
Permission is granted to make and distribute verbatim 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 versions of this
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
@ -54,8 +60,8 @@ Copyright @copyright{} 1998,1999,2000 Ivo Timmermans <itimmermans@@bigfoot.com>
@menu
* Introduction:: Introduction
* Configuring a Linux system:: Before compiling tinc
* Installing tinc::
* Installing tinc - preparations::
* Installing tinc - installation::
* Configuring tinc::
* Running tinc::
* Technical information::
@ -63,12 +69,14 @@ Copyright @copyright{} 1998,1999,2000 Ivo Timmermans <itimmermans@@bigfoot.com>
* Concept Index:: All used terms explained
@end menu
@contents
@c ==================================================================
@node Introduction, Configuring a Linux system, Top, Top
@node Introduction, Installing tinc - preparations, Top, Top
@chapter Introduction
@c straight from the www page
@cindex tinc
tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
encryption to create a secure private network between hosts on the
Internet.
@ -86,12 +94,14 @@ process of tinc itself.
@menu
* VPNs:: Virtual Private Networks in general
* tinc:: about tinc
* Supported platforms::
@end menu
@c ==================================================================
@node VPNs, tinc, Introduction, Introduction
@section Virtual Private Networks
@cindex VPN
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
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
even two computers hooked up using a null-modem cable. In these cases,
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
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
@ -131,9 +141,11 @@ that flows over the network.
@c ==================================================================
@node tinc, , VPNs, Introduction
@node tinc, Supported platforms, VPNs, Introduction
@section tinc
@cindex vpnd
@cindex ethertap
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
used the @emph{ethertap} device that Linux knows of since somewhere
@ -158,23 +170,101 @@ available too.
@c ==================================================================
@node Configuring a Linux system, Installing tinc, Introduction, Top
@chapter Configuring a Linux system
@node Supported platforms, , tinc, Introduction
@section Supported platforms
This chapter contains information on how a Linux system is configured
for the use of tinc.
tinc works on Linux, FreeBSD and Solaris. These are the three platforms
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
* Configuring the kernel::
* Files Needed::
* Setting up the devices::
* Libraries::
@end menu
@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
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
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
@ -185,9 +275,11 @@ new kernel, you should read the
@uref{http://howto.linuxberg.com/LDP/HOWTO/Kernel-HOWTO.html, Kernel
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.
For kernel 2.2.x:
@example
Code maturity level options
[*] Prompt for development and/or incomplete code/drivers
@ -198,6 +290,19 @@ Network device support
<*> Ethertap network tap
@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
decide to build any of these as dynamic kernel modules, it's a good idea
to add these lines to @file{/etc/modules.conf}.
@ -207,34 +312,179 @@ alias tap0 ethertap
alias char-major-36 netlink_dev
@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
it. Unfortunately it's not possible to insert these modules in a running
kernel.
it. Unfortunately it's not possible to insert these modules in a
running kernel.
@c ==================================================================
@node Files Needed, Setting up the devices, Configuring the kernel, Configuring a Linux system
@section Files Needed
@node Configuration of the FreeBSD kernel, Configuration of the Solaris kernel, Configuration of the Linux kernel, Configuring the kernel
@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
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
mknod -m 600 /dev/tap0 c 36 16
chown 0.0 /dev/tap0
@end example
The permissions now will 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.
Any further ethertap devices have minor device number 16 through 31.
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}
@ -245,6 +495,9 @@ symbolic name. For example:
myvpn 10.0.0.0
@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}
@ -260,15 +513,15 @@ tinc 655/udp TINC
@c ==================================================================
@node Setting up the devices, , Files Needed, Configuring a Linux system
@section Setting up the devices
@node Interfaces, , System files, Installing tinc - installation
@section Interfaces
Before you can start transmitting data over the tinc tunnel, you must
set up the ethertap network devices.
First, decide which IP addresses you want to have associated with these
devices, and what network mask they must have. You also need these
numbers when you are going to configure tinc itself. @xref{Configuring
devices, and what network mask they must have. You also need these
numbers when you are going to configure tinc itself. @xref{Configuring
tinc}.
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}
@end example
The @emph{n} here is the number of the ethertap device you want to
use. 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
The @emph{n} here is the number of the ethertap device you want to use.
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
(0--ff). With previous versions of tincd, it didn't matter what they
were. But newer kernels require properly set up ethernet addresses.
In fact, the old behavior was wrong. It is required that the @emph{xx}s
match MyOwnVPNIP.
were. But newer kernels require properly set up ethernet addresses. In
fact, the old behavior was wrong. It is required that the @emph{xx}s
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
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
This will activate the device with an IP address @emph{IP} with network
mask @emph{mask}.
@cindex ifconfig
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 ==================================================================
@node Installing tinc, Configuring tinc, Configuring a Linux system, Top
@chapter Installing tinc
First download it. This is 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.
@c
@c
@c
@c
@c Configuring tinc
@c
@c
@c
@c
@c ==================================================================
@node Configuring tinc, Running tinc, Installing tinc, Top
@node Configuring tinc, Running tinc, Installing tinc - installation, Top
@chapter Configuring tinc
@menu
@ -327,7 +590,6 @@ included in the source distribution.
* Example::
@end menu
@c ==================================================================
@node Multiple networks, How connections work, Configuring tinc, Configuring tinc
@section Multiple networks
@ -395,31 +657,67 @@ out, remember to replace it with at least one space character.
@node Variables, , Configuration file, Configuration file
@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
@table @asis
@item ConnectPort = port
@item ConnectPort = <port> (655)
Connect to the upstream host (given with the ConnectTo directive) on
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
number for both the UDP and the TCP (meta) connections.
@item ConnectTo = (IP address|hostname)
Specifies which host to connect to on startup. If the ConnectPort
variable is omitted, then tinc will try to connect to port 655.
@item ConnectTo = <IP address|hostname> (optional)
Specifies which host to connect to on startup. Multiple ConnectTo variables
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
value for ConnectPort is given, tinc won't connect at all, and will
instead just listen for incoming connections. Only the initiator of a
tinc VPN should need this.
instead just listen for incoming connections.
@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
use this number as the argument for his ConnectPort. Again, the
default is 655.
use this number as the argument for his ConnectPort.
@item MyOwnVPNIP = local address[/maskbits]
@item MyOwnVPNIP = <local address[/maskbits]> (required)
The local address 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
@ -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.
@item MyVirtualIP = local address[/maskbits]
@item MyVirtualIP = <local address[/maskbits]>
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
connect. Please see the manpage for genauth(8) for more information
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
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
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
daemon. The info pages of the tinc package contain more information
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
by the tinc daemon itself, but can be used by startup scripts to configure
the ethertap devices correctly.
@end table
@c ==================================================================
@node Example, , Configuration file, Configuring tinc
@section Example
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
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).
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
that leads to the internet.
the inner LAN of the office, although this could also be the same as the
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
@emph{A} would be configured like this:
@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 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
and in /etc/tinc/tinc.conf:
@ -507,9 +816,9 @@ VpnMask = 255.0.0.0
@subsubheading For B
@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 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
and in /etc/tinc/tinc.conf:
@ -528,30 +837,33 @@ connect to this node.
@subsubheading For C
@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 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
and in /etc/tinc/A/tinc.conf:
@example
MyVirtualIP = 10.3.69.254/16
TapDevice = /dev/tap1
ConnectTo = 1.2.3.4
ListenPort = 2000
VpnMask = 255.0.0.0
@end example
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'.
@subsubheading For D
@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 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
and in /etc/tinc/tinc.conf:
@ -564,7 +876,8 @@ VpnMask=255.0.0.0
@end example
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
@ -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
/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
@ -810,16 +1123,47 @@ This chapter is a mixture of ideas, reasoning and explanation, please
don't take it too serious.
@menu
* Key Types::
* Key Management::
* Authentication::
* Protection::
@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 ==================================================================
@node Key Management, Authentication, Security, Security
@node Key Management, Authentication, Key Types, Security
@subsection Key Management
@c FIXME: recheck
@c FIXME change for the current protocol
@cindex Diffie-Hellman
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
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
still secret key.
@ -864,17 +1204,25 @@ system.
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
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
@c ehrmz... but we only use 1024 bits passphrases ourselves? [guus]
This passphrase should be 2304 bits for a symmetric encryption
system. But since an asymmetric system is more secure, we could do with
2048 bits. This only holds if the passphrase is very random.
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
passphrase to B.
The only thing that needs to be taken care of is how A can securely send
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 ==================================================================
@ -884,6 +1232,7 @@ passphrase to B.
Now we have securely hidden our data. But a malicious cracker may still
bother you by randomly altering the encrypted data he intercepts.
@c FIXME what the hell is this all about? remove? IT
@c ==================================================================
@node About us, Concept Index, Technical information, Top

View file

@ -1,8 +1,9 @@
## 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
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

View file

@ -1,6 +1,7 @@
/*
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
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.
*/
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include "config.h"
#include <utils.h>
#include <syslog.h>
volatile int cp_line;
volatile char *cp_file;
volatile int (cp_line[]) = {0, 0, 0, 0, 0, 0, 0, 0};
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
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
it under the terms of the GNU General Public License as published by
@ -20,11 +21,27 @@
#ifndef __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 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;
extern volatile char *cp_file;
#define cp { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 8; }
#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__ */

View file

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

View file

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

View file

@ -4,10 +4,12 @@
# Package source files
lib/pidfile.c
lib/utils.c
src/conf.c
src/encr.c
src/genauth.c
src/meta.c
src/net.c
src/netutl.c
src/protocol.c
src/subnet.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
Name: tinc
Version: 1.0pre2
Version: 1.0pre3
Release: 1
Copyright: GPL
Group: System Environment/Daemons

View file

@ -1,17 +1,18 @@
## 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
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
genauth_LDADD = $(top_builddir)/lib/libvpn.a

View file

@ -19,52 +19,63 @@
along with this program; if not, write to the Free Software
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 <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <xalloc.h>
#include "conf.h"
#include "netutl.h" /* for strtoip */
#include <utils.h> /* for cp */
#include "config.h"
#include "connlist.h"
#include "system.h"
config_t *config;
config_t *config = NULL;
int debug_lvl = 0;
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 {
char *name;
enum which_t which;
int argtype;
} internal_config_t;
/* Will be set if HUP signal is received. It will be processed when it is safe. */
int sighup = 0;
/*
These are all the possible configurable values
*/
static internal_config_t hazahaza[] = {
{ "AllowConnect", allowconnect, TYPE_BOOL }, /* Is not used anywhere. Remove? */
{ "ConnectTo", upstreamip, TYPE_IP },
{ "ConnectPort", upstreamport, TYPE_INT },
{ "ListenPort", listenport, TYPE_INT },
{ "MyOwnVPNIP", myvpnip, TYPE_IP },
{ "MyVirtualIP", myvpnip, TYPE_IP }, /* an alias */
{ "Passphrases", passphrasesdir, TYPE_NAME },
/* Main configuration file keywords */
{ "Name", tincname, TYPE_NAME },
{ "ConnectTo", connectto, TYPE_NAME },
{ "PingTimeout", pingtimeout, TYPE_INT },
{ "TapDevice", tapdevice, TYPE_NAME },
{ "TapSubnet", tapsubnet, TYPE_IP },
{ "PrivateKey", privatekey, TYPE_NAME },
{ "KeyExpire", keyexpire, TYPE_INT },
{ "VpnMask", vpnmask, TYPE_IP },
{ "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 }
};
@ -74,12 +85,12 @@ static internal_config_t hazahaza[] = {
config_t *
add_config_val(config_t **cfg, int argtype, char *val)
{
config_t *p;
config_t *p, *r;
char *q;
cp
p = (config_t*)xmalloc(sizeof(*p));
p->data.val = 0;
switch(argtype)
{
case TYPE_INT:
@ -103,46 +114,57 @@ add_config_val(config_t **cfg, int argtype, char *val)
p->data.val = 0;
}
p->argtype = argtype;
if(p->data.val)
{
p->next = *cfg;
*cfg = p;
cp
return p;
}
free(p);
return NULL;
else
{
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
readconfig(const char *fname, FILE *fp)
int read_config_file(config_t **base, const char *fname)
{
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;
int i, lineno = 0;
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(;;)
{
if(fgets(line, 80, fp) == NULL)
return 0;
while(!index(line, '\n'))
if(fgets(line, MAXBUFSIZE, fp) == NULL)
{
fgets(temp_buf, (strlen(line)+1) * 80, fp);
if(!temp_buf)
break;
strcat(line, temp_buf);
line = (char *)xrealloc(line, (strlen(line)+1) * sizeof(char));
}
err = 0;
break;
}
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)
continue; /* no tokens on this line */
@ -155,66 +177,92 @@ readconfig(const char *fname, FILE *fp)
if(!hazahaza[i].name)
{
fprintf(stderr, _("%s: %d: Invalid variable name `%s'.\n"),
fname, lineno, p);
return -1;
syslog(LOG_ERR, _("Invalid variable name on line %d while reading config file %s"),
lineno, fname);
break;
}
if(((q = strtok(NULL, "\t\n\r =")) == NULL) || q[0] == '#')
{
fprintf(stderr, _("%s: %d: No value given for `%s'.\n"),
fname, lineno, hazahaza[i].name);
return -1;
fprintf(stderr, _("No value for variable on line %d while reading config file %s"),
lineno, fname);
break;
}
cfg = add_config_val(&config, hazahaza[i].argtype, q);
cfg = add_config_val(base, hazahaza[i].argtype, q);
if(cfg == NULL)
{
fprintf(stderr, _("%s: %d: Invalid value `%s' for variable `%s'.\n"),
fname, lineno, q, hazahaza[i].name);
return -1;
fprintf(stderr, _("Invalid value for variable on line %d while reading config file %s"),
lineno, fname);
break;
}
cfg->which = hazahaza[i].which;
if(!config)
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);
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
*/
const config_t *
get_config_val(which_t type)
const config_t *get_config_val(config_t *p, which_t type)
{
config_t *p;
for(p = config; p != NULL; p = p->next)
cp
for(; p != NULL; p = p->next)
if(p->which == type)
return p;
/* Not found */
return NULL;
break;
cp
return p;
}
/*
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
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__
#define __TINC_CONF_H__
#define MAXTIMEOUT 900 /* Maximum timeout value for retries. Should this be a configuration option? */
typedef struct ip_mask_t {
unsigned long ip;
unsigned long mask;
} ip_mask_t;
typedef union data_t {
unsigned long val;
void *ptr;
ip_mask_t *ip;
} data_t;
typedef enum which_t {
passphrasesdir = 1,
upstreamip,
upstreamport,
listenport,
myvpnip,
tapdevice,
allowconnect,
tincname = 1,
connectto,
pingtimeout,
tapdevice,
tapsubnet,
privatekey,
keyexpire,
vpnmask,
resolve_dns
resolve_dns,
interface,
interfaceip,
address,
port,
publickey,
subnet,
restricthosts,
restrictsubnets,
restrictaddress,
restrictport,
indirectdata,
tcponly,
} which_t;
typedef struct config_t {
struct config_t *next;
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;
typedef struct internal_config_t {
char *name;
enum which_t which;
int argtype;
} internal_config_t;
enum {
stupid_false = 1,
stupid_true
@ -69,9 +86,16 @@ enum {
extern config_t *config;
extern int debug_lvl;
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 int read_config_file(const char *);
extern const config_t *get_config_val(which_t type);
extern int read_config_file(config_t **, const char *);
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__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
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"
@ -61,8 +61,8 @@ int key_inited = 0, encryption_keylen;
mpz_t my_private_key, my_public_key, generator, shared_prime;
int my_key_expiry = (time_t)(-1);
static char* mypassphrase;
static int mypassphraselen;
char* mypassphrase;
int mypassphraselen;
int char_hex_to_bin(int c)
{
@ -98,18 +98,17 @@ int read_passphrase(char *which, char **out)
cp
if((cfg = get_config_val(passphrasesdir)) == NULL)
{
filename = xmalloc(strlen(confbase)+13+strlen(which));
sprintf(filename, "%spassphrases/%s", confbase, which);
asprintf(&filename, "%spassphrases/%s", confbase, which);
}
else
{
filename = xmalloc(strlen(cfg->data.ptr)+2+strlen(which));
sprintf(filename, "%s/%s", (char*)cfg->data.ptr, which);
asprintf(&filename, "%s/%s", (char*)cfg->data.ptr, which);
}
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;
}
@ -119,12 +118,14 @@ cp
syslog(LOG_ERR, _("Illegal passphrase in %s; size would be %d"), filename, size);
return -1;
}
size >>= 2; /* bits->nibbles */
pp = xmalloc(size+2);
fgets(pp, size+1, f);
/* Hmz... hackish... strange +1 and +2 stuff... I really like more comments on those alignment thingies! */
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);
*out = xmalloc(size);
*out = xmalloc(size/8 + 2); /* Allocate enough bytes, +1 for rounding if bits%8 != 0, +1 for 2-byte alignment */
cp
return str_hex_to_bin(*out, pp);
}
@ -150,7 +151,8 @@ cp
else
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)
{
@ -266,7 +268,7 @@ int verify_passphrase(conn_list_t *cl, unsigned char *his_pubkey)
mpz_t pk;
unsigned char *out;
BF_KEY bf_key;
char which[sizeof("123.123.123.123")+1];
char *which;
char *meuk;
cp
mpz_init_set_str(pk, his_pubkey, 36);
@ -280,7 +282,7 @@ cp
if(key_inited)
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)
return -1;
@ -335,12 +337,12 @@ cp
/* We haven't received a key from this host (yet). */
continue;
ek = make_shared_key(p->public_key->key);
free_key(p->key);
p->key = xmalloc(sizeof(*p->key));
p->key->length = strlen(ek);
p->key->expiry = p->public_key->expiry;
p->key->key = xmalloc(strlen(ek) + 1);
strcpy(p->key->key, ek);
free_key(p->datakey);
p->datakey = xmalloc(sizeof(*p->datakey));
p->datakey->length = strlen(ek);
p->datakey->expiry = p->public_key->expiry;
p->datakey->key = xmalloc(strlen(ek) + 1);
strcpy(p->datakey->key, ek);
}
cp
}

View file

@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
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__
@ -30,9 +32,6 @@ extern int my_key_expiry;
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 void set_shared_key(char *);
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>
2000 Guus Sliepen <guus@sliepen.warande.net>
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
@ -16,7 +17,7 @@
along with this program; if not, write to the Free Software
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"
@ -24,20 +25,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <openssl/rsa.h>
#include <xalloc.h>
#include "encr.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)
{
FILE *fp;
int bits, c, i, bytes;
unsigned char *p;
int bits;
RSA *key;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@ -51,54 +81,25 @@ int main(int argc, char **argv)
if(!argv[1])
argv[1] = "1024";
if(!(bits = atol(argv[1])))
bits = atol(argv[1]);
if(bits<32)
{
fprintf(stderr, _("Illegal number: %s\n"), argv[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 number"), bits);
bytes = bits >> 3;
fprintf(stderr, _("Generating %d bits keys:\n"), bits);
if((fp = fopen("/dev/urandom", "r")) == NULL)
{
perror(_("Opening /dev/urandom"));
return 1;
}
key = RSA_generate_key(bits, RSA_PUBLIC_EXPONENT, indicator, NULL);
p = xmalloc(bytes);
fprintf(stderr, _("Done.\n"));
setbuf(stdout, NULL);
for(i = 0; i < bytes; i++)
{
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"));
}
printf(_("Public key: %s\n"), BN_bn2hex(key->n));
printf(_("Private key: %s\n"), BN_bn2hex(key->d));
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
along with this program; if not, write to the Free Software
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__
@ -23,7 +25,6 @@
#include <sys/time.h>
#include "config.h"
#include "conf.h"
#define MAXSIZE 1700 /* should be a bit more than the MTU for the tapdevice */
#define MTU 1600
@ -43,9 +44,29 @@
((unsigned char*)&(x))[1],((unsigned char*)&(x))[0]
#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 struct vpn_packet_t {
@ -53,12 +74,6 @@ typedef struct vpn_packet_t {
unsigned char data[MAXSIZE];
} 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 {
unsigned short len;
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 waitingforkey:1; /* 1 if we already sent out a request */
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;
typedef struct option_bits_t {
int unused:32;
} option_bits_t;
typedef struct queue_element_t {
void *packet;
struct queue_element_t *prev;
@ -96,31 +117,6 @@ typedef struct enc_key_t {
time_t expiry;
} 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 total_tap_in;
@ -128,15 +124,23 @@ extern int total_tap_out;
extern int total_socket_in;
extern int total_socket_out;
extern conn_list_t *conn_list;
extern conn_list_t *myself;
extern char *unknown;
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 setup_network_connections(void);
extern void close_network_connections(void);
extern void main_loop(void);
extern int setup_vpn_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__ */

View file

@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
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"
@ -33,6 +33,7 @@
#include <utils.h>
#include <xalloc.h>
#include "errno.h"
#include "conf.h"
#include "encr.h"
#include "net.h"
@ -40,25 +41,6 @@
#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
@ -79,91 +61,7 @@ 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 *name;
@ -175,7 +73,7 @@ cp
in.s_addr = addr;
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)
lookup_hostname = 1;
@ -184,13 +82,11 @@ cp
if(!lookup_hostname || !host)
{
name = xmalloc(20);
sprintf(name, "%s", inet_ntoa(in));
asprintf(&name, "%s", inet_ntoa(in));
}
else
{
name = xmalloc(strlen(host->h_name)+20);
sprintf(name, "%s (%s)", host->h_name, inet_ntoa(in));
asprintf(&name, "%s", host->h_name);
}
cp
return name;
@ -216,7 +112,7 @@ cp
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;
}
@ -236,17 +132,3 @@ cp
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
along with this program; if not, write to the Free Software
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__
#define __TINC_NETUTL_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 ip_mask_t *strtoip(char*);
extern void dump_conn_list(void);
#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
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
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
along with this program; if not, write to the Free Software
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__
#define __TINC_PROTOCOL_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 {
PROT_RESERVED = 0, /* reserved: do not use. */
PROT_NOT_IN_USE,
PROT_TOO_OLD = 2,
PROT_3,
PROT_4,
PROT_ECHELON,
PROT_CURRENT, /* protocol currently in use */
ALL = -1, /* Guardian for allow_request */
ID = 0, CHALLENGE, CHAL_REPLY, ACK,
STATUS, ERROR, TERMREQ,
PING, PONG,
ADD_HOST, DEL_HOST,
ADD_SUBNET, DEL_SUBNET,
KEY_CHANGED, REQ_KEY, ANS_KEY,
LAST /* Guardian for the highest request number */
};
enum {
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 (*request_handlers[])(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_basic_info(conn_list_t *);
extern int send_termreq(conn_list_t *);
extern int send_timeout(conn_list_t *);
extern int send_key_request(ip_t);
extern void send_key_changed_all(void);
extern int send_pong(conn_list_t*);
extern int send_add_host(conn_list_t*, conn_list_t*);
extern int send_del_host(conn_list_t*, conn_list_t*);
extern int send_add_subnet(conn_list_t*, conn_list_t*, subnet_t*);
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__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software
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"
@ -30,6 +30,7 @@
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include <signal.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
@ -43,6 +44,7 @@
#include "encr.h"
#include "net.h"
#include "netutl.h"
#include "protocol.h"
#include "system.h"
@ -61,10 +63,7 @@ static int kill_tincd = 0;
/* If zero, don't detach from the terminal. */
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 *netname = NULL; /* name of the vpn network */
char *pidfilename; /* pid file location */
static pid_t ppid; /* pid of non-detached part */
char **g_argv; /* a copy of the cmdline arguments */
@ -96,7 +95,7 @@ usage(int status)
else
{
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 Increase debug level.\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 */
break;
case 'c': /* config file */
configfilename = xmalloc(strlen(optarg)+1);
strcpy(configfilename, optarg);
confbase = xmalloc(strlen(optarg)+1);
strcpy(confbase, optarg);
break;
case 'D': /* no detach */
do_detach = 0;
@ -156,7 +155,7 @@ parse_options(int argc, char **argv, char **envp)
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);
}
@ -180,7 +179,7 @@ int detach(void)
if(pid) /* parent process */
{
signal(SIGTERM, parent_exit);
sleep(600); /* wait 10 minutes */
// sleep(600); /* wait 10 minutes */
exit(1);
}
}
@ -210,11 +209,11 @@ int detach(void)
openlog(identname, LOG_CONS | LOG_PID, LOG_DAEMON);
if(debug_lvl > 1)
syslog(LOG_NOTICE, _("tincd %s (%s %s) starting, debug level %d."),
if(debug_lvl > 0)
syslog(LOG_NOTICE, _("tincd %s (%s %s) starting, debug level %d"),
VERSION, __DATE__, __TIME__, debug_lvl);
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;
@ -229,7 +228,7 @@ void cleanup_and_exit(int c)
close_network_connections();
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);
closelog();
@ -291,35 +290,24 @@ int kill_other(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)
{
pidfilename = xmalloc(strlen(netname)+20);
sprintf(pidfilename, "/var/run/tinc.%s.pid", netname);
confbase = xmalloc(strlen(netname)+8+strlen(CONFDIR));
sprintf(confbase, "%s/tinc/%s/", CONFDIR, netname);
identname = xmalloc(strlen(netname)+7);
sprintf(identname, "tinc.%s", netname);
if(!pidfilename)
asprintf(&pidfilename, "/var/run/tinc.%s.pid", netname);
if(!confbase)
asprintf(&confbase, "%s/tinc/%s", CONFDIR, netname);
if(!identname)
asprintf(&identname, "tinc.%s", netname);
}
else
{
pidfilename = "/var/run/tinc.pid";
confbase = xmalloc(7+strlen(CONFDIR));
sprintf(confbase, "%s/tinc/", CONFDIR);
identname = "tinc";
netname = "bla";
if(!pidfilename)
pidfilename = "/var/run/tinc.pid";
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);
textdomain (PACKAGE);
/* Do some intl stuff right now */
unknown = _("unknown");
parse_options(argc, argv, envp);
if(show_version)
{
printf(_("%s version %s\n"), PACKAGE, VERSION);
printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans and others,\n"
"see the AUTHORS file for a complete list.\n\n"
printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE, VERSION, __DATE__, __TIME__, PROT_CURRENT);
printf(_("Copyright (C) 1998,1999,2000 Ivo Timmermans, Guus Sliepen and others.\n"
"See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"
"see the file COPYING for details.\n\n"));
printf(_("This product includes software developed by Eric Young (eay@mincom.oz.au)\n"));
"see the file COPYING for details.\n"));
return 0;
}
@ -352,7 +343,7 @@ main(int argc, char **argv, char **envp)
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;
}
@ -363,7 +354,7 @@ main(int argc, char **argv, char **envp)
if(kill_tincd)
exit(kill_other());
if(read_config_file(configfilename))
if(read_server_config())
return 1;
setup_signals();
@ -371,16 +362,32 @@ main(int argc, char **argv, char **envp)
if(detach())
exit(0);
/* FIXME: wt* is this suppose to do?
if(security_init())
return 1;
*/
for(;;)
{
if(!setup_network_connections())
{
main_loop();
cleanup_and_exit(1);
}
syslog(LOG_ERR, _("Unrecoverable error"));
cp_trace();
if(setup_network_connections())
cleanup_and_exit(1);
main_loop();
cleanup_and_exit(1);
return 1;
if(do_detach)
{
syslog(LOG_NOTICE, _("Restarting in %d seconds!"), MAXTIMEOUT);
sleep(MAXTIMEOUT);
}
else
{
syslog(LOG_ERR, _("Aieee! Not restarting."));
exit(0);
}
}
}
RETSIGTYPE
@ -402,41 +409,45 @@ sigquit_handler(int a)
RETSIGTYPE
sigsegv_square(int a)
{
syslog(LOG_NOTICE, _("Got another SEGV signal: not restarting"));
syslog(LOG_ERR, _("Got another SEGV signal: not restarting"));
exit(0);
}
RETSIGTYPE
sigsegv_handler(int a)
{
if(cp_file)
syslog(LOG_NOTICE, _("Got SEGV signal after %s line %d. Trying to re-execute."),
cp_file, cp_line);
syslog(LOG_ERR, _("Got SEGV signal"));
cp_trace();
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
syslog(LOG_NOTICE, _("Got SEGV signal; trying to re-execute."));
signal(SIGSEGV, sigsegv_square);
close_network_connections();
remove_pid(pidfilename);
execvp(g_argv[0], g_argv);
{
syslog(LOG_NOTICE, _("Aieee! Not restarting."));
exit(0);
}
}
RETSIGTYPE
sighup_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, _("Got HUP signal"));
close_network_connections();
setup_network_connections();
/* FIXME: read config-file and re-establish network connections */
syslog(LOG_NOTICE, _("Got HUP signal, rereading configuration and restarting"));
sighup = 1;
}
RETSIGTYPE
sigint_handler(int a)
{
if(debug_lvl > 0)
syslog(LOG_NOTICE, _("Got INT signal"));
syslog(LOG_NOTICE, _("Got INT signal, exiting"));
cleanup_and_exit(0);
}
@ -450,18 +461,17 @@ RETSIGTYPE
sigusr2_handler(int a)
{
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();
*/
}
RETSIGTYPE
sighuh(int a)
{
if(cp_file)
syslog(LOG_NOTICE, _("Got unexpected signal (%d) after %s line %d."),
a, cp_file, cp_line);
else
syslog(LOG_NOTICE, _("Got unexpected signal (%d)."), a);
syslog(LOG_WARNING, _("Got unexpected signal %d (%s)"), a, strsignal(a));
cp_trace();
}
void
@ -485,7 +495,7 @@ setup_signals(void)
signal(SIGINT, sigint_handler);
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
signal(SIGCHLD, parent_exit);
// signal(SIGCHLD, parent_exit);
}
RETSIGTYPE parent_exit(int a)