No description
Find a file
Etienne Dechamps 613d586afd Don't unset validkey when receiving SPTPS handshakes over ANS_KEY.
This fixes a hairy race condition that was introduced in
1e89a63f16, which changed
the underlying transport of handshake packets from REQ_KEY to ANS_KEY.
Unfortunately, what I missed in that commit is, on the receiving side,
there is a slight difference between req_key_h() and ans_key_h():
indeed, the latter resets validkey to false.

The reason why this is not a problem during typical operation is
because the normal SPTPS key regeneration procedure looks like this:

    KEX ->
    <- KEX
    SIG ->
    <- SIG

All these messages are sent over ANS_KEY, therefore the receiving side
will unset validkey. However, that's typically not a problem in practice
because upon reception of the last message (SIG), SPTPS will call
sptps_receive_record(), which will set validkey to true again, and
everything works out fine in the end.

However, that was the *typical* scenario. Now let's assume that the
SPTPS channel is in active use at the same time key regeneration
happens. Specifically, let's assume a normal VPN data packet sneaks in
during the key regeneration procedure:

    KEX ->
    <- KEX
    <- (SPTPS packet, over TCP or UDP)
    <- KEX (wtf?)
    SIG -> (refused with Invalid packet seqno: XXX != 0)

At this point, both nodes are extremely confused and the SPTPS channel
becomes unusable with various errors being thrown on both sides. The
channel will stay down until automatic SPTPS channel restart kicks in
after 10 seconds.

(Note: the above is just an example - the race can occur on either side
whenever a packet is sent during the period of time between KEX and SIG
messages are received by the node sending the packet.)

I've seen this race occur in the wild - it is very likely to occur if
key regeneration occurs on a heavily loaded channel. It can be
reproduced fairly easily by setting KeyExpire to a short value (a few
seconds) and then running something like ping -f foobar -i 0.01.

The reason why this occurs is because tinc's TX code path triggers the
following:

 - send_packet()
 - try_tx()
 - try_tx_sptps()
 - validkey is false because we just received an ANS_KEY message
 - waitingforkey is false because it's not used for key regeneration
 - send_req_key()
 - SPTPS channel restart (sptps_stop(), sptps_start()).

Obviously, it all goes downhill from there and the two nodes get very
confused quickly (for example the seqno gets reset, hence the error
messages).

This commit fixes the issue by keeping validkey set when SPTPS data is
received over ANS_KEY messages.
2015-11-22 17:53:52 +00:00
bash_completion.d Add UPnP support to tincd. 2015-11-21 16:17:59 +00:00
doc Add UPnP support to tincd. 2015-11-21 16:17:59 +00:00
gui tinc-gui: Don't assign broadcast subnets to any node, fix parsing of Edges, fix diplay of Subnet.weight. 2014-10-14 22:18:56 +02:00
m4 Add a new optional dependency on the miniupnpc library. 2015-11-21 15:49:25 +00:00
src Don't unset validkey when receiving SPTPS handshakes over ANS_KEY. 2015-11-22 17:53:52 +00:00
systemd Optionally install systemd service files. 2015-09-24 22:11:16 +02:00
test Fix check for public key in invite-join.test. 2015-05-19 13:30:42 +02:00
.gitignore Don't ignore Makefile.am. 2012-09-24 14:56:00 +02:00
AUTHORS Remove Google from the list of copyright owners. 2014-08-30 10:57:57 +01:00
configure.ac Allow tinc to be built with miniupnpc on Windows. 2015-11-21 16:18:01 +00:00
COPYING Update copyright notices. 2014-02-07 20:38:48 +01:00
COPYING.README Releasing 1.0.12. 2010-02-03 22:49:48 +01:00
Makefile.am Optionally install systemd service files. 2015-09-24 22:11:16 +02:00
NEWS Releasing 1.1pre11. 2014-12-27 09:22:31 +01:00
README Releasing 1.1pre11. 2014-12-27 09:22:31 +01:00
README.android Android cross-compilation instructions. 2012-09-24 13:55:38 +02:00
README.git Document clearly that tinc depends on curses and readline libraries. 2014-01-20 20:16:58 +01:00
THANKS Update THANKS file. 2015-11-21 19:41:14 +01:00

This is the README file for tinc version 1.1pre11. Installation
instructions may be found in the INSTALL file.

tinc is Copyright (C) 1998-2014 by:

Ivo Timmermans,
Guus Sliepen <guus@tinc-vpn.org>,
and others.

For a complete list of authors see the AUTHORS file.

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 is a pre-release
---------------------

Please note that this is NOT a stable release. Until version 1.1.0 is released,
please use one of the 1.0.x versions if you need a stable version of tinc.

Although tinc 1.1 will be protocol compatible with tinc 1.0.x, the
functionality of the tinc program may still change, and the control socket
protocol is not fixed yet.


Security statement
------------------

This version uses an experimental and unfinished cryptographic protocol. Use it
at your own risk.


Compatibility
-------------

Version 1.1pre11 is compatible with 1.0pre8, 1.0 and later, but not with older
versions of tinc.

When the ExperimentalProtocol option is used, tinc is still compatible with
1.0.X and 1.1pre11 itself, but not with any other 1.1preX version.


Requirements
------------

In order to compile tinc, you will need a GNU C compiler environment. Please
ensure you have the latest stable versions of all the required libraries:

- OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for
  elliptic curve cryptography (ECC) and Galois counter mode (GCM) enabled.

The following libraries are used by default, but can be disabled if necessary:

- zlib (http://www.gzip.org/zlib/)
- lzo (http://www.oberhumer.com/opensource/lzo/)
- ncurses (http://invisible-island.net/ncurses/)
- readline (ftp://ftp.gnu.org/pub/gnu/readline/)


Features
--------

Tinc is a peer-to-peer VPN daemon that supports VPNs with an arbitrary number
of nodes. Instead of configuring tunnels, you give tinc the location and
public key of a few nodes in the VPN. After making the initial connections to
those nodes, tinc will learn about all other nodes on the VPN, and will make
connections automatically. When direct connections are not possible, data will
be forwarded by intermediate nodes.

By default, nodes authenticate each other using 2048 bit RSA (or 521 bit
ECDSA*) keys. Traffic is encrypted using Blowfish in CBC mode (or AES-256 in
GCM mode*), authenticated using HMAC-SHA1 (or GCM*), and is protected against
replay attacks.

*) When using the ExperimentalProtocol option.

Tinc fully supports IPv6.

Tinc can operate in several routing modes. In the default mode, "router", every
node is associated with one or more IPv4 and/or IPv6 Subnets. The other two
modes, "switch" and "hub", let the tinc daemons work together to form a virtual
Ethernet network switch or hub.

Normally, when started tinc will detach and run in the background. In a native
Windows environment this means tinc will intall itself as a service, which will
restart after reboots.  To prevent tinc from detaching or running as a service,
use the -D option.

The status of the VPN can be queried using the "tinc" command, which connects
to a running tinc daemon via a control connection. The same tool also makes it
easy to start and stop tinc, and to change its configuration.