Guus Sliepen [Mon, 20 Feb 2012 16:19:00 +0000 (17:19 +0100)]
Allow disabling of broadcast packets.
The Broadcast option can be used to cause tinc to drop all broadcast and
multicast packets. This option might be expanded in the future to selectively
allow only some broadcast packet types.
Guus Sliepen [Mon, 20 Feb 2012 15:52:53 +0000 (16:52 +0100)]
Don't bind outgoing TCP sockets anymore.
The code introduced in commit 41a05f59ba2c3eb5caab555f096ed1b9fbe69ee3 is not
needed anymore, since tinc has been able to handle UDP packets from a different
source address than those of the TCP packets since 1.0.10. When using multiple
BindToAddress statements, this code does not make sense anymore, we do want the
kernel to choose the source address on its own.
Guus Sliepen [Mon, 20 Feb 2012 15:34:02 +0000 (16:34 +0100)]
Decrement TTL of incoming packets.
Tinc will now, by default, decrement the TTL field of incoming IPv4 and IPv6
packets, before forwarding them to the virtual network device or to another
node. Packets with a TTL value of zero will be dropped, and an ICMP Time
Exceeded message will be sent back.
This behaviour can be disabled using the DecrementTTL option.
Guus Sliepen [Fri, 17 Feb 2012 15:13:38 +0000 (16:13 +0100)]
Set FD_CLOEXEC flag on all sockets.
Scripts called by tinc would inherit its open filedescriptors. This could
be a problem if other long-running daemons are started from those scripts,
if those daemons would not close all filedescriptors before going into the
background.
Problem found and solution suggested by Nick Hibma.
Guus Sliepen [Sun, 4 Dec 2011 00:20:59 +0000 (01:20 +0100)]
Allow linking with multiple device drivers.
Apart from the platform specific tun/tap driver, link with the dummy and
raw_socket devices, and optionally with support for UML and VDE devices.
At runtime, the DeviceType option can be used to select which driver to
use.
Guus Sliepen [Wed, 5 Oct 2011 20:00:51 +0000 (22:00 +0200)]
Update SPTPS protocol.
* Exchange nonce and ECDH public key first, calculate the ECDSA signature
over the complete key exchange.
* Make an explicit distinction between client and server in the signatures.
* Add more comments and replace some magic numbers by #defines.
Thanks to Erik Tews for very helpful hints and comments!
Guus Sliepen [Tue, 30 Aug 2011 17:56:56 +0000 (19:56 +0200)]
Prevent read_rsa_public_key() from returning an uninitialized RSA structure.
In case the config file could not be opened a new but unitialized RSA structure
would be returned, causing a segmentation fault later on. This would only
happen in the case that the config file could be opened before, but not when
read_rsa_public_key() was called. This situation could occur when the --user
option was used, and the config files were not readable by the specified user.
Guus Sliepen [Wed, 10 Aug 2011 15:04:17 +0000 (17:04 +0200)]
Handle UDP packets with unknown source addresses properly.
Probably due to a merge, the try_harder() function had duplicated the
rate-limiting code for detecting the sender node based on the HMAC of the
packet. This prevented this detection from running at all. The function is now
identical again to that in the 1.0 branch.
Michael Tokarev [Sun, 7 Aug 2011 08:18:20 +0000 (12:18 +0400)]
use execvp() not execve() in tincctl start
sometimes argv[0] will have directory-less name (when the
command is started by shell searching in $PATH for example).
For tincctl start we want the same rules to run tincd as for
tincctl itself (having full path is better but if shell does
not provide one we've no other choice). Previous code tried
to run ./tincd in this case, which is obviously wrong.
Michael Tokarev [Sun, 7 Aug 2011 08:05:07 +0000 (12:05 +0400)]
run tincd from the same directory as tincctl and pass all options to it
For tincctl start, run tincd from dirname($0) not SBINDIR -
this allows painless alternative directory installation and
running from build directory too.
Also while at it, pass the rest of command line to tincd, not
only options before "start" argument. This way it's possible
to pass options to tincd like this:
tincctl -n net start -- -d 1 -R -U tincuser ...
And also add missing newline at the end of error message there.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].
The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.
A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.
The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.
This is mainly important for Windows, where the select() call in the
main thread is not being woken up when the tapreader thread calls
route(), causing a delay of up to 1 second before the output buffer is
flushed. This would cause bad performance when UDP communication is not
possible.
Make code to detect two nodes with the same Name less triggerhappy.
First of all, if there really are two nodes with the same name, much
more than 10 contradicting ADD_EDGE and DEL_EDGE messages will be sent.
Also, we forgot to reset the counters when nothing happened.
In case there is a ADD_EDGE/DEL_EDGE storm, we do not shut down, but
sleep an increasing amount of time, allowing tinc to recover gracefully
from temporary failures.
Make hexadecimal and base64 routines behave the same.
The length parameter for the encoding functions is the length of the
binary input, and for the decoding functions it is the maximum size of
the binary output.
The return value is always the length of the resulting output, excluding
the terminating NULL character for the encoding routines.
All functions can encode and decode in-place. The encoding functions
will always write a terminating NULL character, and the decoding
functions will stop at a NULL character.
Automatically exchange ECDSA keys and upgrade to new authentication protocol.
If we don't have ECDSA keys for the node we connect to, set protocol_minor
to 1, to indicate this to the other end. This will first complete the
old way of authentication with RSA keys, and will then exchange ECDSA keys.
The connection will be terminated right afterwards, and the next attempt
will use ECDSA keys.
The generate-keys command now generates both an RSA and an ECDSA keypair,
but one can generate-rsa-keys or generate-ecdsa-keys to just generate one type.
Add PRF to derive key material from the ECDH shared secret.
It is modelled after the pseudorandom function from RFC4346 (TLS 1.1), the only
significant change is the use of SHA512 and Whirlpool instead of MD5 and SHA1.
REQ_KEY requests have an extra field indicating key exchange version.
If it is present and > 0, the sender supports ECDH. If the receiver also
does, then it will generate a new keypair and sends the public key in a
ANS_KEY request with "ECDH:" prefixed. The ans_key_h() function will
compute the shared secret, which, at the moment,is used as is to set the
cipher and HMAC keys. However, this must be changed to use a proper KDF.
In the future, the ECDH key exchange must also be signed.
Guus Sliepen [Sat, 25 Jun 2011 19:35:27 +0000 (21:35 +0200)]
Make pid files backwards compatible and add address of listening socket.
The pid is now written first, so that a version 1.0.x tincd can be used to stop
a running version 1.1 tincd. Getsockname() is used to determine the address of
the first listening socket, so that tincctl can connect to the local tincd even
if AddressFamily = ipv6, or if BindToAddress or BindToInterface is used.