Import Upstream version 1.1~pre17

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:53 +02:00
parent bc8ca65653
commit b511a112e6
216 changed files with 43313 additions and 18448 deletions

View file

@ -1,4 +1,4 @@
Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others. Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.
See the AUTHORS file for a complete list. See the AUTHORS file for a complete list.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under

25974
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -2,12 +2,14 @@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu
SUBDIRS = src doc gui test systemd SUBDIRS = src doc test systemd
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android EXTRA_DIST = COPYING.README README.android
@CODE_COVERAGE_RULES@
# If git describe works, force autoconf to run in order to make sure we have the # If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script. # current version number from git in the resulting configure script.
configure-version: configure-version:
@ -33,3 +35,6 @@ release:
echo "Please edit the NEWS file now..." echo "Please edit the NEWS file now..."
/usr/bin/editor $(srcdir)/NEWS /usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist $(MAKE) dist
astyle:
astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch]

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -143,7 +144,7 @@ am__recursive_targets = \
$(RECURSIVE_CLEAN_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets) $(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in $(LISP)config.h.in
# Read a list of newline-separated strings from the standard input, # Read a list of newline-separated strings from the standard input,
@ -221,6 +222,12 @@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCDEPMODE = @CCDEPMODE@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@ CURSES_LIBS = @CURSES_LIBS@
@ -232,16 +239,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@ GREP = @GREP@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -256,6 +265,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@ READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
@ -313,7 +323,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu
SUBDIRS = src doc gui test systemd SUBDIRS = src doc test systemd
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = COPYING.README README.android EXTRA_DIST = COPYING.README README.android
all: config.h all: config.h
@ -341,8 +351,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' $(SHELL) ./config.status'; \ echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \ $(SHELL) ./config.status;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -475,7 +485,10 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir) $(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)" test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@ -788,6 +801,8 @@ uninstall-am:
.PRECIOUS: Makefile .PRECIOUS: Makefile
@CODE_COVERAGE_RULES@
# If git describe works, force autoconf to run in order to make sure we have the # If git describe works, force autoconf to run in order to make sure we have the
# current version number from git in the resulting configure script. # current version number from git in the resulting configure script.
configure-version: configure-version:
@ -814,6 +829,9 @@ release:
/usr/bin/editor $(srcdir)/NEWS /usr/bin/editor $(srcdir)/NEWS
$(MAKE) dist $(MAKE) dist
astyle:
astyle --options=.astylerc -nQ src/*.[ch] src/*/*.[ch]
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

40
NEWS
View file

@ -1,3 +1,35 @@
# Version 1.1pre17 October 8 2018
* Prevent oracle attacks in the legacy protocol (CVE-2018-16737,
CVE-2018-16738).
* Prevent a MITM from forcing a NULL cipher for UDP in the legacy protocol
(CVE-2018-16758).
* AutoConnect is now enabled by default.
* Per-node network traffic statistics are now shown in the output of "info" and
"dump nodes" commands.
Thanks to volth and Rafael Sadowski for their contributions to this version of
tinc.
# Version 1.1pre16 June 12 2018
* Fixed building with support for UML sockets.
* Documentation updates and spelling fixes.
* Support for MSS clamping of IP-in-IP packets.
* Fixed parsing of the -b flag.
* Added the ability to set a firemall mark on sockets on Linux.
* Minor improvements to the build system.
* Added a cache of recently seen addresses of peers.
* Add support for --runstatedir to the configure script.
* Fixed linking with libncurses on some distributions.
* Automatically disable PMTUDiscovery when TCPOnly is enabled.
* Fixed removing the tinc service on Windows in some situations.
* Fixed the TAP-Win32 device locking up after waking up from suspend.
Thanks to Todd C. Miller, Etienne Dechamps, Daniel Lublin,
Gjergji Ramku, Mike Sullivan and Oliver Freyermuth for their
contributions to this version of tinc.
# Version 1.1pre15 September 2 2017 # Version 1.1pre15 September 2 2017
* Detect when the machine is resuming from suspension or hibernation. * Detect when the machine is resuming from suspension or hibernation.
@ -12,7 +44,7 @@
* Support PriorityInheritance for IPv6 packets. * Support PriorityInheritance for IPv6 packets.
* Fixes for Solaris tun/tap support. * Fixes for Solaris tun/tap support.
* Add a configurable expiration time for invitations. * Add a configurable expiration time for invitations.
* Store invitation data after a succesful join. * Store invitation data after a successful join.
* Exit gracefully when the tun/tap device is in a bad state. * Exit gracefully when the tun/tap device is in a bad state.
* Add the LogLevel option. * Add the LogLevel option.
* AutoConnect now actively tries to heal split networks. * AutoConnect now actively tries to heal split networks.
@ -43,7 +75,7 @@ contributions to this version of tinc.
* Allow tinc to be compiled without LibreSSL or OpenSSL (this drops * Allow tinc to be compiled without LibreSSL or OpenSSL (this drops
compatibility with nodes running 1.0.x). compatibility with nodes running 1.0.x).
* Added a "fsck" command to check the configuration files for problems. * Added a "fsck" command to check the configuration files for problems.
* Tinc "start" now checks whether the daemon really started succesfully, and * Tinc "start" now checks whether the daemon really started successfully, and
displays error messages otherwise. displays error messages otherwise.
* Added systemd service files. * Added systemd service files.
* Use the recvmmsg() function if available. * Use the recvmmsg() function if available.
@ -378,7 +410,7 @@ their contributions to this version of tinc.
* Improved default settings of tun and tap devices on BSD platforms. * Improved default settings of tun and tap devices on BSD platforms.
* Make IPv6 sockets bind only to IPv6 on Linux. * Make IPv6 sockets bind only to IPv6 on Linux.
* Enable path MTU discovery by default. * Enable path MTU discovery by default.
* Fixed a memory leak that occured when connections were closed. * Fixed a memory leak that occurred when connections were closed.
Thanks to Max Rijevski for his contributions to this version of tinc. Thanks to Max Rijevski for his contributions to this version of tinc.
@ -552,7 +584,7 @@ Thanks to Scott Lamb for his contributions to this version of tinc.
* Tinc will retry to connect upon startup, does not quit if it doesn't * Tinc will retry to connect upon startup, does not quit if it doesn't
work the first time. work the first time.
* Hosts that are disconnected implicitly if we lose a connection get * Hosts that are disconnected implicitly if we lose a connection get
deleted from the internal list, to prevent hogging eachother with deleted from the internal list, to prevent hogging each other with
add and delete requests when the connection is restored. add and delete requests when the connection is restored.
# Version 1.0pre1 May 12 2000 # Version 1.0pre1 May 12 2000

30
README
View file

@ -1,7 +1,7 @@
This is the README file for tinc version 1.1pre15. Installation This is the README file for tinc version 1.1pre17. Installation
instructions may be found in the INSTALL file. instructions may be found in the INSTALL file.
tinc is Copyright © 1998-2017 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, and others. tinc is Copyright © 1998-2018 Ivo Timmermans, Guus Sliepen <guus@tinc-vpn.org>, and others.
For a complete list of authors see the AUTHORS file. For a complete list of authors see the AUTHORS file.
@ -28,11 +28,25 @@ Security statement
This version uses an experimental and unfinished cryptographic protocol. Use it This version uses an experimental and unfinished cryptographic protocol. Use it
at your own risk. at your own risk.
When connecting to nodes that use the legacy protocol used in tinc 1.0, be
aware that any security issues in tinc 1.0 will apply to tinc 1.1 as well. On
September 6th, 2018, Michael Yonly contacted us and provided proof-of-concept
code that allowed a remote attacker to create an authenticated, one-way
connection with a node using the legacy protocol, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to be sent
in plaintext. The first issue was trivial to exploit on tinc versions prior to
1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this
weakness much harder to exploit. These issues have been fixed in tinc 1.0.35
and tinc 1.1pre17. The new protocol in the tinc 1.1 branch is not susceptible
to these issues. However, be aware that SPTPS is only used between nodes
running tinc 1.1pre* or later, and in a VPN with nodes running different
versions, the security might only be as good as that of the oldest version.
Compatibility Compatibility
------------- -------------
Version 1.1pre15 is compatible with 1.0pre8, 1.0 and later, but not with older Version 1.1pre17 is compatible with 1.0pre8, 1.0 and later, but not with older
versions of tinc. versions of tinc.
When the ExperimentalProtocol option is used, tinc is still compatible with When the ExperimentalProtocol option is used, tinc is still compatible with
@ -50,9 +64,9 @@ ensure you have the latest stable versions of all the required libraries:
The following libraries are used by default, but can be disabled if necessary: The following libraries are used by default, but can be disabled if necessary:
- zlib (http://www.zlib.net/) - zlib (https://zlib.net/)
- LZO (https://www.oberhumer.com/opensource/lzo/) - LZO (https://www.oberhumer.com/opensource/lzo/)
- ncurses (http://invisible-island.net/ncurses/) - ncurses (https://invisible-island.net/ncurses/)
- readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) - readline (https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html)
@ -68,8 +82,8 @@ be forwarded by intermediate nodes.
Tinc 1.1 support two protocols. The first is a legacy protocol that provides Tinc 1.1 support two protocols. The first is a legacy protocol that provides
backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit backwards compatibility with tinc 1.0 nodes, and which by default uses 2048 bit
RSA keys for authentication, and encrypts traffic using Blowfish in CBC mode RSA keys for authentication, and encrypts traffic using AES256 in CBC mode
and HMAC-SHA1. The second is a new protocol which uses Curve25519 keys for and HMAC-SHA256. The second is a new protocol which uses Curve25519 keys for
authentication, and encrypts traffic using Chacha20-Poly1305, and provides authentication, and encrypts traffic using Chacha20-Poly1305, and provides
forward secrecy. forward secrecy.
@ -82,7 +96,7 @@ Ethernet network switch or hub.
Normally, when started tinc will detach and run in the background. In a native Normally, when started tinc will detach and run in the background. In a native
Windows environment this means tinc will install itself as a service, which will Windows environment this means tinc will install itself as a service, which will
restart after reboots. To prevent tinc from detaching or running as a service, restart after reboots. To prevent tinc from detaching or running as a service,
use the -D option. use the -D option.
The status of the VPN can be queried using the "tinc" command, which connects The status of the VPN can be queried using the "tinc" command, which connects

18
THANKS
View file

@ -5,9 +5,12 @@ We would like to thank the following people for their contributions to tinc:
* Alexis Hildebrandt * Alexis Hildebrandt
* Allesandro Gatti * Allesandro Gatti
* Andreas van Cranenburgh * Andreas van Cranenburgh
* Andrew Hahn
* Anthony G. Basile * Anthony G. Basile
* Armijn Hemel * Armijn Hemel
* Armin Fisslthaler * Armin Fisslthaler
* Aron Cowan
* Ashish Bajaj
* Baptiste Jonglez * Baptiste Jonglez
* Borg * Borg
* Brandon Black * Brandon Black
@ -19,35 +22,41 @@ We would like to thank the following people for their contributions to tinc:
* Delf Eldkraft * Delf Eldkraft
* Dennis Joachimsthaler * Dennis Joachimsthaler
* dnk * dnk
* Élie Bouttier
* Enrique Zanardi * Enrique Zanardi
* Erik Tews * Erik Tews
* Etienne Dechamps * Etienne Dechamps
* Florent Clairambault * Florent Clairambault
* Florian Forster
* Florian Klink * Florian Klink
* Florian Weik * Florian Weik
* Flynn Marquardt * Flynn Marquardt
* Franz Pletz * Franz Pletz
* Gary Kessler and Claudia Gonzalez * Gary Kessler and Claudia Gonzalez
* Grzegorz Dymarek * Grzegorz Dymarek
* Gusariev Oleksandr
* Hans Bayle * Hans Bayle
* Harvest * Harvest
* Ivo Smits
* Ivo van Dong * Ivo van Dong
* James Cook * James Cook
* James MacLean * James MacLean
* Jamie Briggs * Jamie Briggs
* Jason Harper * Jason Harper
* Jason Livesay * Jason Livesay
* Jasper Krijgsman
* Jelle de Jong * Jelle de Jong
* Jeroen Domburg * Jeroen Domburg
* Jeroen Ubbink * Jeroen Ubbink
* Jerome Etienne * Jerome Etienne
* Jo-Philipp Wich
* Jochen Voss * Jochen Voss
* Jo-Philipp Wich
* Julien Muchembled * Julien Muchembled
* Lavrans Laading * Lavrans Laading
* Loïc Dachary * Loïc Dachary
* Loïc Grenié * Loïc Grenié
* Lubomír Bulej * Lubomír Bulej
* luckyhacky
* LunarShaddow * LunarShaddow
* Mads Kiilerich * Mads Kiilerich
* Marc A. Lehmann * Marc A. Lehmann
@ -63,18 +72,22 @@ We would like to thank the following people for their contributions to tinc:
* Menno Smits * Menno Smits
* Mesar Hameed * Mesar Hameed
* Michael Tokarev * Michael Tokarev
* Michael Yonli
* Miles Nordin * Miles Nordin
* Nathan Stratton Treadway
* Murat Donmez * Murat Donmez
* Nathan Stratton Treadway
* Nick Hibma * Nick Hibma
* Nick Patavalis * Nick Patavalis
* Paul Littlefield * Paul Littlefield
* Philipp Babel * Philipp Babel
* Pierre Emeriaud * Pierre Emeriaud
* Pierre-Olivier Mercier
* Rafael Sadowski
* Rafał Leśniak * Rafał Leśniak
* Rhosyn Celyn * Rhosyn Celyn
* Robert van der Meulen * Robert van der Meulen
* Rumko * Rumko
* Ryan Miller
* Sam Bryan * Sam Bryan
* Samuel Thibault * Samuel Thibault
* Saverio Proto * Saverio Proto
@ -92,6 +105,7 @@ We would like to thank the following people for their contributions to tinc:
* Ulrich Seifert * Ulrich Seifert
* Vil Brekin * Vil Brekin
* Vittorio Gambaletta * Vittorio Gambaletta
* Wendy Willard
* Wessel Dankers * Wessel Dankers
* William A. Kennington III * William A. Kennington III
* William McArthur * William McArthur

190
aclocal.m4 vendored
View file

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc. # Copyright (C) 1996-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely. If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])]) To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# Copyright (C) 2002-2017 Free Software Foundation, Inc. # Copyright (C) 2002-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# generated from the m4 files accompanying Automake X.Y. # generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.) # (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION], AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.15' [am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro. dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.15.1], [], m4_if([$1], [1.16.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
]) ])
@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.15.1])dnl [AM_AUTOMAKE_VERSION([1.16.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION], m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*- # AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
# AM_CONDITIONAL -*- Autoconf -*- # AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2017 Free Software Foundation, Inc. # Copyright (C) 1997-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]]) Usually this means the macro was only invoked conditionally.]])
fi])]) fi])])
# Copyright (C) 1999-2017 Free Software Foundation, Inc. # Copyright (C) 1999-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*- # Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2017 Free Software Foundation, Inc. # Copyright (C) 1999-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved. # with or without modifications, as long as this notice is preserved.
# _AM_OUTPUT_DEPENDENCY_COMMANDS # _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------ # ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@ -346,49 +345,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Older Autoconf quotes --file arguments for eval, but not when files # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval # are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting. # if we detect the quoting.
case $CONFIG_FILES in # TODO: see whether this extra hack can be removed once we start
*\'*) eval set x "$CONFIG_FILES" ;; # requiring Autoconf 2.70 or later.
*) set x $CONFIG_FILES ;; AS_CASE([$CONFIG_FILES],
esac [*\'*], [eval set x "$CONFIG_FILES"],
[*], [set x $CONFIG_FILES])
shift shift
for mf # Used to flag and report bootstrapping failures.
am_rc=0
for am_mf
do do
# Strip MF so we end up with the name of the file. # Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'` am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not. # Check whether this is an Automake generated Makefile which includes
# We used to match only the files named 'Makefile.in', but # dependency-tracking related rules and includes.
# some people rename them; so instead we look at the file content. # Grep'ing the whole file directly is not great: AIX grep has a line
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000. # limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
dirpart=`AS_DIRNAME("$mf")` || continue
else am_dirpart=`AS_DIRNAME(["$am_mf"])`
continue am_filepart=`AS_BASENAME(["$am_mf"])`
fi AM_RUN_LOG([cd "$am_dirpart" \
# Extract the definition of DEPDIR, am__include, and am__quote && sed -e '/# am--include-marker/d' "$am_filepart" \
# from the Makefile without running 'make'. | $MAKE -f - am--depfiles]) || am_rc=$?
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
AS_UNSET([am_dirpart])
AS_UNSET([am_filepart])
AS_UNSET([am_mf])
AS_UNSET([am_rc])
rm -f conftest-deps.mk
} }
])# _AM_OUTPUT_DEPENDENCY_COMMANDS ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
@ -397,18 +388,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# ----------------------------- # -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE. # This macro should only be invoked once -- use via AC_REQUIRE.
# #
# This code is only required when automatic dependency tracking # This code is only required when automatic dependency tracking is enabled.
# is enabled. FIXME. This creates each '.P' file that we will # This creates each '.Po' and '.Plo' makefile fragment that we'll need in
# need in order to bootstrap the dependency handling code. # order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles], [AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
])
# Do all the work for Automake. -*- Autoconf -*- # Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc. # Copyright (C) 1996-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -495,8 +485,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility. To be removed once Automake 1.9.x # For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see: # dies out for good. For more background, see:
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> # <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> # <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
AC_SUBST([mkdir_p], ['$(MKDIR_P)']) AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target (and possibly the TAP driver). The # We need awk for the "check" target (and possibly the TAP driver). The
# system "awk" is bad on some platforms. # system "awk" is bad on some platforms.
@ -563,7 +553,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue. Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: <http://www.gnu.org/software/coreutils/>. that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@ -605,7 +595,7 @@ for _am_header in $config_headers :; do
done done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -626,7 +616,7 @@ if test x"${install_sh+set}" != xset; then
fi fi
AC_SUBST([install_sh])]) AC_SUBST([install_sh])])
# Copyright (C) 2003-2017 Free Software Foundation, Inc. # Copyright (C) 2003-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -647,7 +637,7 @@ AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*- # Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -655,49 +645,42 @@ AC_SUBST([am__leading_dot])])
# AM_MAKE_INCLUDE() # AM_MAKE_INCLUDE()
# ----------------- # -----------------
# Check to see how make treats includes. # Check whether make has an 'include' directive that can support all
# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE], AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make} [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
cat > confinc << 'END' cat > confinc.mk << 'END'
am__doit: am__doit:
@echo this is the am__doit target @echo this is the am__doit target >confinc.out
.PHONY: am__doit .PHONY: am__doit
END END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#" am__include="#"
am__quote= am__quote=
_am_result=none # BSD make does it like this.
# First try GNU make style include. echo '.include "confinc.mk" # ignored' > confmf.BSD
echo "include confinc" > confmf # Other make implementations (GNU, Solaris 10, AIX) do it like this.
# Ignore all kinds of additional output from 'make'. echo 'include confinc.mk # ignored' > confmf.GNU
case `$am_make -s -f confmf 2> /dev/null` in #( _am_result=no
*the\ am__doit\ target*) for s in GNU BSD; do
am__include=include AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
am__quote= AS_CASE([$?:`cat confinc.out 2>/dev/null`],
_am_result=GNU ['0:this is the am__doit target'],
;; [AS_CASE([$s],
esac [BSD], [am__include='.include' am__quote='"'],
# Now try BSD make style include. [am__include='include' am__quote=''])])
if test "$am__include" = "#"; then if test "$am__include" != "#"; then
echo '.include "confinc"' > confmf _am_result="yes ($s style)"
case `$am_make -s -f confmf 2> /dev/null` in #( break
*the\ am__doit\ target*) fi
am__include=.include done
am__quote="\"" rm -f confinc.* confmf.*
_am_result=BSD AC_MSG_RESULT([${_am_result}])
;; AC_SUBST([am__include])])
esac AC_SUBST([am__quote])])
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2017 Free Software Foundation, Inc. # Copyright (C) 1997-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -736,7 +719,7 @@ fi
# Helper functions for option handling. -*- Autoconf -*- # Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -765,7 +748,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION], AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2017 Free Software Foundation, Inc. # Copyright (C) 1999-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -812,7 +795,7 @@ AC_LANG_POP([C])])
# For backward compatibility. # For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -831,7 +814,7 @@ AC_DEFUN([AM_RUN_LOG],
# Check to make sure that the build environment is sane. -*- Autoconf -*- # Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc. # Copyright (C) 1996-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -912,7 +895,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file rm -f conftest.file
]) ])
# Copyright (C) 2009-2017 Free Software Foundation, Inc. # Copyright (C) 2009-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -972,7 +955,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
]) ])
# Copyright (C) 2001-2017 Free Software Foundation, Inc. # Copyright (C) 2001-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1000,7 +983,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])]) AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2017 Free Software Foundation, Inc. # Copyright (C) 2006-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1019,7 +1002,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*- # Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2017 Free Software Foundation, Inc. # Copyright (C) 2004-2018 Free Software Foundation, Inc.
# #
# This file is free software; the Free Software Foundation # This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -1155,6 +1138,7 @@ m4_include([m4/ax_append_flag.m4])
m4_include([m4/ax_cflags_warn_all.m4]) m4_include([m4/ax_cflags_warn_all.m4])
m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_compile_flag.m4])
m4_include([m4/ax_check_link_flag.m4]) m4_include([m4/ax_check_link_flag.m4])
m4_include([m4/ax_code_coverage.m4])
m4_include([m4/ax_require_defined.m4]) m4_include([m4/ax_require_defined.m4])
m4_include([m4/curses.m4]) m4_include([m4/curses.m4])
m4_include([m4/libgcrypt.m4]) m4_include([m4/libgcrypt.m4])

13
compile
View file

@ -1,9 +1,9 @@
#! /bin/sh #! /bin/sh
# Wrapper for compilers which do not understand '-c -o'. # Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc. # Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>. # Written by Tom Tromey <tromey@cygnus.com>.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@ -255,7 +255,8 @@ EOF
echo "compile $scriptversion" echo "compile $scriptversion"
exit $? exit $?
;; ;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return... func_cl_wrapper "$@" # Doesn't return...
;; ;;
esac esac
@ -339,9 +340,9 @@ exit $ret
# Local Variables: # Local Variables:
# mode: shell-script # mode: shell-script
# sh-indentation: 2 # sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC" # time-stamp-end: "; # UTC"
# End: # End:

584
config.guess vendored

File diff suppressed because it is too large Load diff

View file

@ -42,9 +42,13 @@
/* Darwin (MacOS/X) */ /* Darwin (MacOS/X) */
#undef HAVE_DARWIN #undef HAVE_DARWIN
/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms /* Define to 1 if you have the declaration of `EVP_aes_256_cfb', and to 0 if
EVP_aes_256_cfb', and to 0 if you don't. */ you don't. */
#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS_EVP_AES_256_CFB #undef HAVE_DECL_EVP_AES_256_CFB
/* Define to 1 if you have the declaration of `OpenSSL_add_all_algorithms',
and to 0 if you don't. */
#undef HAVE_DECL_OPENSSL_ADD_ALL_ALGORITHMS
/* Define to 1 if you have the declaration of `res_init', and to 0 if you /* Define to 1 if you have the declaration of `res_init', and to 0 if you
don't. */ don't. */
@ -83,9 +87,6 @@
/* FreeBSD */ /* FreeBSD */
#undef HAVE_FREEBSD #undef HAVE_FREEBSD
/* Define to 1 if you have the `ftime' function. */
#undef HAVE_FTIME
/* Define to 1 if you have the <gcrypt.h> header file. */ /* Define to 1 if you have the <gcrypt.h> header file. */
#undef HAVE_GCRYPT_H #undef HAVE_GCRYPT_H
@ -98,6 +99,9 @@
/* Define to 1 if you have the `gettimeofday' function. */ /* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY #undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `HMAC_CTX_new' function. */
#undef HAVE_HMAC_CTX_NEW
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #undef HAVE_INTTYPES_H
@ -424,5 +428,8 @@
/* Defined if the __malloc__ attribute is not supported. */ /* Defined if the __malloc__ attribute is not supported. */
#undef __malloc__ #undef __malloc__
/* Defined if the __nonnull__ attribute is not supported. */
#undef __nonnull__
/* Defined if the __warn_unused_result__ attribute is not supported. */ /* Defined if the __warn_unused_result__ attribute is not supported. */
#undef __warn_unused_result__ #undef __warn_unused_result__

258
config.sub vendored
View file

@ -1,8 +1,8 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc. # Copyright 1992-2018 Free Software Foundation, Inc.
timestamp='2016-11-04' timestamp='2018-02-22'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
@ -15,7 +15,7 @@ timestamp='2016-11-04'
# General Public License for more details. # General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>. # along with this program; if not, see <https://www.gnu.org/licenses/>.
# #
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@ -33,7 +33,7 @@ timestamp='2016-11-04'
# Otherwise, we print the canonical config type on stdout and succeed. # Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from: # You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages # This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases # and recognize all the CPU types, system types and aliases
@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name. Canonicalize a configuration name.
Operation modes: Options:
-h, --help print this help, then exit -h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit -t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit -v, --version print version number, then exit
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright 1992-2016 Free Software Foundation, Inc. Copyright 1992-2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -94,7 +94,7 @@ while test $# -gt 0 ; do
*local*) *local*)
# First pass through any local machine types. # First pass through any local machine types.
echo $1 echo "$1"
exit ;; exit ;;
* ) * )
@ -112,7 +112,7 @@ esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations. # Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
@ -120,16 +120,16 @@ case $maybe_os in
kopensolaris*-gnu* | cloudabi*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*) storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;; ;;
android-linux) android-linux)
os=-linux-android os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;; ;;
*) *)
basic_machine=`echo $1 | sed 's/-[^-]*$//'` basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ] if [ "$basic_machine" != "$1" ]
then os=`echo $1 | sed 's/.*-/-/'` then os=`echo "$1" | sed 's/.*-/-/'`
else os=; fi else os=; fi
;; ;;
esac esac
@ -178,44 +178,44 @@ case $os in
;; ;;
-sco6) -sco6)
os=-sco5v6 os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco5) -sco5)
os=-sco3.2v5 os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco4) -sco4)
os=-sco3.2v4 os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco3.2.[4-9]*) -sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco3.2v[4-9]*) -sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer. # Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco5v6*) -sco5v6*)
# Don't forget version if it is 3.2v4 or newer. # Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco*) -sco*)
os=-sco3.2v2 os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-udk*) -udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-isc) -isc)
os=-isc2.2 os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-clix*) -clix*)
basic_machine=clipper-intergraph basic_machine=clipper-intergraph
;; ;;
-isc*) -isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-lynx*178) -lynx*178)
os=-lynxos178 os=-lynxos178
@ -227,10 +227,7 @@ case $os in
os=-lynxos os=-lynxos
;; ;;
-ptx*) -ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;; ;;
-psos*) -psos*)
os=-psos os=-psos
@ -263,7 +260,7 @@ case $basic_machine in
| fido | fr30 | frv | ft32 \ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \ | hexagon \
| i370 | i860 | i960 | ia64 \ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \ | ip2k | iq2000 \
| k1om \ | k1om \
| le32 | le64 \ | le32 | le64 \
@ -299,7 +296,7 @@ case $basic_machine in
| nios | nios2 | nios2eb | nios2el \ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \ | ns16k | ns32k \
| open8 | or1k | or1knd | or32 \ | open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \ | pdp10 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pru \ | pru \
| pyramid \ | pyramid \
@ -315,7 +312,7 @@ case $basic_machine in
| ubicom32 \ | ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| visium \ | visium \
| we32k \ | wasm32 \
| x86 | xc16x | xstormy16 | xtensa \ | x86 | xc16x | xstormy16 | xtensa \
| z8k | z80) | z8k | z80)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
@ -336,7 +333,7 @@ case $basic_machine in
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
os=-none os=-none
;; ;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
;; ;;
ms1) ms1)
basic_machine=mt-unknown basic_machine=mt-unknown
@ -365,7 +362,7 @@ case $basic_machine in
;; ;;
# Object if more than one company name word. # Object if more than one company name word.
*-*-*) *-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1 exit 1
;; ;;
# Recognize the basic CPU types with company name. # Recognize the basic CPU types with company name.
@ -388,7 +385,7 @@ case $basic_machine in
| h8300-* | h8500-* \ | h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \ | ip2k-* | iq2000-* \
| k1om-* \ | k1om-* \
| le32-* | le64-* \ | le32-* | le64-* \
@ -446,6 +443,7 @@ case $basic_machine in
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \ | vax-* \
| visium-* \ | visium-* \
| wasm32-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \ | xstormy16-* | xtensa*-* \
@ -459,7 +457,7 @@ case $basic_machine in
# Recognize the various machine names and aliases which stand # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
386bsd) 386bsd)
basic_machine=i386-unknown basic_machine=i386-pc
os=-bsd os=-bsd
;; ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@ -493,7 +491,7 @@ case $basic_machine in
basic_machine=x86_64-pc basic_machine=x86_64-pc
;; ;;
amd64-*) amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
amdahl) amdahl)
basic_machine=580-amdahl basic_machine=580-amdahl
@ -538,7 +536,7 @@ case $basic_machine in
os=-linux os=-linux
;; ;;
blackfin-*) blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
bluegene*) bluegene*)
@ -546,13 +544,13 @@ case $basic_machine in
os=-cnk os=-cnk
;; ;;
c54x-*) c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c55x-*) c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c6x-*) c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c90) c90)
basic_machine=c90-cray basic_machine=c90-cray
@ -641,7 +639,7 @@ case $basic_machine in
basic_machine=rs6000-bull basic_machine=rs6000-bull
os=-bosx os=-bosx
;; ;;
dpx2* | dpx2*-bull) dpx2*)
basic_machine=m68k-bull basic_machine=m68k-bull
os=-sysv3 os=-sysv3
;; ;;
@ -650,7 +648,7 @@ case $basic_machine in
os=$os"spe" os=$os"spe"
;; ;;
e500v[12]-*) e500v[12]-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=$os"spe" os=$os"spe"
;; ;;
ebmon29k) ebmon29k)
@ -742,9 +740,6 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9]) hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp basic_machine=hppa1.0-hp
;; ;;
hppa-next)
os=-nextstep3
;;
hppaosf) hppaosf)
basic_machine=hppa1.1-hp basic_machine=hppa1.1-hp
os=-osf os=-osf
@ -757,26 +752,26 @@ case $basic_machine in
basic_machine=i370-ibm basic_machine=i370-ibm
;; ;;
i*86v32) i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv32 os=-sysv32
;; ;;
i*86v4*) i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv4 os=-sysv4
;; ;;
i*86v) i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv os=-sysv
;; ;;
i*86sol2) i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-solaris2 os=-solaris2
;; ;;
i386mach) i386mach)
basic_machine=i386-mach basic_machine=i386-mach
os=-mach os=-mach
;; ;;
i386-vsta | vsta) vsta)
basic_machine=i386-unknown basic_machine=i386-unknown
os=-vsta os=-vsta
;; ;;
@ -795,19 +790,16 @@ case $basic_machine in
os=-sysv os=-sysv
;; ;;
leon-*|leon[3-9]-*) leon-*|leon[3-9]-*)
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
;; ;;
m68knommu) m68knommu)
basic_machine=m68k-unknown basic_machine=m68k-unknown
os=-linux os=-linux
;; ;;
m68knommu-*) m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230) magnum | m3230)
basic_machine=mips-mips basic_machine=mips-mips
os=-sysv os=-sysv
@ -839,10 +831,10 @@ case $basic_machine in
os=-mint os=-mint
;; ;;
mips3*-*) mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
;; ;;
mips3*) mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
;; ;;
monitor) monitor)
basic_machine=m68k-rom68k basic_machine=m68k-rom68k
@ -861,7 +853,7 @@ case $basic_machine in
os=-msdos os=-msdos
;; ;;
ms1-*) ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
;; ;;
msys) msys)
basic_machine=i686-pc basic_machine=i686-pc
@ -903,7 +895,7 @@ case $basic_machine in
basic_machine=v70-nec basic_machine=v70-nec
os=-sysv os=-sysv
;; ;;
next | m*-next ) next | m*-next)
basic_machine=m68k-next basic_machine=m68k-next
case $os in case $os in
-nextstep* ) -nextstep* )
@ -948,6 +940,12 @@ case $basic_machine in
nsr-tandem) nsr-tandem)
basic_machine=nsr-tandem basic_machine=nsr-tandem
;; ;;
nsv-tandem)
basic_machine=nsv-tandem
;;
nsx-tandem)
basic_machine=nsx-tandem
;;
op50n-* | op60c-*) op50n-* | op60c-*)
basic_machine=hppa1.1-oki basic_machine=hppa1.1-oki
os=-proelf os=-proelf
@ -980,7 +978,7 @@ case $basic_machine in
os=-linux os=-linux
;; ;;
parisc-*) parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
pbd) pbd)
@ -996,7 +994,7 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
;; ;;
pc98-*) pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentium | p5 | k5 | k6 | nexgen | viac3) pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc basic_machine=i586-pc
@ -1011,16 +1009,16 @@ case $basic_machine in
basic_machine=i786-pc basic_machine=i786-pc
;; ;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentiumpro-* | p6-* | 6x86-* | athlon-*) pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentium4-*) pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pn) pn)
basic_machine=pn-gould basic_machine=pn-gould
@ -1030,23 +1028,23 @@ case $basic_machine in
ppc | ppcbe) basic_machine=powerpc-unknown ppc | ppcbe) basic_machine=powerpc-unknown
;; ;;
ppc-* | ppcbe-*) ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppcle | powerpclittle) ppcle | powerpclittle)
basic_machine=powerpcle-unknown basic_machine=powerpcle-unknown
;; ;;
ppcle-* | powerpclittle-*) ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppc64) basic_machine=powerpc64-unknown ppc64) basic_machine=powerpc64-unknown
;; ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppc64le | powerpc64little) ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown basic_machine=powerpc64le-unknown
;; ;;
ppc64le-* | powerpc64little-*) ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ps2) ps2)
basic_machine=i386-ibm basic_machine=i386-ibm
@ -1100,17 +1098,10 @@ case $basic_machine in
sequent) sequent)
basic_machine=i386-sequent basic_machine=i386-sequent
;; ;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el) sh5el)
basic_machine=sh5le-unknown basic_machine=sh5le-unknown
;; ;;
sh64) simso-wrs)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs basic_machine=sparclite-wrs
os=-vxworks os=-vxworks
;; ;;
@ -1129,7 +1120,7 @@ case $basic_machine in
os=-sysv4 os=-sysv4
;; ;;
strongarm-* | thumb-*) strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
sun2) sun2)
basic_machine=m68000-sun basic_machine=m68000-sun
@ -1251,6 +1242,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond basic_machine=hppa1.1-winbond
os=-proelf os=-proelf
;; ;;
x64)
basic_machine=x86_64-pc
;;
xbox) xbox)
basic_machine=i686-pc basic_machine=i686-pc
os=-mingw32 os=-mingw32
@ -1259,20 +1253,12 @@ case $basic_machine in
basic_machine=xps100-honeywell basic_machine=xps100-honeywell
;; ;;
xscale-* | xscalee[bl]-*) xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
;; ;;
ymp) ymp)
basic_machine=ymp-cray basic_machine=ymp-cray
os=-unicos os=-unicos
;; ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none) none)
basic_machine=none-none basic_machine=none-none
os=-none os=-none
@ -1301,10 +1287,6 @@ case $basic_machine in
vax) vax)
basic_machine=vax-dec basic_machine=vax-dec
;; ;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11) pdp11)
basic_machine=pdp11-dec basic_machine=pdp11-dec
;; ;;
@ -1314,9 +1296,6 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown basic_machine=sh-unknown
;; ;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra) cydra)
basic_machine=cydra-cydrome basic_machine=cydra-cydrome
;; ;;
@ -1336,7 +1315,7 @@ case $basic_machine in
# Make sure to match an already-canonicalized machine name. # Make sure to match an already-canonicalized machine name.
;; ;;
*) *)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1 exit 1
;; ;;
esac esac
@ -1344,10 +1323,10 @@ esac
# Here we canonicalize certain aliases for manufacturers. # Here we canonicalize certain aliases for manufacturers.
case $basic_machine in case $basic_machine in
*-digital*) *-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
;; ;;
*-commodore*) *-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
;; ;;
*) *)
;; ;;
@ -1358,8 +1337,8 @@ esac
if [ x"$os" != x"" ] if [ x"$os" != x"" ]
then then
case $os in case $os in
# First match some system type aliases # First match some system type aliases that might get confused
# that might get confused with valid system types. # with valid system types.
# -solaris* is a basic system type, with this one exception. # -solaris* is a basic system type, with this one exception.
-auroraux) -auroraux)
os=-auroraux os=-auroraux
@ -1370,18 +1349,19 @@ case $os in
-solaris) -solaris)
os=-solaris2 os=-solaris2
;; ;;
-svr4*)
os=-sysv4
;;
-unixware*) -unixware*)
os=-sysv4.2uw os=-sysv4.2uw
;; ;;
-gnu/linux*) -gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;; ;;
# First accept the basic system types. # es1800 is here to avoid being matched by es* (a different OS)
-es1800*)
os=-ose
;;
# Now accept the basic system types.
# The portable systems comes first. # The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number. # Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4. # -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
@ -1391,25 +1371,26 @@ case $os in
| -aos* | -aros* | -cloudabi* | -sortix* \ | -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -morphos* | -superux* | -rtmk* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos* | -phoenix* | -fuchsia*) | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
| -midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-qnx*) -qnx*)
@ -1426,12 +1407,12 @@ case $os in
-nto*) -nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'` os=`echo $os | sed -e 's|nto|nto-qnx|'`
;; ;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ -sim | -xray | -os68k* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -windows* | -osx | -abug | -netware* | -os9* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;; ;;
-mac*) -mac*)
os=`echo $os | sed -e 's|mac|macos|'` os=`echo "$os" | sed -e 's|mac|macos|'`
;; ;;
-linux-dietlibc) -linux-dietlibc)
os=-linux-dietlibc os=-linux-dietlibc
@ -1440,10 +1421,10 @@ case $os in
os=`echo $os | sed -e 's|linux|linux-gnu|'` os=`echo $os | sed -e 's|linux|linux-gnu|'`
;; ;;
-sunos5*) -sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'` os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;; ;;
-sunos6*) -sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'` os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;; ;;
-opened*) -opened*)
os=-openedition os=-openedition
@ -1454,12 +1435,6 @@ case $os in
-wince*) -wince*)
os=-wince os=-wince
;; ;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*) -utek*)
os=-bsd os=-bsd
;; ;;
@ -1484,7 +1459,7 @@ case $os in
-nova*) -nova*)
os=-rtmk-nova os=-rtmk-nova
;; ;;
-ns2 ) -ns2)
os=-nextstep2 os=-nextstep2
;; ;;
-nsk*) -nsk*)
@ -1506,7 +1481,7 @@ case $os in
-oss*) -oss*)
os=-sysv3 os=-sysv3
;; ;;
-svr4) -svr4*)
os=-sysv4 os=-sysv4
;; ;;
-svr3) -svr3)
@ -1521,24 +1496,28 @@ case $os in
-ose*) -ose*)
os=-ose os=-ose
;; ;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint os=-mint
;; ;;
-aros*)
os=-aros
;;
-zvmoe) -zvmoe)
os=-zvmoe os=-zvmoe
;; ;;
-dicos*) -dicos*)
os=-dicos os=-dicos
;; ;;
-pikeos*)
# Until real need of OS specific support for
# particular features comes up, bare metal
# configurations are quite functional.
case $basic_machine in
arm*)
os=-eabi
;;
*)
os=-elf
;;
esac
;;
-nacl*) -nacl*)
;; ;;
-ios) -ios)
@ -1548,7 +1527,7 @@ case $os in
*) *)
# Get rid of the `-' at the beginning of $os. # Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'` os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1 exit 1
;; ;;
esac esac
@ -1638,12 +1617,12 @@ case $basic_machine in
sparc-* | *-sun) sparc-* | *-sun)
os=-sunos4.1.1 os=-sunos4.1.1
;; ;;
pru-*)
os=-elf
;;
*-be) *-be)
os=-beos os=-beos
;; ;;
*-haiku)
os=-haiku
;;
*-ibm) *-ibm)
os=-aix os=-aix
;; ;;
@ -1683,7 +1662,7 @@ case $basic_machine in
m88k-omron*) m88k-omron*)
os=-luna os=-luna
;; ;;
*-next ) *-next)
os=-nextstep os=-nextstep
;; ;;
*-sequent) *-sequent)
@ -1698,9 +1677,6 @@ case $basic_machine in
i370-*) i370-*)
os=-mvs os=-mvs
;; ;;
*-next)
os=-nextstep3
;;
*-gould) *-gould)
os=-sysv os=-sysv
;; ;;
@ -1810,15 +1786,15 @@ case $basic_machine in
vendor=stratus vendor=stratus
;; ;;
esac esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;; ;;
esac esac
echo $basic_machine$os echo "$basic_machine$os"
exit exit
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='" # time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d" # time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'" # time-stamp-end: "'"

2404
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,10 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
origcflags="$CFLAGS"
AC_PREREQ(2.61) AC_PREREQ(2.61)
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//')) AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
AC_CONFIG_SRCDIR([src/tincd.c]) AC_CONFIG_SRCDIR([src/tincd.c])
AC_GNU_SOURCE
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall]) AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
@ -19,10 +20,12 @@ dnl Checks for programs.
AC_PROG_CC_C99 AC_PROG_CC_C99
AC_PROG_CPP AC_PROG_CPP
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S
AM_PROG_CC_C_O AM_PROG_CC_C_O
dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS.
AX_CODE_COVERAGE
AS_IF([test "x$enable_code_coverage" = "xyes" -a "x$origcflags" = "x"], [CFLAGS=""])
dnl Check and set OS dnl Check and set OS
AC_CANONICAL_HOST AC_CANONICAL_HOST
@ -117,7 +120,7 @@ AC_ARG_WITH(systemd,
[ systemd=false ] [ systemd=false ]
) )
AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="/lib/systemd/system"], AS_IF([test "x$with_systemd" = "xyes"], [systemd_path="\${libdir}/systemd/system"],
[AS_IF([test "x$with_systemd" = "xno"], [systemd=false])]) [AS_IF([test "x$with_systemd" = "xno"], [systemd=false])])
AC_SUBST(systemd_path, $systemd_path) AC_SUBST(systemd_path, $systemd_path)
@ -178,6 +181,7 @@ AC_CHECK_HEADERS([netinet/tcp.h netinet/ip_icmp.h netinet/icmp6.h],
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
tinc_ATTRIBUTE(__malloc__) tinc_ATTRIBUTE(__malloc__)
tinc_ATTRIBUTE(__nonnull__)
tinc_ATTRIBUTE(__warn_unused_result__) tinc_ATTRIBUTE(__warn_unused_result__)
AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , , AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip, struct icmp, struct ip6_hdr, struct icmp6_hdr, struct nd_neighbor_solicit, struct nd_opt_hdr], , ,
@ -186,7 +190,7 @@ AC_CHECK_TYPES([struct ether_header, struct arphdr, struct ether_arp, struct ip,
dnl Checks for library functions. dnl Checks for library functions.
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname], AC_CHECK_FUNCS([asprintf daemon fchmod flock fork gettimeofday mlockall putenv recvmmsg strsignal nanosleep unsetenv vsyslog devname fdevname],
[], [], [#include "$srcdir/src/have.h"] [], [], [#include "$srcdir/src/have.h"]
) )
@ -257,6 +261,11 @@ AC_ARG_ENABLE(jumbograms,
] ]
) )
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile gui/Makefile test/Makefile systemd/Makefile]) dnl Ensure runstatedir is set if we are using a version of autoconf that does not support it
if test "x$runstatedir" = "x"; then
AC_SUBST([runstatedir], ['${localstatedir}/run'])
fi
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile test/Makefile systemd/Makefile])
AC_OUTPUT AC_OUTPUT

View file

@ -1,9 +1,9 @@
#! /bin/sh #! /bin/sh
# depcomp - compile a program generating dependencies as side-effects # depcomp - compile a program generating dependencies as side-effects
scriptversion=2016-01-11.22; # UTC scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2017 Free Software Foundation, Inc. # Copyright (C) 1999-2018 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@ scriptversion=2016-01-11.22; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@ -783,7 +783,7 @@ exit 0
# Local Variables: # Local Variables:
# mode: shell-script # mode: shell-script
# sh-indentation: 2 # sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0" # time-stamp-time-zone: "UTC0"

View file

@ -1,23 +1,13 @@
## Process this file with automake to get Makefile.in ## Process this file with automake to get Makefile.in
info_TEXINFOS = tinc.texi info_TEXINFOS = tinc.texi
tinc_TEXINFOS = tincinclude.texi
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
# Use `ginstall' in the definition of man_MANS to avoid
# confusion with the `install' target. The install rule transforms `ginstall'
# to install before applying any user-specified name transformations.
transform = s/ginstall/install/; @program_transform_name@
# For additional rules usually of interest only to the maintainer,
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
tincd.8.html: tincd.8 tincd.8.html: tincd.8
$(AM_V_GEN)w3mman2html $? > $@ $(AM_V_GEN)w3mman2html $? > $@
@ -35,21 +25,20 @@ substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \
-e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@VERSION\@',"$(VERSION)",g \
-e s,'@sysconfdir\@',"$(sysconfdir)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \
-e s,'@runstatedir\@',"$(runstatedir)",g \
-e s,'@localstatedir\@',"$(localstatedir)",g -e s,'@localstatedir\@',"$(localstatedir)",g
tincd.8: tincd.8.in tincd.8: $(srcdir)/tincd.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
tinc.8: tinc.8.in tinc.8: $(srcdir)/tinc.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
tinc-gui.8: tinc-gui.8.in tinc-gui.8: $(srcdir)/tinc-gui.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
tinc.conf.5: tinc.conf.5.in tinc.conf.5: $(srcdir)/tinc.conf.5.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
tincinclude.texi: tincinclude.texi.in tincinclude.texi: $(srcdir)/tincinclude.texi.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@
tinc.texi: tincinclude.texi

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -78,6 +78,7 @@ install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA) INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = : NORMAL_INSTALL = :
PRE_INSTALL = : PRE_INSTALL = :
POST_INSTALL = : POST_INSTALL = :
@ -93,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -198,13 +200,8 @@ man8dir = $(mandir)/man8
NROFF = nroff NROFF = nroff
MANS = $(man_MANS) MANS = $(man_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in texinfo.tex am__DIST_COMMON = $(srcdir)/Makefile.in $(tinc_TEXINFOS) texinfo.tex
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
# Use `ginstall' in the definition of man_MANS to avoid
# confusion with the `install' target. The install rule transforms `ginstall'
# to install before applying any user-specified name transformations.
transform = s/ginstall/install/; @program_transform_name@
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@ AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@ -215,6 +212,12 @@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCDEPMODE = @CCDEPMODE@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@ CURSES_LIBS = @CURSES_LIBS@
@ -226,16 +229,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@ GREP = @GREP@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -250,6 +255,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@ READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
@ -307,13 +313,15 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
info_TEXINFOS = tinc.texi info_TEXINFOS = tinc.texi
tinc_TEXINFOS = tincinclude.texi
man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8
EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config
CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi sample-config.tar.gz CLEANFILES = *.html tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi
substitute = sed \ substitute = sed \
-e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \
-e s,'@VERSION\@',"$(VERSION)",g \ -e s,'@VERSION\@',"$(VERSION)",g \
-e s,'@sysconfdir\@',"$(sysconfdir)",g \ -e s,'@sysconfdir\@',"$(sysconfdir)",g \
-e s,'@runstatedir\@',"$(runstatedir)",g \
-e s,'@localstatedir\@',"$(localstatedir)",g -e s,'@localstatedir\@',"$(localstatedir)",g
all: all-am all: all-am
@ -337,8 +345,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \ *config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -393,10 +401,10 @@ $(am__aclocal_m4_deps):
else \ else \
rm -rf $(@:.html=.htp); exit 1; \ rm -rf $(@:.html=.htp); exit 1; \
fi fi
$(srcdir)/tinc.info: tinc.texi $(srcdir)/tinc.info: tinc.texi $(tinc_TEXINFOS)
tinc.dvi: tinc.texi tinc.dvi: tinc.texi $(tinc_TEXINFOS)
tinc.pdf: tinc.texi tinc.pdf: tinc.texi $(tinc_TEXINFOS)
tinc.html: tinc.texi tinc.html: tinc.texi $(tinc_TEXINFOS)
.dvi.ps: .dvi.ps:
$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
$(DVIPS) $(AM_V_texinfo) -o $@ $< $(DVIPS) $(AM_V_texinfo) -o $@ $<
@ -583,7 +591,10 @@ ctags CTAGS:
cscope cscopelist: cscope cscopelist:
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \ list='$(DISTFILES)'; \
@ -835,12 +846,6 @@ uninstall-man: uninstall-man5 uninstall-man8
.PRECIOUS: Makefile .PRECIOUS: Makefile
# For additional rules usually of interest only to the maintainer,
# see GNUmakefile and Makefile.maint.
sample-config.tar.gz: sample-config
$(AM_V_GEN)GZIP=$(GZIP_ENV) $(AMTAR) chozf $@ --exclude .svn $<
tincd.8.html: tincd.8 tincd.8.html: tincd.8
$(AM_V_GEN)w3mman2html $? > $@ $(AM_V_GEN)w3mman2html $? > $@
@ -853,22 +858,20 @@ tinc-gui.8.html: tinc-gui.8
tinc.conf.5.html: tinc.conf.5 tinc.conf.5.html: tinc.conf.5
$(AM_V_GEN)w3mman2html $? > $@ $(AM_V_GEN)w3mman2html $? > $@
tincd.8: tincd.8.in tincd.8: $(srcdir)/tincd.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tincd.8.in > $@
tinc.8: tinc.8.in tinc.8: $(srcdir)/tinc.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc.8.in > $@
tinc-gui.8: tinc-gui.8.in tinc-gui.8: $(srcdir)/tinc-gui.8.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc-gui.8.in > $@
tinc.conf.5: tinc.conf.5.in tinc.conf.5: $(srcdir)/tinc.conf.5.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tinc.conf.5.in > $@
tincinclude.texi: tincinclude.texi.in tincinclude.texi: $(srcdir)/tincinclude.texi.in
$(AM_V_GEN)$(substitute) $? > $@ $(AM_V_GEN)$(substitute) $(srcdir)/tincinclude.texi.in > $@
tinc.texi: tincinclude.texi
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.

Binary file not shown.

View file

@ -0,0 +1,15 @@
# Sample host configuration file
# The real IP address of this tinc host. Can be used by other tinc hosts.
Address = 123.234.35.67
# Portnumber for incoming connections. Default is 655.
Port = 655
# Subnet on the virtual private network that is local for this host.
Subnet = 192.168.1.0/24
# The public key generated by `tincd -n example -K' is stored here
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

View file

@ -0,0 +1,16 @@
# Sample host configuration file
# This file was generated by host beta.
# The real IP address of this tinc host. Can be used by other tinc hosts.
Address = 123.45.67.189
# Portnumber for incoming connections. Default is 655.
Port = 6500
# Subnet on the virtual private network that is local for this host.
Subnet = 192.168.2.0/24
# The public key generated by `tincd -n example -K' is stored here
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

View file

@ -0,0 +1 @@
# Generate this file with `tincd -n example -K`

View file

@ -0,0 +1,4 @@
#!/bin/sh
# This file closes down the tap device.
ifconfig $INTERFACE down

11
doc/sample-config/tinc-up Normal file
View file

@ -0,0 +1,11 @@
#!/bin/sh
# This file sets up the tap device.
# It gives you the freedom to do anything you want with it.
# Use the correct name for the tap device:
# The environment variable $INTERFACE is set to the right name
# on most platforms, but if it doesn't work try to set it manually.
# Give it the right ip and netmask. Remember, the subnet of the
# tap device must be larger than that of the individual Subnets
# as defined in the host configuration file!
ifconfig $INTERFACE 192.168.1.1 netmask 255.255.0.0

View file

@ -0,0 +1,22 @@
# Sample tinc configuration file
# This is a comment.
# Spaces and tabs are eliminated.
# The = sign isn't strictly necessary any longer, though you may want
# to leave it in as it improves readability :)
# Variable names are treated case insensitive.
# The name of this tinc host. Required.
Name = alpha
# The internet host to connect with.
# Comment these out to make yourself a listen-only connection
# You must use the name of another tinc host.
# May be used multiple times for redundance.
ConnectTo = beta
# The tap device tinc will use.
# Default is /dev/tap0 for ethertap or FreeBSD,
# /dev/tun0 for Solaris and OpenBSD,
# and /dev/net/tun for Linux tun/tap device.
Device = /dev/net/tun

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,7 @@ Use the cookie from
.Ar FILENAME .Ar FILENAME
to authenticate with a running tinc daemon. to authenticate with a running tinc daemon.
If unspecified, the default is If unspecified, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. .Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl -help .It Fl -help
Display short list of options. Display short list of options.
.El .El

View file

@ -7,10 +7,11 @@
.Nd tinc VPN control .Nd tinc VPN control
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl cn .Op Fl bcn
.Op Fl -config Ns = Ns Ar DIR .Op Fl -config Ns = Ns Ar DIR
.Op Fl -net Ns = Ns Ar NETNAME .Op Fl -net Ns = Ns Ar NETNAME
.Op Fl -pidfile Ns = Ns Ar FILENAME .Op Fl -pidfile Ns = Ns Ar FILENAME
.Op Fl -batch
.Op Fl -force .Op Fl -force
.Op Fl -help .Op Fl -help
.Op Fl -version .Op Fl -version
@ -54,7 +55,9 @@ Use the cookie from
.Ar FILENAME .Ar FILENAME
to authenticate with a running tinc daemon. to authenticate with a running tinc daemon.
If unspecified, the default is If unspecified, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. .Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl b, -batch
Don't ask for anything (non-interactive mode).
.It Fl -force .It Fl -force
Force some commands to work despite warnings. Force some commands to work despite warnings.
.It Fl -help .It Fl -help
@ -249,7 +252,7 @@ to allow a signature from any node whose public key is known.
If no If no
.Ar filename .Ar filename
is given, the file is read from standard input. is given, the file is read from standard input.
If the verification is succesful, If the verification is successful,
a copy of the input with the signature removed is written to standard output, a copy of the input with the signature removed is written to standard output,
and the exit code will be zero. and the exit code will be zero.
If the verification failed, If the verification failed,

View file

@ -114,7 +114,7 @@ If
.Qq any .Qq any
is selected, then depending on the operating system both IPv4 and IPv6 or just is selected, then depending on the operating system both IPv4 and IPv6 or just
IPv6 listening sockets will be created. IPv6 listening sockets will be created.
.It Va AutoConnect Li = yes | no Po no Pc Bq experimental .It Va AutoConnect Li = yes | no Po yes
If set to yes, If set to yes,
.Nm tinc .Nm tinc
will automatically set up meta connections to other nodes, will automatically set up meta connections to other nodes,
@ -177,7 +177,7 @@ line).
.Pp .Pp
If you don't specify a host with If you don't specify a host with
.Va ConnectTo .Va ConnectTo
and don't enable and have disabled
.Va AutoConnect , .Va AutoConnect ,
.Nm tinc .Nm tinc
won't try to connect to other daemons at all, won't try to connect to other daemons at all,
@ -242,7 +242,7 @@ Packets received for the local node are written to it.
Create a UNIX socket with the filename specified by Create a UNIX socket with the filename specified by
.Va Device , .Va Device ,
or or
.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket .Pa @runstatedir@/ Ns Ar NETNAME Ns Pa .umlsocket
if not specified. if not specified.
.Nm tinc .Nm tinc
will wait for a User Mode Linux instance to connect to this socket. will wait for a User Mode Linux instance to connect to this socket.
@ -251,7 +251,7 @@ Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
using the UNIX socket specified by using the UNIX socket specified by
.Va Device , .Va Device ,
or or
.Pa @localstatedir@/run/vde.ctl .Pa @runstatedir@/vde.ctl
if not specified. if not specified.
.El .El
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device, Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
@ -306,10 +306,16 @@ Incoming packets that are meant for another node are forwarded by tinc internall
.Pp .Pp
This is the default mode, and unless you really know you need another forwarding mode, don't change it. This is the default mode, and unless you really know you need another forwarding mode, don't change it.
.It kernel .It kernel
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node. Incoming packets using the legacy protocol are always sent to the TUN/TAP device,
even if the packets are not for the local node.
This is less efficient, but allows the kernel to apply its routing and firewall rules on them, This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
and can also help debugging. and can also help debugging.
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
.El .El
.It Va FWMark Li = Ar value Po 0 Pc Bq experimental
When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark.
This can be used for mark-based routing or for packet filtering.
This option is currently only supported on Linux.
.It Va Hostnames Li = yes | no Pq no .It Va Hostnames Li = yes | no Pq no
This option selects whether IP addresses (both real and on the VPN) should 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 be resolved. Since DNS lookups are blocking, it might affect tinc's
@ -786,7 +792,7 @@ its connection to the virtual network device.
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/ .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitations/
This directory contains outstanding invitations. This directory contains outstanding invitations.
.It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data .It Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /invitation-data
After a succesful join, this file contains a copy of the invitation data received. After a successful join, this file contains a copy of the invitation data received.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr tincd 8 , .Xr tincd 8 ,

View file

@ -1,14 +1,14 @@
This is tinc.info, produced by makeinfo version 6.4.90 from tinc.texi. This is tinc.info, produced by makeinfo version 6.5 from tinc.texi.
INFO-DIR-SECTION Networking tools INFO-DIR-SECTION Networking tools
START-INFO-DIR-ENTRY START-INFO-DIR-ENTRY
* tinc: (tinc). The tinc Manual. * tinc: (tinc). The tinc Manual.
END-INFO-DIR-ENTRY END-INFO-DIR-ENTRY
This is the info manual for tinc version 1.1pre14-62-g958a751e, a This is the info manual for tinc version 1.1pre17, a Virtual Private
Virtual Private Network daemon. Network daemon.
Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen
<guus@tinc-vpn.org> and Wessel Dankers <wsl@tinc-vpn.org>. <guus@tinc-vpn.org> and Wessel Dankers <wsl@tinc-vpn.org>.
Permission is granted to make and distribute verbatim copies of this Permission is granted to make and distribute verbatim copies of this
@ -119,7 +119,7 @@ both the receiving and sending end, it has become largely
runtime-configurable--in short, it has become a full-fledged runtime-configurable--in short, it has become a full-fledged
professional package. professional package.
Tinc also allows more than two sites to connect to eachother and form a Tinc also allows more than two sites to connect to each other and form a
single VPN. Traditionally VPNs are created by making tunnels, which only single VPN. Traditionally VPNs are created by making tunnels, which only
have two endpoints. Larger VPNs with more sites are created by adding have two endpoints. Larger VPNs with more sites are created by adding
more tunnels. Tinc takes another approach: only endpoints are more tunnels. Tinc takes another approach: only endpoints are
@ -285,7 +285,7 @@ File: tinc.info, Node: Libraries, Prev: Configuring the kernel, Up: Preparati
============= =============
Before you can configure or build tinc, you need to have the LibreSSL or Before you can configure or build tinc, you need to have the LibreSSL or
OpenSSL, zlib, lzo, curses and readline libraries installed on your OpenSSL, zlib, LZO, curses and readline libraries installed on your
system. If you try to configure tinc without having them installed, system. If you try to configure tinc without having them installed,
configure will give you an error message, and stop. configure will give you an error message, and stop.
@ -293,7 +293,7 @@ configure will give you an error message, and stop.
* LibreSSL/OpenSSL:: * LibreSSL/OpenSSL::
* zlib:: * zlib::
* lzo:: * LZO::
* libcurses:: * libcurses::
* libreadline:: * libreadline::
@ -306,7 +306,7 @@ File: tinc.info, Node: LibreSSL/OpenSSL, Next: zlib, Up: Libraries
For all cryptography-related functions, tinc uses the functions provided For all cryptography-related functions, tinc uses the functions provided
by the LibreSSL or the OpenSSL library. by the LibreSSL or the OpenSSL library.
If this library is not installed, you wil get an error when configuring If this library is not installed, you will get an error when configuring
tinc for build. Support for running tinc with other cryptographic tinc for build. Support for running tinc with other cryptographic
libraries installed _may_ be added in the future. libraries installed _may_ be added in the future.
@ -316,7 +316,7 @@ of this package.
If your operating system comes neither with LibreSSL or OpenSSL, you If your operating system comes neither with LibreSSL or OpenSSL, you
have to install one manually. It is recommended that you get the latest have to install one manually. It is recommended that you get the latest
version of LibreSSL from <http://www.libressl.org/>. Instructions on version of LibreSSL from <https://www.libressl.org/>. Instructions on
how to configure, build and install this package are included within the how to configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries package. Please make sure you build development and runtime libraries
(which is the default). (which is the default).
@ -357,7 +357,7 @@ present the following exemption:
Markus F.X.J. Oberhumer Markus F.X.J. Oberhumer
 
File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Libraries File: tinc.info, Node: zlib, Next: LZO, Prev: LibreSSL/OpenSSL, Up: Libraries
2.2.2 zlib 2.2.2 zlib
---------- ----------
@ -365,7 +365,7 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: LibreSSL/OpenSSL, Up: Librarie
For the optional compression of UDP packets, tinc uses the functions For the optional compression of UDP packets, tinc uses the functions
provided by the zlib library. provided by the zlib library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install the zlib library, or disable configure script. You can either install the zlib library, or disable
support for zlib compression by using the "-disable-zlib" option when support for zlib compression by using the "-disable-zlib" option when
running the configure script. Note that if you disable support for running the configure script. Note that if you disable support for
@ -377,19 +377,19 @@ available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install zlib manually, you can get the source code from If you have to install zlib manually, you can get the source code from
<http://www.zlib.net/>. Instructions on how to configure, build and <https://zlib.net/>. Instructions on how to configure, build and
install this package are included within the package. Please make sure install this package are included within the package. Please make sure
you build development and runtime libraries (which is the default). you build development and runtime libraries (which is the default).
 
File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries File: tinc.info, Node: LZO, Next: libcurses, Prev: zlib, Up: Libraries
2.2.3 lzo 2.2.3 LZO
--------- ---------
Another form of compression is offered using the LZO library. Another form of compression is offered using the LZO library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install the LZO library, or disable configure script. You can either install the LZO library, or disable
support for LZO compression by using the "-disable-lzo" option when support for LZO compression by using the "-disable-lzo" option when
running the configure script. Note that if you disable support for LZO, running the configure script. Note that if you disable support for LZO,
@ -400,29 +400,29 @@ You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install lzo manually, you can get the source code from If you have to install LZO manually, you can get the source code from
<https://www.oberhumer.com/opensource/lzo/>. Instructions on how to <https://www.oberhumer.com/opensource/lzo/>. Instructions on how to
configure, build and install this package are included within the configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries package. Please make sure you build development and runtime libraries
(which is the default). (which is the default).
 
File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Libraries File: tinc.info, Node: libcurses, Next: libreadline, Prev: LZO, Up: Libraries
2.2.4 libcurses 2.2.4 libcurses
--------------- ---------------
For the "tinc top" command, tinc requires a curses library. For the "tinc top" command, tinc requires a curses library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install a suitable curses library, or configure script. You can either install a suitable curses library, or
disable all functionality that depends on a curses library by using the disable all functionality that depends on a curses library by using the
"-disable-curses" option when running the configure script. "-disable-curses" option when running the configure script.
There are several curses libraries. It is recommended that you install There are several curses libraries. It is recommended that you install
"ncurses" (<http://invisible-island.net/ncurses/>), however other curses "ncurses" (<https://invisible-island.net/ncurses/>), however other
libraries should also work. In particular, "PDCurses" curses libraries should also work. In particular, "PDCurses"
(<http://pdcurses.sourceforge.net/>) is recommended if you want to (<https://pdcurses.sourceforge.io/>) is recommended if you want to
compile tinc for Windows. compile tinc for Windows.
You can use your operating system's package manager to install this if You can use your operating system's package manager to install this if
@ -438,7 +438,7 @@ File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries
For the "tinc" command's shell functionality, tinc uses the readline For the "tinc" command's shell functionality, tinc uses the readline
library. library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install a suitable readline library, configure script. You can either install a suitable readline library,
or disable all functionality that depends on a readline library by using or disable all functionality that depends on a readline library by using
the "-disable-readline" option when running the configure script. the "-disable-readline" option when running the configure script.
@ -448,7 +448,7 @@ available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install libreadline manually, you can get the source code If you have to install libreadline manually, you can get the source code
from <http://www.gnu.org/software/readline/>. Instructions on how to from <https://www.gnu.org/software/readline/>. Instructions on how to
configure, build and install this package are included within the configure, build and install this package are included within the
package. Please make sure you build development and runtime libraries package. Please make sure you build development and runtime libraries
(which is the default). (which is the default).
@ -625,7 +625,7 @@ Do you want to run tinc in router mode or switch mode? These questions
can only be answered by yourself, you will not find the answers in this can only be answered by yourself, you will not find the answers in this
documentation. Make sure you have an adequate understanding of networks documentation. Make sure you have an adequate understanding of networks
in general. A good resource on networking is the Linux Network in general. A good resource on networking is the Linux Network
Administrators Guide (http://www.tldp.org/LDP/nag2/). Administrators Guide (https://www.tldp.org/LDP/nag2/).
If you have everything clearly pictured in your mind, proceed in the If you have everything clearly pictured in your mind, proceed in the
following order: First, create the initial configuration files and following order: First, create the initial configuration files and
@ -651,7 +651,7 @@ assign a NETNAME to your VPN. It is not required if you only run one
tinc daemon, it doesn't even have to be the same on all the nodes of tinc daemon, it doesn't even have to be the same on all the nodes of
your VPN, but it is recommended that you choose one anyway. your VPN, but it is recommended that you choose one anyway.
We will asume you use a netname throughout this document. This means We will assume you use a netname throughout this document. This means
that you call tinc with the -n argument, which will specify the netname. that you call tinc with the -n argument, which will specify the netname.
The effect of this option is that tinc will set its configuration root The effect of this option is that tinc will set its configuration root
@ -675,22 +675,17 @@ File: tinc.info, Node: How connections work, Next: Configuration files, Prev:
======================== ========================
When tinc starts up, it parses the command-line options and then reads When tinc starts up, it parses the command-line options and then reads
in the configuration file tinc.conf. If it sees one or more 'ConnectTo' in the configuration file tinc.conf. It will then start listening for
values pointing to other tinc daemons in that file, it will try to incoming connection from other daemons, and will by default also
connect to those other daemons. Whether this succeeds or not and automatically try to connect to known peers. By default, tinc will try
whether 'ConnectTo' is specified or not, tinc will listen for incoming to keep at least 3 working meta-connections alive at all times.
connection from other deamons. If you did specify a 'ConnectTo' value
and the other side is not responding, tinc will keep retrying. This
means that once started, tinc will stay running until you tell it to
stop, and failures to connect to other tinc daemons will not stop your
tinc daemon for trying again later. This means you don't have to
intervene if there are temporary network problems.
There is no real distinction between a server and a client in tinc. If There is no real distinction between a server and a client in tinc. If
you wish, you can view a tinc daemon without a 'ConnectTo' value as a you wish, you can view a tinc daemon without a 'ConnectTo' statement in
server, and one which does specify such a value as a client. It does tinc.conf and 'AutoConnect = no' as a server, and one which does have
not matter if two tinc daemons have a 'ConnectTo' value pointing to each one or more 'ConnectTo' statements or 'Autoconnect = yes' (which is the
other however. default) as a client. It does not matter if two tinc daemons have a
'ConnectTo' value pointing to each other however.
Connections specified using 'ConnectTo' are so-called meta-connections. Connections specified using 'ConnectTo' are so-called meta-connections.
Tinc daemons exchange information about all other daemon they know about Tinc daemons exchange information about all other daemon they know about
@ -712,7 +707,7 @@ might also prevent direct communication. In that case, VPN packets
between A and C will be forwarded by B. between A and C will be forwarded by B.
In effect, all nodes in the VPN will be able to talk to each other, as In effect, all nodes in the VPN will be able to talk to each other, as
long as their is a path of meta-connections between them, and whenever long as there is a path of meta-connections between them, and whenever
possible, two nodes will communicate with each other directly. possible, two nodes will communicate with each other directly.
 
@ -725,8 +720,8 @@ The actual configuration of the daemon is done in the file
'/etc/tinc/NETNAME/tinc.conf' and at least one other file in the '/etc/tinc/NETNAME/tinc.conf' and at least one other file in the
directory '/etc/tinc/NETNAME/hosts/'. directory '/etc/tinc/NETNAME/hosts/'.
An optionnal directory '/etc/tinc/NETNAME/conf.d' can be added from An optional directory '/etc/tinc/NETNAME/conf.d' can be added from which
which any .conf file will be read. any .conf file will be read.
These file consists of comments (lines started with a #) or assignments These file consists of comments (lines started with a #) or assignments
in the form of in the form of
@ -771,7 +766,7 @@ AddressFamily = <ipv4|ipv6|any> (any)
system both IPv4 and IPv6 or just IPv6 listening sockets will be system both IPv4 and IPv6 or just IPv6 listening sockets will be
created. created.
AutoConnect = <yes|no> (no) [experimental] AutoConnect = <yes|no> (yes)
If set to yes, tinc will automatically set up meta connections to If set to yes, tinc will automatically set up meta connections to
other nodes, without requiring CONNECTTO variables. other nodes, without requiring CONNECTTO variables.
@ -831,7 +826,7 @@ ConnectTo = <NAME>
names should be known to this tinc daemon (i.e., there should be a names should be known to this tinc daemon (i.e., there should be a
host configuration file for the name on the ConnectTo line). host configuration file for the name on the ConnectTo line).
If you don't specify a host with ConnectTo and don't enable If you don't specify a host with ConnectTo and have disabled
AutoConnect, tinc won't try to connect to other daemons at all, and AutoConnect, tinc won't try to connect to other daemons at all, and
will instead just listen for incoming connections. will instead just listen for incoming connections.
@ -966,16 +961,24 @@ Forwarding = <off|internal|kernel> (internal) [experimental]
another forwarding mode, don't change it. another forwarding mode, don't change it.
kernel kernel
Incoming packets are always sent to the TUN/TAP device, even Incoming packets using the legacy protocol are always sent to
if the packets are not for the local node. This is less the TUN/TAP device, even if the packets are not for the local
efficient, but allows the kernel to apply its routing and node. This is less efficient, but allows the kernel to apply
firewall rules on them, and can also help debugging. its routing and firewall rules on them, and can also help
debugging. Incoming packets using the SPTPS protocol are
dropped, since they are end-to-end encrypted.
FWMark = <VALUE> (0) [experimental]
When set to a non-zero value, all TCP and UDP sockets created by
tinc will use the given value as the firewall mark. This can be
used for mark-based routing or for packet filtering. This option
is currently only supported on Linux.
Hostnames = <yes|no> (no) Hostnames = <yes|no> (no)
This option selects whether IP addresses (both real and on the VPN) This option selects whether IP addresses (both real and on the VPN)
should be resolved. Since DNS lookups are blocking, it might should be resolved. Since DNS lookups are blocking, it might
affect tinc's efficiency, even stopping the daemon for a few affect tinc's efficiency, even stopping the daemon for a few
seconds everytime it does a lookup if your DNS server is not seconds every time it does a lookup if your DNS server is not
responding. responding.
This does not affect resolving hostnames to IP addresses from the This does not affect resolving hostnames to IP addresses from the
@ -1093,7 +1096,7 @@ PriorityInheritance = <yes|no> (no) [experimental]
PrivateKey = <KEY> [obsolete] PrivateKey = <KEY> [obsolete]
This is the RSA private key for tinc. However, for safety reasons This is the RSA private key for tinc. However, for safety reasons
it is advised to store private keys of any kind in separate files. it is advised to store private keys of any kind in separate files.
This prevents accidental eavesdropping if you are editting the This prevents accidental eavesdropping if you are editing the
configuration file. configuration file.
PrivateKeyFile = <PATH> ('/etc/tinc/NETNAME/rsa_key.priv') PrivateKeyFile = <PATH> ('/etc/tinc/NETNAME/rsa_key.priv')
@ -1243,7 +1246,7 @@ ClampMSS = <yes|no> (yes)
Compression = <LEVEL> (0) Compression = <LEVEL> (0)
This option sets the level of compression used for UDP packets. This option sets the level of compression used for UDP packets.
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 Possible values are 0 (off), 1 (fast zlib) and any integer up to 9
(best zlib), 10 (fast lzo) and 11 (best lzo). (best zlib), 10 (fast LZO) and 11 (best LZO).
Digest = <DIGEST> (sha1) Digest = <DIGEST> (sha1)
The digest algorithm used to authenticate UDP packets using the The digest algorithm used to authenticate UDP packets using the
@ -1299,9 +1302,9 @@ PublicKeyFile = <PATH> [obsolete]
Subnet = <ADDRESS[/PREFIXLENGTH[#WEIGHT]]> Subnet = <ADDRESS[/PREFIXLENGTH[#WEIGHT]]>
The subnet which this tinc daemon will serve. Tinc tries to look The subnet which this tinc daemon will serve. Tinc tries to look
up which other daemon it should send a packet to by searching the up which other daemon it should send a packet to by searching the
appropiate subnet. If the packet matches a subnet, it will be sent appropriate subnet. If the packet matches a subnet, it will be
to the daemon who has this subnet in his host configuration file. sent to the daemon who has this subnet in his host configuration
Multiple subnet lines can be specified for each daemon. file. Multiple subnet lines can be specified for each daemon.
Subnets can either be single MAC, IPv4 or IPv6 addresses, in which Subnets can either be single MAC, IPv4 or IPv6 addresses, in which
case a subnet consisting of only that single address is assumed, or case a subnet consisting of only that single address is assumed, or
@ -1513,26 +1516,14 @@ run:
tinc -n NETNAME add address foo.example.org tinc -n NETNAME add address foo.example.org
If you already know to which daemons your daemon should make
meta-connections, you should configure that now as well. Suppose you
want to connect to a daemon named "bar", run:
tinc -n NETNAME add connectto bar
Note that you specify the Name of the other daemon here, not an IP
address or hostname! When you start tinc, and it tries to make a
connection to "bar", it will look for a host configuration file named
'hosts/bar', and will read Address statements and public keys from that
file.
Step 2. Exchanging configuration files. Step 2. Exchanging configuration files.
....................................... .......................................
If your daemon has a ConnectTo = bar statement in its 'tinc.conf' file, In order for two tinc daemons to be able to connect to each other, they
or if bar has a ConnectTo your daemon, then you both need each other's each need the other's host configuration files. So if you want foo to
host configuration files. You should send 'hosts/NAME' to bar, and bar be able to connect with bar, You should send 'hosts/NAME' to bar, and
should send you his file which you should move to 'hosts/bar'. If you bar should send you his file which you should move to 'hosts/bar'. If
are on a UNIX platform, you can easily send an email containing the you are on a UNIX platform, you can easily send an email containing the
necessary information using the following command (assuming the owner of necessary information using the following command (assuming the owner of
bar has the email address bar@example.org): bar has the email address bar@example.org):
@ -1552,10 +1543,9 @@ following command:
| ssh bar.example.org tinc -n NETNAME exchange \ | ssh bar.example.org tinc -n NETNAME exchange \
| tinc -n NETNAME import | tinc -n NETNAME import
You should repeat this for all nodes you ConnectTo, or which ConnectTo You can repeat this for a few other nodes as well. It is not necessary
you. However, remember that you do not need to ConnectTo all nodes in to manually exchange host config files between all nodes; after the
the VPN; it is only necessary to create one or a few meta-connections, initial connections are made tinc will learn about all the other nodes
after the connections are made tinc will learn about all the other nodes
in the VPN, and will automatically make other connections as necessary. in the VPN, and will automatically make other connections as necessary.
 
@ -1692,11 +1682,9 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf': and in '/etc/tinc/company/tinc.conf':
Name = BranchB Name = BranchB
ConnectTo = BranchA
Note here that the internal address (on eth0) doesn't have to be the Note here that the internal address (on eth0) doesn't have to be the
same as on the VPN interface. Also, ConnectTo is given so that this same as on the VPN interface.
node will always try to connect to BranchA.
On all hosts, in '/etc/tinc/company/hosts/BranchB': On all hosts, in '/etc/tinc/company/hosts/BranchB':
@ -1722,7 +1710,6 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf': and in '/etc/tinc/company/tinc.conf':
Name = BranchC Name = BranchC
ConnectTo = BranchA
C already has another daemon that runs on port 655, so they have to C already has another daemon that runs on port 655, so they have to
reserve another port for tinc. It knows the portnumber it has to listen reserve another port for tinc. It knows the portnumber it has to listen
@ -1753,7 +1740,6 @@ In '/etc/tinc/company/tinc-up':
and in '/etc/tinc/company/tinc.conf': and in '/etc/tinc/company/tinc.conf':
Name = BranchD Name = BranchD
ConnectTo = BranchC
D will be connecting to C, which has a tincd running for this network on D will be connecting to C, which has a tincd running for this network on
port 2000. It knows the port number from the host configuration file. port 2000. It knows the port number from the host configuration file.
@ -1861,6 +1847,9 @@ command line options.
facility. If FILE is omitted, the default is facility. If FILE is omitted, the default is
'/var/log/tinc.NETNAME.log'. '/var/log/tinc.NETNAME.log'.
'--pidfile=FILE'
Write PID to FILE instead of '/var/run/tinc.NETNAME.pid'.
'--bypass-security' '--bypass-security'
Disables encryption and authentication. Only useful for debugging. Disables encryption and authentication. Only useful for debugging.
@ -1871,12 +1860,16 @@ command line options.
chroot is performed after all the initialization is done, after chroot is performed after all the initialization is done, after
writing pid files and opening network sockets. writing pid files and opening network sockets.
Note that this option alone does not do any good without -U/-user, This option is best used in combination with the -U/-user option
below. described below.
Note also that tinc can't run scripts anymore (such as tinc-down or You will need to ensure the chroot environment contains all the
host-up), unless it's setup to be runnable inside chroot files necessary for tinc to run correctly. Most importantly, for
environment. tinc to be able to resolve hostnames inside the chroot environment,
you must copy '/etc/resolv.conf' into the chroot directory. If you
want to be able to run scripts other than 'tinc-up' in the chroot,
you must ensure the appropriate shell is also installed in the
chroot, along with all its dependencies.
This option is not supported on all platforms. This option is not supported on all platforms.
'-U, --user=USER' '-U, --user=USER'
@ -2150,6 +2143,9 @@ File: tinc.info, Node: tinc runtime options, Next: tinc environment variables,
daemon. If unspecified, the default is daemon. If unspecified, the default is
'/var/run/tinc.NETNAME.pid'. '/var/run/tinc.NETNAME.pid'.
'-b, --batch'
Don't ask for anything (non-interactive mode).
'--force' '--force'
Force some commands to work despite warnings. Force some commands to work despite warnings.
@ -2353,8 +2349,8 @@ File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environ
NAME of the node must be given, or can be "." to check against the NAME of the node must be given, or can be "." to check against the
local node's public key, or "*" to allow a signature from any node local node's public key, or "*" to allow a signature from any node
whose public key is known. If no FILENAME is given, the file is whose public key is known. If no FILENAME is given, the file is
read from standard input. If the verification is succesful, a copy read from standard input. If the verification is successful, a
of the input with the signature removed is written to standard copy of the input with the signature removed is written to standard
output, and the exit code will be zero. If the verification output, and the exit code will be zero. If the verification
failed, nothing will be written to standard output, and the exit failed, nothing will be written to standard output, and the exit
code will be non-zero. code will be non-zero.
@ -2376,7 +2372,7 @@ Examples of changing the configuration using tinc:
tinc -n vpn init foo tinc -n vpn init foo
tinc -n vpn add Subnet 192.168.1.0/24 tinc -n vpn add Subnet 192.168.1.0/24
tinc -n vpn add bar.Address bar.example.com tinc -n vpn add bar.Address bar.example.com
tinc -n vpn add ConnectTo bar tinc -n vpn set Mode switch
tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com
 
@ -2400,7 +2396,7 @@ can be changed using the following keys:
<c> <c>
Toggle between displaying current traffic rates (in packets and Toggle between displaying current traffic rates (in packets and
bytes per second) and cummulative traffic (total packets and bytes bytes per second) and cumulative traffic (total packets and bytes
since the tinc daemon started). since the tinc daemon started).
<n> <n>
@ -2528,7 +2524,8 @@ invite' command looks like this:
The file is basically a concatenation of several host config blocks. The file is basically a concatenation of several host config blocks.
Each host config block starts with 'Name = ...'. Lines that look like Each host config block starts with 'Name = ...'. Lines that look like
'#---#' are not important, it just makes it easier for humans to read '#---#' are not important, it just makes it easier for humans to read
the file. the file. However, the first line of an invitation file _must_ always
start with 'Name = ...'.
The first host config block is always the one representing the invitee. The first host config block is always the one representing the invitee.
So the first Name statement determines the name that the invitee will So the first Name statement determines the name that the invitee will
@ -2582,7 +2579,7 @@ When an invitation is generated, the "invitation-created" script is
called (if it exists) right after the invitation file is written, but called (if it exists) right after the invitation file is written, but
before the URL has been written to stdout. This allows one to change before the URL has been written to stdout. This allows one to change
the invitation file automatically before the invitation URL is passed to the invitation file automatically before the invitation URL is passed to
the invitee. Here is an example shell script that aproximately the invitee. Here is an example shell script that approximately
recreates the default invitation file: recreates the default invitation file:
#!/bin/sh #!/bin/sh
@ -2684,8 +2681,7 @@ correct destination MAC address. In those modes every interface should
have a unique MAC address, so make sure they are not the same. Because have a unique MAC address, so make sure they are not the same. Because
switch and hub modes rely on MAC addresses to function correctly, these switch and hub modes rely on MAC addresses to function correctly, these
modes cannot be used on the following operating systems which don't have modes cannot be used on the following operating systems which don't have
a 'tap' style virtual network device: OpenBSD, NetBSD, Darwin and a 'tap' style virtual network device: NetBSD, Darwin and Solaris.
Solaris.
 
File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection File: tinc.info, Node: The meta-connection, Prev: The UDP tunnel, Up: The connection
@ -3189,14 +3185,29 @@ too short, and he doesn't like tinc's use of RSA during authentication.
We do not know of a security hole in the legacy protocol of tinc, but it We do not know of a security hole in the legacy protocol of tinc, but it
is not as strong as TLS or IPsec. is not as strong as TLS or IPsec.
The Sweet32 attack affects versions of tinc prior to 1.0.30.
On September 6th, 2018, Michael Yonly contacted us and provided
proof-of-concept code that allowed a remote attacker to create an
authenticated, one-way connection with a node, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to
be sent in plaintext. The first issue was trivial to exploit on tinc
versions prior to 1.0.30, but the changes in 1.0.30 to mitigate the
Sweet32 attack made this weakness much harder to exploit. These issues
have been fixed in tinc 1.0.35.
This version of tinc comes with an improved protocol, called Simple This version of tinc comes with an improved protocol, called Simple
Peer-to-Peer Security, which aims to be as strong as TLS with one of the Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with
strongest cipher suites. one of the strongest cipher suites. None of the above security issues
affected SPTPS. However, be aware that SPTPS is only used between nodes
running tinc 1.1pre* or later, and in a VPN with nodes running different
versions, the security might only be as good as that of the oldest
version.
Cryptography is a hard thing to get right. We cannot make any Cryptography is a hard thing to get right. We cannot make any
guarantees. Time, review and feedback are the only things that can guarantees. Time, review and feedback are the only things that can
prove the security of any cryptographic product. If you wish to review prove the security of any cryptographic product. If you wish to review
tinc or give us feedback, you are stronly encouraged to do so. tinc or give us feedback, you are strongly encouraged to do so.
 
File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top File: tinc.info, Node: Platform specific information, Next: About us, Prev: Technical information, Up: Top
@ -3208,6 +3219,7 @@ File: tinc.info, Node: Platform specific information, Next: About us, Prev: T
* Interface configuration:: * Interface configuration::
* Routes:: * Routes::
* Automatically starting tinc::
 
File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information File: tinc.info, Node: Interface configuration, Next: Routes, Up: Platform specific information
@ -3246,11 +3258,6 @@ Solaris 'ifconfig' INTERFACE 'inet6 plumb up'
Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH Darwin (MacOS/X) 'ifconfig' INTERFACE 'inet6' ADDRESS 'prefixlen' PREFIXLENGTH
Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH Windows 'netsh interface ipv6 add address' INTERFACE 'static' ADDRESS/PREFIXLENGTH
On some platforms, when running tinc in switch mode, the VPN interface
must be set to tap mode with an ifconfig command:
OpenBSD 'ifconfig' INTERFACE 'link0'
On Linux, it is possible to create a persistent tun/tap interface which On Linux, it is possible to create a persistent tun/tap interface which
will continue to exist even if tinc quit, although this is normally not will continue to exist even if tinc quit, although this is normally not
required. It can be useful to set up a tun/tap interface owned by a required. It can be useful to set up a tun/tap interface owned by a
@ -3260,7 +3267,7 @@ privileges at all.
Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME Linux 'ip tuntap add dev' INTERFACE 'mode' TUN|TAP 'user' USERNAME
 
File: tinc.info, Node: Routes, Prev: Interface configuration, Up: Platform specific information File: tinc.info, Node: Routes, Next: Automatically starting tinc, Prev: Interface configuration, Up: Platform specific information
9.2 Routes 9.2 Routes
========== ==========
@ -3295,6 +3302,72 @@ Solaris 'route add -inet6' NETWORK_ADDRESS'/'PREFIXLENGTH LOCAL_ADDRE
Darwin (MacOS/X) ? Darwin (MacOS/X) ?
Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE Windows 'netsh interface ipv6 add route' NETWORK ADDRESS/PREFIXLENGTH INTERFACE

File: tinc.info, Node: Automatically starting tinc, Prev: Routes, Up: Platform specific information
9.3 Automatically starting tinc
===============================
* Menu:
* Linux::
* Windows::
* Other platforms::

File: tinc.info, Node: Linux, Next: Windows, Up: Automatically starting tinc
9.3.1 Linux
-----------
There are many Linux distributions, and historically, many of them had
their own way of starting programs at boot time. Today, a number of
major Linux distributions have chosen to use systemd as their init
system. Tinc ships with systemd service files that allow you to start
and stop tinc using systemd. There are two service files:
'tinc.service' is used to globally enable or disable all tinc daemons
managed by systemd, and 'tinc@NETNAME.service' is used to enable or
disable specific tinc daemons. So if one has created a tinc network
with netname 'foo', then you have to run the following two commands to
ensure it is started at boot time:
systemctl enable tinc
systemctl enable tinc@foo
To start the tinc daemon immediately if it wasn't already running, use
the following command:
systemctl start tinc@foo
You can also use 'systemctl start tinc', this will start all tinc
daemons that are enabled. You can stop and disable tinc networks in the
same way.
If your system is not using systemd, then you have to look up your
distribution's way of starting tinc at boot time.

File: tinc.info, Node: Windows, Next: Other platforms, Prev: Linux, Up: Automatically starting tinc
9.3.2 Windows
-------------
On Windows, if tinc is started with the 'tinc start' command without
using the '-D' or '--no-detach' option, it will automatically register
itself as a service that is started at boot time. When tinc is stopped
using the 'tinc stop' command, it will also automatically unregister
itself. Once tinc is registered as a service, it is also possible to
stop and start tinc using the Windows Services Manager.

File: tinc.info, Node: Other platforms, Prev: Windows, Up: Automatically starting tinc
9.3.3 Other platforms
---------------------
On platforms other than the ones mentioned in the earlier sections, you
have to look up your platform's way of starting programs at boot time.
 
File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top File: tinc.info, Node: About us, Next: Concept Index, Prev: Platform specific information, Up: Top
@ -3354,6 +3427,8 @@ Concept Index
* ANS_KEY: The meta-protocol. (line 63) * ANS_KEY: The meta-protocol. (line 63)
* AutoConnect: Main configuration variables. * AutoConnect: Main configuration variables.
(line 12) (line 12)
* batch: tinc runtime options.
(line 18)
* binary package: Building and installing tinc. * binary package: Building and installing tinc.
(line 9) (line 9)
* BindToAddress: Main configuration variables. * BindToAddress: Main configuration variables.
@ -3376,7 +3451,7 @@ Concept Index
* ClampMSS: Host configuration variables. * ClampMSS: Host configuration variables.
(line 22) (line 22)
* client: How connections work. * client: How connections work.
(line 18) (line 12)
* command line: Runtime options. (line 9) * command line: Runtime options. (line 9)
* command line interface: Controlling tinc. (line 6) * command line interface: Controlling tinc. (line 6)
* Compression: Host configuration variables. * Compression: Host configuration variables.
@ -3422,7 +3497,7 @@ Concept Index
* exchange: tinc commands. (line 48) * exchange: tinc commands. (line 48)
* exchange-all: tinc commands. (line 51) * exchange-all: tinc commands. (line 51)
* exec: Main configuration variables. * exec: Main configuration variables.
(line 365) (line 373)
* ExperimentalProtocol: Main configuration variables. * ExperimentalProtocol: Main configuration variables.
(line 185) (line 185)
* export: tinc commands. (line 36) * export: tinc commands. (line 36)
@ -3433,38 +3508,40 @@ Concept Index
(line 192) (line 192)
* frame type: The UDP tunnel. (line 6) * frame type: The UDP tunnel. (line 6)
* fsck: tinc commands. (line 160) * fsck: tinc commands. (line 160)
* FWMark: Main configuration variables.
(line 214)
* generate-ed25519-keys: tinc commands. (line 86) * generate-ed25519-keys: tinc commands. (line 86)
* generate-keys: tinc commands. (line 81) * generate-keys: tinc commands. (line 81)
* generate-rsa-keys: tinc commands. (line 89) * generate-rsa-keys: tinc commands. (line 89)
* get: tinc commands. (line 11) * get: tinc commands. (line 11)
* graph: tinc commands. (line 108) * graph: tinc commands. (line 108)
* Hostnames: Main configuration variables. * Hostnames: Main configuration variables.
(line 212) (line 220)
* http: Main configuration variables. * http: Main configuration variables.
(line 362) (line 370)
* hub: Main configuration variables. * hub: Main configuration variables.
(line 280) (line 288)
* ID: Legacy authentication protocol. * ID: Legacy authentication protocol.
(line 6) (line 6)
* Ifconfig: Invitation file format. * Ifconfig: Invitation file format.
(line 35) (line 36)
* import: tinc commands. (line 43) * import: tinc commands. (line 43)
* IndirectData: Host configuration variables. * IndirectData: Host configuration variables.
(line 40) (line 40)
* info: tinc commands. (line 120) * info: tinc commands. (line 120)
* init: tinc commands. (line 6) * init: tinc commands. (line 6)
* Interface: Main configuration variables. * Interface: Main configuration variables.
(line 223) (line 231)
* INTERFACE: Scripts. (line 75) * INTERFACE: Scripts. (line 75)
* InvitationExpire: Main configuration variables. * InvitationExpire: Main configuration variables.
(line 285) (line 293)
* INVITATION_FILE: Scripts. (line 98) * INVITATION_FILE: Scripts. (line 98)
* INVITATION_URL: Scripts. (line 102) * INVITATION_URL: Scripts. (line 102)
* invite: tinc commands. (line 54) * invite: tinc commands. (line 54)
* IRC: Contact information. (line 9) * IRC: Contact information. (line 9)
* join: tinc commands. (line 59) * join: tinc commands. (line 59)
* KeyExpire: Main configuration variables. * KeyExpire: Main configuration variables.
(line 288) (line 296)
* KEY_CHANGED: The meta-protocol. (line 63) * KEY_CHANGED: The meta-protocol. (line 63)
* legacy authentication protocol: Legacy authentication protocol. * legacy authentication protocol: Legacy authentication protocol.
(line 6) (line 6)
@ -3474,31 +3551,31 @@ Concept Index
* LibreSSL: LibreSSL/OpenSSL. (line 6) * LibreSSL: LibreSSL/OpenSSL. (line 6)
* license: LibreSSL/OpenSSL. (line 38) * license: LibreSSL/OpenSSL. (line 38)
* ListenAddress: Main configuration variables. * ListenAddress: Main configuration variables.
(line 231) (line 239)
* LocalDiscovery: Main configuration variables. * LocalDiscovery: Main configuration variables.
(line 243) (line 251)
* log: tinc commands. (line 130) * log: tinc commands. (line 130)
* LogLevel: Main configuration variables. * LogLevel: Main configuration variables.
(line 254) (line 262)
* lzo: lzo. (line 6) * LZO: LZO. (line 6)
* MACExpire: Main configuration variables. * MACExpire: Main configuration variables.
(line 294) (line 302)
* MACLength: Host configuration variables. * MACLength: Host configuration variables.
(line 45) (line 45)
* MaxConnectionBurst: Main configuration variables. * MaxConnectionBurst: Main configuration variables.
(line 299) (line 307)
* meta-protocol: The meta-connection. (line 18) * meta-protocol: The meta-connection. (line 18)
* META_KEY: Legacy authentication protocol. * META_KEY: Legacy authentication protocol.
(line 6) (line 6)
* Mode: Main configuration variables. * Mode: Main configuration variables.
(line 258) (line 266)
* MTUInfoInterval: Host configuration variables. * MTUInfoInterval: Host configuration variables.
(line 60) (line 60)
* multicast: Main configuration variables. * multicast: Main configuration variables.
(line 118) (line 118)
* multiple networks: Multiple networks. (line 6) * multiple networks: Multiple networks. (line 6)
* Name: Main configuration variables. * Name: Main configuration variables.
(line 305) (line 313)
* NAME: Scripts. (line 69) * NAME: Scripts. (line 69)
* netmask: Network interfaces. (line 39) * netmask: Network interfaces. (line 39)
* netname: Multiple networks. (line 6) * netname: Multiple networks. (line 6)
@ -3517,9 +3594,9 @@ Concept Index
* pid: tinc commands. (line 78) * pid: tinc commands. (line 78)
* PING: The meta-protocol. (line 88) * PING: The meta-protocol. (line 88)
* PingInterval: Main configuration variables. * PingInterval: Main configuration variables.
(line 316) (line 324)
* PingTimeout: Main configuration variables. * PingTimeout: Main configuration variables.
(line 320) (line 328)
* platforms: Supported platforms. (line 6) * platforms: Supported platforms. (line 6)
* PMTU: Host configuration variables. * PMTU: Host configuration variables.
(line 52) (line 52)
@ -3530,17 +3607,17 @@ Concept Index
(line 65) (line 65)
* port numbers: Other files. (line 17) * port numbers: Other files. (line 17)
* PriorityInheritance: Main configuration variables. * PriorityInheritance: Main configuration variables.
(line 326) (line 334)
* private: Virtual Private Networks. * private: Virtual Private Networks.
(line 10) (line 10)
* PrivateKey: Main configuration variables. * PrivateKey: Main configuration variables.
(line 331) (line 339)
* PrivateKeyFile: Main configuration variables. * PrivateKeyFile: Main configuration variables.
(line 337) (line 345)
* ProcessPriority: Main configuration variables. * ProcessPriority: Main configuration variables.
(line 342) (line 350)
* Proxy: Main configuration variables. * Proxy: Main configuration variables.
(line 347) (line 355)
* PublicKey: Host configuration variables. * PublicKey: Host configuration variables.
(line 69) (line 69)
* PublicKeyFile: Host configuration variables. * PublicKeyFile: Host configuration variables.
@ -3553,40 +3630,41 @@ Concept Index
* REMOTEADDRESS: Scripts. (line 84) * REMOTEADDRESS: Scripts. (line 84)
* REMOTEPORT: Scripts. (line 87) * REMOTEPORT: Scripts. (line 87)
* ReplayWindow: Main configuration variables. * ReplayWindow: Main configuration variables.
(line 370) (line 378)
* requirements: Libraries. (line 6) * requirements: Libraries. (line 6)
* REQ_KEY: The meta-protocol. (line 63) * REQ_KEY: The meta-protocol. (line 63)
* restart: tinc commands. (line 70) * restart: tinc commands. (line 70)
* retry: tinc commands. (line 135) * retry: tinc commands. (line 135)
* Route: Invitation file format. * Route: Invitation file format.
(line 51) (line 52)
* router: Main configuration variables. * router: Main configuration variables.
(line 261) (line 269)
* runtime options: Runtime options. (line 9) * runtime options: Runtime options. (line 9)
* scalability: tinc. (line 19) * scalability: tinc. (line 19)
* scripts: Scripts. (line 6) * scripts: Scripts. (line 6)
* server: How connections work. * server: How connections work.
(line 18) (line 12)
* set: tinc commands. (line 16) * set: tinc commands. (line 16)
* shell: Controlling tinc. (line 11) * shell: Controlling tinc. (line 11)
* sign: tinc commands. (line 172) * sign: tinc commands. (line 172)
* signals: Signals. (line 6) * signals: Signals. (line 6)
* socks4: Main configuration variables. * socks4: Main configuration variables.
(line 351) (line 359)
* socks5: Main configuration variables. * socks5: Main configuration variables.
(line 356) (line 364)
* SPTPS: Simple Peer-to-Peer Security. * SPTPS: Simple Peer-to-Peer Security.
(line 6) (line 6)
* start: tinc commands. (line 64) * start: tinc commands. (line 64)
* stop: tinc commands. (line 67) * stop: tinc commands. (line 67)
* StrictSubnets: Main configuration variables. * StrictSubnets: Main configuration variables.
(line 381) (line 389)
* Subnet: Host configuration variables. * Subnet: Host configuration variables.
(line 84) (line 84)
* SUBNET: Scripts. (line 91) * SUBNET: Scripts. (line 91)
* SVPN: Security. (line 11) * SVPN: Security. (line 11)
* switch: Main configuration variables. * switch: Main configuration variables.
(line 269) (line 277)
* systemd: Linux. (line 6)
* TCP: The meta-connection. (line 10) * TCP: The meta-connection. (line 10)
* TCPonly: Host configuration variables. * TCPonly: Host configuration variables.
(line 113) (line 113)
@ -3602,36 +3680,36 @@ Concept Index
* tunifhead: Main configuration variables. * tunifhead: Main configuration variables.
(line 158) (line 158)
* TunnelServer: Main configuration variables. * TunnelServer: Main configuration variables.
(line 388) (line 396)
* tunnohead: Main configuration variables. * tunnohead: Main configuration variables.
(line 152) (line 152)
* UDP: The UDP tunnel. (line 30) * UDP: The UDP tunnel. (line 30)
* UDP <1>: Encryption of network packets. * UDP <1>: Encryption of network packets.
(line 11) (line 11)
* UDPDiscoveryInterval: Main configuration variables. * UDPDiscoveryInterval: Main configuration variables.
(line 408) (line 416)
* UDPDiscoveryKeepaliveInterval: Main configuration variables. * UDPDiscoveryKeepaliveInterval: Main configuration variables.
(line 402) (line 410)
* UDPDiscoveryTimeout: Main configuration variables. * UDPDiscoveryTimeout: Main configuration variables.
(line 412) (line 420)
* UDPDiscovey: Main configuration variables. * UDPDiscovey: Main configuration variables.
(line 395) (line 403)
* UDPInfoInterval: Main configuration variables. * UDPInfoInterval: Main configuration variables.
(line 417) (line 425)
* UDPRcvBuf: Main configuration variables. * UDPRcvBuf: Main configuration variables.
(line 421) (line 429)
* UDPSndBuf: Main configuration variables. * UDPSndBuf: Main configuration variables.
(line 427) (line 435)
* UML: Main configuration variables. * UML: Main configuration variables.
(line 134) (line 134)
* Universal tun/tap: Configuration of Linux kernels. * Universal tun/tap: Configuration of Linux kernels.
(line 6) (line 6)
* UPnP: Main configuration variables. * UPnP: Main configuration variables.
(line 433) (line 441)
* UPnPDiscoverWait: Main configuration variables. * UPnPDiscoverWait: Main configuration variables.
(line 444) (line 452)
* UPnPRefreshPeriod: Main configuration variables. * UPnPRefreshPeriod: Main configuration variables.
(line 448) (line 456)
* utun: Main configuration variables. * utun: Main configuration variables.
(line 165) (line 165)
* VDE: Main configuration variables. * VDE: Main configuration variables.
@ -3652,78 +3730,82 @@ Concept Index
 
Tag Table: Tag Table:
Node: Top824 Node: Top808
Node: Introduction1160 Node: Introduction1144
Node: Virtual Private Networks1964 Node: Virtual Private Networks1948
Node: tinc3676 Node: tinc3660
Node: Supported platforms5188 Node: Supported platforms5173
Node: Preparations5885 Node: Preparations5870
Node: Configuring the kernel6141 Node: Configuring the kernel6126
Node: Configuration of Linux kernels6550 Node: Configuration of Linux kernels6535
Node: Configuration of FreeBSD kernels7399 Node: Configuration of FreeBSD kernels7384
Node: Configuration of OpenBSD kernels7864 Node: Configuration of OpenBSD kernels7849
Node: Configuration of NetBSD kernels8221 Node: Configuration of NetBSD kernels8206
Node: Configuration of Solaris kernels8623 Node: Configuration of Solaris kernels8608
Node: Configuration of Darwin (MacOS/X) kernels9285 Node: Configuration of Darwin (MacOS/X) kernels9270
Node: Configuration of Windows10098 Node: Configuration of Windows10083
Node: Libraries10637 Node: Libraries10622
Node: LibreSSL/OpenSSL11094 Node: LibreSSL/OpenSSL11079
Node: zlib13620 Node: zlib13607
Node: lzo14642 Node: LZO14627
Node: libcurses15633 Node: libcurses15619
Node: libreadline16543 Node: libreadline16531
Node: Installation17480 Node: Installation17470
Node: Building and installing tinc18384 Node: Building and installing tinc18374
Node: Darwin (MacOS/X) build environment19040 Node: Darwin (MacOS/X) build environment19030
Node: Cygwin (Windows) build environment19599 Node: Cygwin (Windows) build environment19589
Node: MinGW (Windows) build environment20184 Node: MinGW (Windows) build environment20174
Node: System files20772 Node: System files20762
Node: Device files21037 Node: Device files21027
Node: Other files21450 Node: Other files21440
Node: Configuration22063 Node: Configuration22053
Node: Configuration introduction22350 Node: Configuration introduction22340
Node: Multiple networks23871 Node: Multiple networks23862
Node: How connections work25238 Node: How connections work25230
Node: Configuration files27799 Node: Configuration files27494
Node: Main configuration variables29431 Node: Main configuration variables29125
Node: Host configuration variables50412 Node: Host configuration variables50523
Node: Scripts56482 Node: Scripts56595
Node: How to configure60382 Node: How to configure60495
Node: Network interfaces64866 Node: Network interfaces64406
Node: Example configuration67245 Node: Example configuration66785
Node: Running tinc72344 Node: Running tinc71726
Node: Runtime options72931 Node: Runtime options72313
Node: Signals75791 Node: Signals75581
Node: Debug levels76640 Node: Debug levels76430
Node: Solving problems77576 Node: Solving problems77366
Node: Error messages79002 Node: Error messages78792
Node: Sending bug reports83319 Node: Sending bug reports83109
Node: Controlling tinc84266 Node: Controlling tinc84056
Node: tinc runtime options85002 Node: tinc runtime options84792
Node: tinc environment variables85751 Node: tinc environment variables85608
Node: tinc commands86080 Node: tinc commands85937
Node: tinc examples92938 Node: tinc examples92796
Node: tinc top93500 Node: tinc top93356
Node: Invitations95085 Node: Invitations94940
Node: How invitations work95748 Node: How invitations work95603
Node: Invitation file format98041 Node: Invitation file format97896
Node: Writing an invitation-created script100966 Node: Writing an invitation-created script100907
Node: Technical information102028 Node: Technical information101970
Node: The connection102258 Node: The connection102200
Node: The UDP tunnel102570 Node: The UDP tunnel102512
Node: The meta-connection105615 Node: The meta-connection105548
Node: The meta-protocol107073 Node: The meta-protocol107006
Node: Security112056 Node: Security111989
Node: Legacy authentication protocol113393 Node: Legacy authentication protocol113326
Node: Simple Peer-to-Peer Security118010 Node: Simple Peer-to-Peer Security117943
Node: Encryption of network packets123655 Node: Encryption of network packets123588
Node: Security issues126293 Node: Security issues126226
Node: Platform specific information128040 Node: Platform specific information128818
Node: Interface configuration128268 Node: Interface configuration129078
Node: Routes130709 Node: Routes131348
Node: About us132620 Node: Automatically starting tinc133295
Node: Contact information132797 Node: Linux133518
Node: Authors133200 Node: Windows134730
Node: Concept Index133604 Node: Other platforms135274
Node: About us135556
Node: Contact information135733
Node: Authors136136
Node: Concept Index136540
 
End Tag Table End Tag Table

View file

@ -15,7 +15,7 @@
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
Copyright @copyright{} 1998-2017 Ivo Timmermans, Copyright @copyright{} 1998-2018 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>. Wessel Dankers <wsl@@tinc-vpn.org>.
@ -43,7 +43,7 @@ permission notice identical to this one.
@vskip 0pt plus 1filll @vskip 0pt plus 1filll
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon. This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
Copyright @copyright{} 1998-2017 Ivo Timmermans, Copyright @copyright{} 1998-2018 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>. Wessel Dankers <wsl@@tinc-vpn.org>.
@ -161,7 +161,7 @@ professional package.
@cindex traditional VPNs @cindex traditional VPNs
@cindex scalability @cindex scalability
Tinc also allows more than two sites to connect to eachother and form a single VPN. Tinc also allows more than two sites to connect to each other and form a single VPN.
Traditionally VPNs are created by making tunnels, which only have two endpoints. Traditionally VPNs are created by making tunnels, which only have two endpoints.
Larger VPNs with more sites are created by adding more tunnels. Larger VPNs with more sites are created by adding more tunnels.
Tinc takes another approach: only endpoints are specified, Tinc takes another approach: only endpoints are specified,
@ -331,14 +331,14 @@ as explained in the rest of the documentation.
@cindex requirements @cindex requirements
@cindex libraries @cindex libraries
Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib, Before you can configure or build tinc, you need to have the LibreSSL or OpenSSL, zlib,
lzo, curses and readline libraries installed on your system. If you try to LZO, curses and readline libraries installed on your system. If you try to
configure tinc without having them installed, configure will give you an error configure tinc without having them installed, configure will give you an error
message, and stop. message, and stop.
@menu @menu
* LibreSSL/OpenSSL:: * LibreSSL/OpenSSL::
* zlib:: * zlib::
* lzo:: * LZO::
* libcurses:: * libcurses::
* libreadline:: * libreadline::
@end menu @end menu
@ -353,7 +353,7 @@ message, and stop.
For all cryptography-related functions, tinc uses the functions provided For all cryptography-related functions, tinc uses the functions provided
by the LibreSSL or the OpenSSL library. by the LibreSSL or the OpenSSL library.
If this library is not installed, you wil get an error when configuring If this library is not installed, you will get an error when configuring
tinc for build. Support for running tinc with other cryptographic libraries tinc for build. Support for running tinc with other cryptographic libraries
installed @emph{may} be added in the future. installed @emph{may} be added in the future.
@ -363,7 +363,7 @@ of this package.
If your operating system comes neither with LibreSSL or OpenSSL, you have to If your operating system comes neither with LibreSSL or OpenSSL, you have to
install one manually. It is recommended that you get the latest version of install one manually. It is recommended that you get the latest version of
LibreSSL from @url{http://www.libressl.org/}. Instructions on how to LibreSSL from @url{https://www.libressl.org/}. Instructions on how to
configure, build and install this package are included within the package. configure, build and install this package are included within the package.
Please make sure you build development and runtime libraries (which is the Please make sure you build development and runtime libraries (which is the
default). default).
@ -419,7 +419,7 @@ Markus F.X.J. Oberhumer
For the optional compression of UDP packets, tinc uses the functions provided For the optional compression of UDP packets, tinc uses the functions provided
by the zlib library. by the zlib library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install the zlib library, or disable support configure script. You can either install the zlib library, or disable support
for zlib compression by using the "--disable-zlib" option when running the for zlib compression by using the "--disable-zlib" option when running the
configure script. Note that if you disable support for zlib, the resulting configure script. Note that if you disable support for zlib, the resulting
@ -430,20 +430,20 @@ available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install zlib manually, you can get the source code If you have to install zlib manually, you can get the source code
from @url{http://www.zlib.net/}. Instructions on how to configure, from @url{https://zlib.net/}. Instructions on how to configure,
build and install this package are included within the package. Please build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the make sure you build development and runtime libraries (which is the
default). default).
@c ================================================================== @c ==================================================================
@node lzo @node LZO
@subsection lzo @subsection LZO
@cindex lzo @cindex LZO
Another form of compression is offered using the LZO library. Another form of compression is offered using the LZO library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install the LZO library, or disable support configure script. You can either install the LZO library, or disable support
for LZO compression by using the "--disable-lzo" option when running the for LZO compression by using the "--disable-lzo" option when running the
configure script. Note that if you disable support for LZO, the resulting configure script. Note that if you disable support for LZO, the resulting
@ -453,7 +453,7 @@ You can use your operating system's package manager to install this if
available. Make sure you install the development AND runtime versions available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install lzo manually, you can get the source code If you have to install LZO manually, you can get the source code
from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure, from @url{https://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure,
build and install this package are included within the package. Please build and install this package are included within the package. Please
make sure you build development and runtime libraries (which is the make sure you build development and runtime libraries (which is the
@ -467,15 +467,15 @@ default).
@cindex libcurses @cindex libcurses
For the "tinc top" command, tinc requires a curses library. For the "tinc top" command, tinc requires a curses library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install a suitable curses library, or disable configure script. You can either install a suitable curses library, or disable
all functionality that depends on a curses library by using the all functionality that depends on a curses library by using the
"--disable-curses" option when running the configure script. "--disable-curses" option when running the configure script.
There are several curses libraries. It is recommended that you install There are several curses libraries. It is recommended that you install
"ncurses" (@url{http://invisible-island.net/ncurses/}), "ncurses" (@url{https://invisible-island.net/ncurses/}),
however other curses libraries should also work. however other curses libraries should also work.
In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/}) In particular, "PDCurses" (@url{https://pdcurses.sourceforge.io/})
is recommended if you want to compile tinc for Windows. is recommended if you want to compile tinc for Windows.
You can use your operating system's package manager to install this if You can use your operating system's package manager to install this if
@ -490,7 +490,7 @@ of this package.
@cindex libreadline @cindex libreadline
For the "tinc" command's shell functionality, tinc uses the readline library. For the "tinc" command's shell functionality, tinc uses the readline library.
If this library is not installed, you wil get an error when running the If this library is not installed, you will get an error when running the
configure script. You can either install a suitable readline library, or configure script. You can either install a suitable readline library, or
disable all functionality that depends on a readline library by using the disable all functionality that depends on a readline library by using the
"--disable-readline" option when running the configure script. "--disable-readline" option when running the configure script.
@ -500,7 +500,7 @@ available. Make sure you install the development AND runtime versions
of this package. of this package.
If you have to install libreadline manually, you can get the source code from If you have to install libreadline manually, you can get the source code from
@url{http://www.gnu.org/software/readline/}. Instructions on how to configure, @url{https://www.gnu.org/software/readline/}. Instructions on how to configure,
build and install this package are included within the package. Please make build and install this package are included within the package. Please make
sure you build development and runtime libraries (which is the default). sure you build development and runtime libraries (which is the default).
@ -691,7 +691,7 @@ you will not find the answers in this documentation.
Make sure you have an adequate understanding of networks in general. Make sure you have an adequate understanding of networks in general.
@cindex Network Administrators Guide @cindex Network Administrators Guide
A good resource on networking is the A good resource on networking is the
@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}. @uref{https://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}.
If you have everything clearly pictured in your mind, If you have everything clearly pictured in your mind,
proceed in the following order: proceed in the following order:
@ -721,7 +721,7 @@ It is not required if you only run one tinc daemon,
it doesn't even have to be the same on all the nodes of your VPN, it doesn't even have to be the same on all the nodes of your VPN,
but it is recommended that you choose one anyway. but it is recommended that you choose one anyway.
We will asume you use a netname throughout this document. We will assume you use a netname throughout this document.
This means that you call tinc with the -n argument, This means that you call tinc with the -n argument,
which will specify the netname. which will specify the netname.
@ -744,22 +744,15 @@ and the host configuration files are expected to be in @file{@value{sysconfdir}/
When tinc starts up, it parses the command-line options and then When tinc starts up, it parses the command-line options and then
reads in the configuration file tinc.conf. reads in the configuration file tinc.conf.
If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file, It will then start listening for incoming connection from other daemons,
it will try to connect to those other daemons. and will by default also automatically try to connect to known peers.
Whether this succeeds or not and whether `ConnectTo' is specified or not, By default, tinc will try to keep at least 3 working meta-connections alive at all times.
tinc will listen for incoming connection from other deamons.
If you did specify a `ConnectTo' value and the other side is not responding,
tinc will keep retrying.
This means that once started, tinc will stay running until you tell it to stop,
and failures to connect to other tinc daemons will not stop your tinc daemon
for trying again later.
This means you don't have to intervene if there are temporary network problems.
@cindex client @cindex client
@cindex server @cindex server
There is no real distinction between a server and a client in tinc. There is no real distinction between a server and a client in tinc.
If you wish, you can view a tinc daemon without a `ConnectTo' value as a server, If you wish, you can view a tinc daemon without a `ConnectTo' statement in tinc.conf and `AutoConnect = no' as a server,
and one which does specify such a value as a client. and one which does have one or more `ConnectTo' statements or `Autoconnect = yes' (which is the default) as a client.
It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however. It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however.
Connections specified using `ConnectTo' are so-called meta-connections. Connections specified using `ConnectTo' are so-called meta-connections.
@ -778,7 +771,7 @@ It is not always possible to do this however, and firewalls might also prevent d
In that case, VPN packets between A and C will be forwarded by B. In that case, VPN packets between A and C will be forwarded by B.
In effect, all nodes in the VPN will be able to talk to each other, as long as In effect, all nodes in the VPN will be able to talk to each other, as long as
their is a path of meta-connections between them, and whenever possible, two there is a path of meta-connections between them, and whenever possible, two
nodes will communicate with each other directly. nodes will communicate with each other directly.
@ -790,7 +783,7 @@ The actual configuration of the daemon is done in the file
@file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory @file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/}. @file{@value{sysconfdir}/tinc/@var{netname}/hosts/}.
An optionnal directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which An optional directory @file{@value{sysconfdir}/tinc/@var{netname}/conf.d} can be added from which
any .conf file will be read. any .conf file will be read.
These file consists of comments (lines started with a #) or assignments These file consists of comments (lines started with a #) or assignments
@ -839,7 +832,7 @@ If any is selected, then depending on the operating system
both IPv4 and IPv6 or just IPv6 listening sockets will be created. both IPv4 and IPv6 or just IPv6 listening sockets will be created.
@cindex AutoConnect @cindex AutoConnect
@item AutoConnect = <yes|no> (no) [experimental] @item AutoConnect = <yes|no> (yes)
If set to yes, tinc will automatically set up meta connections to other nodes, If set to yes, tinc will automatically set up meta connections to other nodes,
without requiring @var{ConnectTo} variables. without requiring @var{ConnectTo} variables.
@ -900,7 +893,7 @@ in which case outgoing connections to each specified tinc daemon are made.
The names should be known to this tinc daemon The names should be known to this tinc daemon
(i.e., there should be a host configuration file for the name on the ConnectTo line). (i.e., there should be a host configuration file for the name on the ConnectTo line).
If you don't specify a host with ConnectTo and don't enable AutoConnect, If you don't specify a host with ConnectTo and have disabled AutoConnect,
tinc won't try to connect to other daemons at all, tinc won't try to connect to other daemons at all,
and will instead just listen for incoming connections. and will instead just listen for incoming connections.
@ -967,7 +960,7 @@ Packets received for the local node are written to it.
@cindex UML @cindex UML
@item uml (not compiled in by default) @item uml (not compiled in by default)
Create a UNIX socket with the filename specified by Create a UNIX socket with the filename specified by
@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket} @var{Device}, or @file{@value{runstatedir}/@var{netname}.umlsocket}
if not specified. if not specified.
Tinc will wait for a User Mode Linux instance to connect to this socket. Tinc will wait for a User Mode Linux instance to connect to this socket.
@ -975,7 +968,7 @@ Tinc will wait for a User Mode Linux instance to connect to this socket.
@item vde (not compiled in by default) @item vde (not compiled in by default)
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch, Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
using the UNIX socket specified by using the UNIX socket specified by
@var{Device}, or @file{@value{localstatedir}/run/vde.ctl} @var{Device}, or @file{@value{runstatedir}/vde.ctl}
if not specified. if not specified.
@end table @end table
@ -1048,16 +1041,24 @@ Incoming packets that are meant for another node are forwarded by tinc internall
This is the default mode, and unless you really know you need another forwarding mode, don't change it. This is the default mode, and unless you really know you need another forwarding mode, don't change it.
@item kernel @item kernel
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node. Incoming packets using the legacy protocol are always sent to the TUN/TAP device,
even if the packets are not for the local node.
This is less efficient, but allows the kernel to apply its routing and firewall rules on them, This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
and can also help debugging. and can also help debugging.
Incoming packets using the SPTPS protocol are dropped, since they are end-to-end encrypted.
@end table @end table
@cindex FWMark
@item FWMark = <@var{value}> (0) [experimental]
When set to a non-zero value, all TCP and UDP sockets created by tinc will use the given value as the firewall mark.
This can be used for mark-based routing or for packet filtering.
This option is currently only supported on Linux.
@cindex Hostnames @cindex Hostnames
@item Hostnames = <yes|no> (no) @item Hostnames = <yes|no> (no)
This option selects whether IP addresses (both real and on the VPN) This option selects whether IP addresses (both real and on the VPN)
should be resolved. Since DNS lookups are blocking, it might affect should be resolved. Since DNS lookups are blocking, it might affect
tinc's efficiency, even stopping the daemon for a few seconds everytime tinc's efficiency, even stopping the daemon for a few seconds every time
it does a lookup if your DNS server is not responding. it does a lookup if your DNS server is not responding.
This does not affect resolving hostnames to IP addresses from the This does not affect resolving hostnames to IP addresses from the
@ -1179,7 +1180,7 @@ will be inherited by the UDP packets that are sent out.
@item PrivateKey = <@var{key}> [obsolete] @item PrivateKey = <@var{key}> [obsolete]
This is the RSA private key for tinc. However, for safety reasons it is This is the RSA private key for tinc. However, for safety reasons it is
advised to store private keys of any kind in separate files. This prevents advised to store private keys of any kind in separate files. This prevents
accidental eavesdropping if you are editting the configuration file. accidental eavesdropping if you are editing the configuration file.
@cindex PrivateKeyFile @cindex PrivateKeyFile
@item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv}) @item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
@ -1335,7 +1336,7 @@ Fragmentation Needed or Packet too Big messages are dropped by firewalls.
@item Compression = <@var{level}> (0) @item Compression = <@var{level}> (0)
This option sets the level of compression used for UDP packets. This option sets the level of compression used for UDP packets.
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
10 (fast lzo) and 11 (best lzo). 10 (fast LZO) and 11 (best LZO).
@cindex Digest @cindex Digest
@item Digest = <@var{digest}> (sha1) @item Digest = <@var{digest}> (sha1)
@ -1396,7 +1397,7 @@ connection with that host.
@cindex Subnet @cindex Subnet
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]> @item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
The subnet which this tinc daemon will serve. The subnet which this tinc daemon will serve.
Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet. Tinc tries to look up which other daemon it should send a packet to by searching the appropriate subnet.
If the packet matches a subnet, If the packet matches a subnet,
it will be sent to the daemon who has this subnet in his host configuration file. it will be sent to the daemon who has this subnet in his host configuration file.
Multiple subnet lines can be specified for each daemon. Multiple subnet lines can be specified for each daemon.
@ -1626,23 +1627,11 @@ For example, if your hostname is foo.example.org, run:
tinc -n @var{netname} add address foo.example.org tinc -n @var{netname} add address foo.example.org
@end example @end example
If you already know to which daemons your daemon should make meta-connections,
you should configure that now as well.
Suppose you want to connect to a daemon named "bar", run:
@example
tinc -n @var{netname} add connectto bar
@end example
Note that you specify the Name of the other daemon here, not an IP address or hostname!
When you start tinc, and it tries to make a connection to "bar",
it will look for a host configuration file named @file{hosts/bar},
and will read Address statements and public keys from that file.
@subsubheading Step 2. Exchanging configuration files. @subsubheading Step 2. Exchanging configuration files.
If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file, In order for two tinc daemons to be able to connect to each other,
or if bar has a ConnectTo your daemon, then you both need each other's host configuration files. they each need the other's host configuration files.
So if you want foo to be able to connect with bar,
You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}. You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}.
If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command
(assuming the owner of bar has the email address bar@@example.org): (assuming the owner of bar has the email address bar@@example.org):
@ -1668,10 +1657,9 @@ tinc -n @var{netname} export \
| tinc -n @var{netname} import | tinc -n @var{netname} import
@end example @end example
You should repeat this for all nodes you ConnectTo, or which ConnectTo you. You can repeat this for a few other nodes as well.
However, remember that you do not need to ConnectTo all nodes in the VPN; It is not necessary to manually exchange host config files between all nodes;
it is only necessary to create one or a few meta-connections, after the initial connections are made tinc will learn about all the other nodes in the VPN,
after the connections are made tinc will learn about all the other nodes in the VPN,
and will automatically make other connections as necessary. and will automatically make other connections as necessary.
@ -1817,12 +1805,10 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example @example
Name = BranchB Name = BranchB
ConnectTo = BranchA
@end example @end example
Note here that the internal address (on eth0) doesn't have to be the Note here that the internal address (on eth0) doesn't have to be the
same as on the VPN interface. Also, ConnectTo is given so that this node will same as on the VPN interface.
always try to connect to BranchA.
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}: On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}:
@ -1853,7 +1839,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example @example
Name = BranchC Name = BranchC
ConnectTo = BranchA
@end example @end example
C already has another daemon that runs on port 655, so they have to C already has another daemon that runs on port 655, so they have to
@ -1890,7 +1875,6 @@ and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
@example @example
Name = BranchD Name = BranchD
ConnectTo = BranchC
@end example @end example
D will be connecting to C, which has a tincd running for this network on D will be connecting to C, which has a tincd running for this network on
@ -1983,7 +1967,7 @@ Specifying . for @var{netname} is the same as not specifying any @var{netname}.
@item --pidfile=@var{filename} @item --pidfile=@var{filename}
Store a cookie in @var{filename} which allows tinc to authenticate. Store a cookie in @var{filename} which allows tinc to authenticate.
If unspecified, the default is If unspecified, the default is
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. @file{@value{runstatedir}/tinc.@var{netname}.pid}.
@item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE} @item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE}
Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}. Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}.
@ -2001,6 +1985,9 @@ This option is not supported on all platforms.
Write log entries to a file instead of to the system logging facility. Write log entries to a file instead of to the system logging facility.
If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}. If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}.
@item --pidfile=@var{file}
Write PID to @var{file} instead of @file{@value{runstatedir}/tinc.@var{netname}.pid}.
@item --bypass-security @item --bypass-security
Disables encryption and authentication. Disables encryption and authentication.
Only useful for debugging. Only useful for debugging.
@ -2012,10 +1999,14 @@ located (@file{@value{sysconfdir}/tinc/@var{netname}/} as determined by
The chroot is performed after all the initialization is done, after The chroot is performed after all the initialization is done, after
writing pid files and opening network sockets. writing pid files and opening network sockets.
Note that this option alone does not do any good without -U/--user, below. This option is best used in combination with the -U/--user option described below.
Note also that tinc can't run scripts anymore (such as tinc-down or host-up), You will need to ensure the chroot environment contains all the files necessary
unless it's setup to be runnable inside chroot environment. for tinc to run correctly.
Most importantly, for tinc to be able to resolve hostnames inside the chroot environment,
you must copy @file{/etc/resolv.conf} into the chroot directory.
If you want to be able to run scripts other than @file{tinc-up} in the chroot,
you must ensure the appropriate shell is also installed in the chroot, along with all its dependencies.
This option is not supported on all platforms. This option is not supported on all platforms.
@item -U, --user=@var{user} @item -U, --user=@var{user}
@ -2295,7 +2286,11 @@ Use configuration for net @var{netname}. @xref{Multiple networks}.
@item --pidfile=@var{filename} @item --pidfile=@var{filename}
Use the cookie from @var{filename} to authenticate with a running tinc daemon. Use the cookie from @var{filename} to authenticate with a running tinc daemon.
If unspecified, the default is If unspecified, the default is
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}. @file{@value{runstatedir}/tinc.@var{netname}.pid}.
@cindex batch
@item -b, --batch
Don't ask for anything (non-interactive mode).
@item --force @item --force
Force some commands to work despite warnings. Force some commands to work despite warnings.
@ -2523,7 +2518,7 @@ The @var{name} of the node must be given,
or can be "." to check against the local node's public key, or can be "." to check against the local node's public key,
or "*" to allow a signature from any node whose public key is known. or "*" to allow a signature from any node whose public key is known.
If no @var{filename} is given, the file is read from standard input. If no @var{filename} is given, the file is read from standard input.
If the verification is succesful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero. If the verification is successful, a copy of the input with the signature removed is written to standard output, and the exit code will be zero.
If the verification failed, nothing will be written to standard output, and the exit code will be non-zero. If the verification failed, nothing will be written to standard output, and the exit code will be non-zero.
@end table @end table
@ -2546,7 +2541,7 @@ Examples of changing the configuration using tinc:
tinc -n vpn init foo tinc -n vpn init foo
tinc -n vpn add Subnet 192.168.1.0/24 tinc -n vpn add Subnet 192.168.1.0/24
tinc -n vpn add bar.Address bar.example.com tinc -n vpn add bar.Address bar.example.com
tinc -n vpn add ConnectTo bar tinc -n vpn set Mode switch
tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com
@end example @end example
@ -2571,7 +2566,7 @@ Intervals lower than 0.1 seconds are not allowed.
@item c @item c
Toggle between displaying current traffic rates (in packets and bytes per second) Toggle between displaying current traffic rates (in packets and bytes per second)
and cummulative traffic (total packets and bytes since the tinc daemon started). and cumulative traffic (total packets and bytes since the tinc daemon started).
@item n @item n
Sort the list of nodes by name. Sort the list of nodes by name.
@ -2696,6 +2691,8 @@ Address = server.example.com
The file is basically a concatenation of several host config blocks. Each host The file is basically a concatenation of several host config blocks. Each host
config block starts with @code{Name = ...}. Lines that look like @code{#---#} config block starts with @code{Name = ...}. Lines that look like @code{#---#}
are not important, it just makes it easier for humans to read the file. are not important, it just makes it easier for humans to read the file.
However, the first line of an invitation file @emph{must} always start with
@code{Name = ...}.
The first host config block is always the one representing the invitee. So the The first host config block is always the one representing the invitee. So the
first Name statement determines the name that the invitee will get. From the first Name statement determines the name that the invitee will get. From the
@ -2744,7 +2741,7 @@ When an invitation is generated, the "invitation-created" script is called (if
it exists) right after the invitation file is written, but before the URL has it exists) right after the invitation file is written, but before the URL has
been written to stdout. This allows one to change the invitation file been written to stdout. This allows one to change the invitation file
automatically before the invitation URL is passed to the invitee. Here is an automatically before the invitation URL is passed to the invitee. Here is an
example shell script that aproximately recreates the default invitation file: example shell script that approximately recreates the default invitation file:
@example @example
#!/bin/sh #!/bin/sh
@ -2846,7 +2843,7 @@ In switch or hub modes ARP does work so the sender already knows the correct des
In those modes every interface should have a unique MAC address, so make sure they are not the same. In those modes every interface should have a unique MAC address, so make sure they are not the same.
Because switch and hub modes rely on MAC addresses to function correctly, Because switch and hub modes rely on MAC addresses to function correctly,
these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device: these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device:
OpenBSD, NetBSD, Darwin and Solaris. NetBSD, Darwin and Solaris.
@c ================================================================== @c ==================================================================
@ -3378,13 +3375,27 @@ that tinc's default length of 4 bytes for the MAC is too short, and he doesn't
like tinc's use of RSA during authentication. We do not know of a security hole like tinc's use of RSA during authentication. We do not know of a security hole
in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. in the legacy protocol of tinc, but it is not as strong as TLS or IPsec.
This version of tinc comes with an improved protocol, called Simple Peer-to-Peer Security, The Sweet32 attack affects versions of tinc prior to 1.0.30.
which aims to be as strong as TLS with one of the strongest cipher suites.
On September 6th, 2018, Michael Yonly contacted us and provided
proof-of-concept code that allowed a remote attacker to create an
authenticated, one-way connection with a node, and also that there was a
possibility for a man-in-the-middle to force UDP packets from a node to be sent
in plaintext. The first issue was trivial to exploit on tinc versions prior to
1.0.30, but the changes in 1.0.30 to mitigate the Sweet32 attack made this
weakness much harder to exploit. These issues have been fixed in tinc 1.0.35.
This version of tinc comes with an improved protocol, called Simple
Peer-to-Peer Security (SPTPS), which aims to be as strong as TLS with one of
the strongest cipher suites. None of the above security issues affected SPTPS.
However, be aware that SPTPS is only used between nodes running tinc 1.1pre* or
later, and in a VPN with nodes running different versions, the security might
only be as good as that of the oldest version.
Cryptography is a hard thing to get right. We cannot make any Cryptography is a hard thing to get right. We cannot make any
guarantees. Time, review and feedback are the only things that can guarantees. Time, review and feedback are the only things that can
prove the security of any cryptographic product. If you wish to review prove the security of any cryptographic product. If you wish to review
tinc or give us feedback, you are stronly encouraged to do so. tinc or give us feedback, you are strongly encouraged to do so.
@c ================================================================== @c ==================================================================
@ -3394,6 +3405,7 @@ tinc or give us feedback, you are stronly encouraged to do so.
@menu @menu
* Interface configuration:: * Interface configuration::
* Routes:: * Routes::
* Automatically starting tinc::
@end menu @end menu
@c ================================================================== @c ==================================================================
@ -3450,13 +3462,6 @@ For IPv6 addresses:
@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength} @tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
@end multitable @end multitable
On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command:
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
@item OpenBSD
@tab @code{ifconfig} @var{interface} @code{link0}
@end multitable
On Linux, it is possible to create a persistent tun/tap interface which will On Linux, it is possible to create a persistent tun/tap interface which will
continue to exist even if tinc quit, although this is normally not required. continue to exist even if tinc quit, although this is normally not required.
It can be useful to set up a tun/tap interface owned by a non-root user, so It can be useful to set up a tun/tap interface owned by a non-root user, so
@ -3520,6 +3525,67 @@ Adding routes to IPv6 subnets:
@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface} @tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
@end multitable @end multitable
@c ==================================================================
@node Automatically starting tinc
@section Automatically starting tinc
@menu
* Linux::
* Windows::
* Other platforms::
@end menu
@c ==================================================================
@node Linux
@subsection Linux
@cindex systemd
There are many Linux distributions, and historically, many of them had their
own way of starting programs at boot time. Today, a number of major Linux
distributions have chosen to use systemd as their init system. Tinc ships with
systemd service files that allow you to start and stop tinc using systemd.
There are two service files: @code{tinc.service} is used to globally enable or
disable all tinc daemons managed by systemd, and
@code{tinc@@@var{netname}.service} is used to enable or disable specific tinc
daemons. So if one has created a tinc network with netname @code{foo}, then
you have to run the following two commands to ensure it is started at boot
time:
@example
systemctl enable tinc
systemctl enable tinc@@foo
@end example
To start the tinc daemon immediately if it wasn't already running, use the
following command:
@example
systemctl start tinc@@foo
@end example
You can also use @samp{systemctl start tinc}, this will start all tinc daemons
that are enabled. You can stop and disable tinc networks in the same way.
If your system is not using systemd, then you have to look up your
distribution's way of starting tinc at boot time.
@c ==================================================================
@node Windows
@subsection Windows
On Windows, if tinc is started with the @code{tinc start} command without using
the @code{-D} or @code{--no-detach} option, it will automatically register
itself as a service that is started at boot time. When tinc is stopped using
the @code{tinc stop} command, it will also automatically unregister itself.
Once tinc is registered as a service, it is also possible to stop and start
tinc using the Windows Services Manager.
@c ==================================================================
@node Other platforms
@subsection Other platforms
On platforms other than the ones mentioned in the earlier sections, you have to
look up your platform's way of starting programs at boot time.
@c ================================================================== @c ==================================================================
@node About us @node About us

View file

@ -100,7 +100,7 @@ to authenticate.
If If
.Ar FILE .Ar FILE
is omitted, the default is is omitted, the default is
.Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid. .Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid.
.It Fl -bypass-security .It Fl -bypass-security
Disables encryption and authentication of the meta protocol. Disables encryption and authentication of the meta protocol.
Only useful for debugging. Only useful for debugging.
@ -173,7 +173,7 @@ This will log all network traffic over the virtual private network.
Directory containing the configuration files tinc uses. Directory containing the configuration files tinc uses.
For more information, see For more information, see
.Xr tinc.conf 5 . .Xr tinc.conf 5 .
.It Pa @localstatedir@/run/tinc. Ns Ar NETNAME Ns Pa .pid .It Pa @runstatedir@/tinc. Ns Ar NETNAME Ns Pa .pid
The PID of the currently running The PID of the currently running
.Nm .Nm
is stored in this file. is stored in this file.

5
doc/tincinclude.texi Normal file
View file

@ -0,0 +1,5 @@
@set VERSION 1.1pre17
@set PACKAGE tinc
@set sysconfdir /etc
@set localstatedir /var
@set runstatedir /var/run

View file

@ -2,3 +2,4 @@
@set PACKAGE @PACKAGE@ @set PACKAGE @PACKAGE@
@set sysconfdir @sysconfdir@ @set sysconfdir @sysconfdir@
@set localstatedir @localstatedir@ @set localstatedir @localstatedir@
@set runstatedir @runstatedir@

View file

@ -1,3 +0,0 @@
dist_bin_SCRIPTS = tinc-gui
extra_DIST = README.gui

View file

@ -1,507 +0,0 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = gui
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
$(top_srcdir)/m4/openssl.m4 $(top_srcdir)/m4/readline.m4 \
$(top_srcdir)/m4/zlib.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(bindir)"
SCRIPTS = $(dist_bin_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
systemd_path = @systemd_path@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
dist_bin_SCRIPTS = tinc-gui
extra_DIST = README.gui
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu gui/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu gui/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
@$(NORMAL_INSTALL)
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n' \
-e 'h;s|.*|.|' \
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
if (++n[d] == $(am__install_max)) { \
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
else { print "f", d "/" $$4, $$1 } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-dist_binSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 's,.*/,,;$(transform)'`; \
dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
installcheck-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
bad=0; pid=$$$$; list="$(dist_bin_SCRIPTS)"; for p in $$list; do \
case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
*" $$p "* | *" $(srcdir)/$$p "*) continue;; \
esac; \
f=`echo "$$p" | sed 's,^.*/,,;$(transform)'`; \
for opt in --help --version; do \
if "$(DESTDIR)$(bindir)/$$f" $$opt >c$${pid}_.out \
2>c$${pid}_.err </dev/null \
&& test -n "`cat c$${pid}_.out`" \
&& test -z "`cat c$${pid}_.err`"; then :; \
else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
done; \
done; rm -f c$${pid}_.???; exit $$bad
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(SCRIPTS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-dist_binSCRIPTS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am: installcheck-dist_binSCRIPTS
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-dist_binSCRIPTS
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
ctags-am distclean distclean-generic distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dist_binSCRIPTS install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am \
installcheck-dist_binSCRIPTS installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am tags-am uninstall uninstall-am \
uninstall-dist_binSCRIPTS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View file

@ -1,634 +0,0 @@
#!/usr/bin/env python2
# tinc-gui -- GUI for controlling a running tincd
# Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
# 2014 Dennis Joachimsthaler <dennis@efjot.de>
#
# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import string
import socket
import os
import platform
import time
from argparse import ArgumentParser
import wx
from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
if platform.system() == 'Windows':
import _winreg
# Classes to interface with a running tinc daemon
REQ_STOP = 0
REQ_RELOAD = 1
REQ_RESTART = 2
REQ_DUMP_NODES = 3
REQ_DUMP_EDGES = 4
REQ_DUMP_SUBNETS = 5
REQ_DUMP_CONNECTIONS = 6
REQ_DUMP_GRAPH = 7
REQ_PURGE = 8
REQ_SET_DEBUG = 9
REQ_RETRY = 10
REQ_CONNECT = 11
REQ_DISCONNECT = 12
ID = 0
ACK = 4
CONTROL = 18
class Node(object):
def __init__(self, args):
self.name = args[0]
self.id = args[1]
self.address = args[2]
self.port = args[4]
self.cipher = int(args[5])
self.digest = int(args[6])
self.maclength = int(args[7])
self.compression = int(args[8])
self.options = int(args[9], 0x10)
self.status = int(args[10], 0x10)
self.nexthop = args[11]
self.via = args[12]
self.distance = int(args[13])
self.pmtu = int(args[14])
self.minmtu = int(args[15])
self.maxmtu = int(args[16])
self.last_state_change = float(args[17])
self.subnets = {}
class Edge(object):
def __init__(self, args):
self.source = args[0]
self.sink = args[1]
self.address = args[2]
self.port = args[4]
self.options = int(args[-2], 16)
self.weight = int(args[-1])
class Subnet(object):
def __init__(self, args):
if args[0].find('#') >= 0:
address, self.weight = args[0].split('#', 1)
else:
self.weight = 10
address = args[0]
if address.find('/') >= 0:
self.address, self.prefixlen = address.split('/', 1)
else:
self.address = address
self.prefixlen = '48'
self.owner = args[1]
class Connection(object):
def __init__(self, args):
self.name = args[0]
self.address = args[1]
self.port = args[3]
self.options = int(args[4], 0x10)
self.socket = int(args[5])
self.status = int(args[6], 0x10)
self.weight = 'n/a'
class VPN(object):
def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'):
if platform.system() == 'Windows':
sam = _winreg.KEY_READ
if platform.machine().endswith('64'):
sam = sam | _winreg.KEY_WOW64_64KEY
try:
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
try:
key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
except WindowsError:
key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
confdir = _winreg.QueryValue(key, None)
except WindowsError:
pass
if netname:
self.netname = netname
self.confbase = os.path.join(confdir, netname)
else:
self.confbase = confdir
self.tincconf = os.path.join(self.confbase, 'tinc.conf')
if pidfile is not None:
self.pidfile = pidfile
else:
if platform.system() == 'Windows':
self.pidfile = os.path.join(self.confbase, 'pid')
else:
if netname:
self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid')
else:
self.pidfile = os.path.join(piddir, 'tinc.pid')
self.sf = None
self.name = None
self.port = None
self.nodes = {}
self.edges = {}
self.subnets = {}
self.connections = {}
def connect(self):
# read the pidfile
f = open(self.pidfile)
info = string.split(f.readline())
f.close()
# check if there is a UNIX socket as well
if self.pidfile.endswith('.pid'):
unixfile = self.pidfile.replace('.pid', '.socket');
else:
unixfile = self.pidfile + '.socket';
if os.path.exists(unixfile):
# use it if it exists
print(unixfile + " exists!");
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(unixfile)
else:
# otherwise connect via TCP
print(unixfile + " does not exist.");
if ':' in info[2]:
af = socket.AF_INET6
else:
af = socket.AF_INET
s = socket.socket(af, socket.SOCK_STREAM)
s.connect((info[2], int(info[4])))
self.sf = s.makefile()
s.close()
hello = string.split(self.sf.readline())
self.name = hello[1]
self.sf.write('0 ^' + info[1] + ' 17\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
self.port = info[4]
self.refresh()
def refresh(self):
for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS):
self.sf.write('{} {}\r\n'.format(CONTROL, request))
self.sf.flush()
for node in self.nodes.values():
node.visited = False
for edge in self.edges.values():
edge.visited = False
for subnet in self.subnets.values():
subnet.visited = False
for connections in self.connections.values():
connections.visited = False
while True:
resp = string.split(self.sf.readline())
if len(resp) < 2:
break
if resp[0] != '18':
break
if resp[1] == '3':
if len(resp) < 19:
continue
node = self.nodes.get(resp[2]) or Node(resp[2:])
node.visited = True
self.nodes[resp[2]] = node
elif resp[1] == '4':
if len(resp) < 9:
continue
edge = self.nodes.get((resp[2], resp[3])) or Edge(resp[2:])
edge.visited = True
self.edges[(resp[2], resp[3])] = edge
elif resp[1] == '5':
if len(resp) < 4:
continue
subnet = self.subnets.get((resp[2], resp[3])) or Subnet(resp[2:])
subnet.visited = True
self.subnets[(resp[2], resp[3])] = subnet
if subnet.owner == "(broadcast)":
continue
self.nodes[subnet.owner].subnets[resp[2]] = subnet
elif resp[1] == '6':
if len(resp) < 9:
break
connection = self.connections.get((resp[2], resp[3], resp[5])) or Connection(resp[2:])
connection.visited = True
self.connections[(resp[2], resp[3], resp[5])] = connection
else:
break
for key, subnet in self.subnets.items():
if not subnet.visited:
del self.subnets[key]
for key, edge in self.edges.items():
if not edge.visited:
del self.edges[key]
for key, node in self.nodes.items():
if not node.visited:
del self.nodes[key]
else:
for key, subnet in node.subnets.items():
if not subnet.visited:
del node.subnets[key]
for key, connection in self.connections.items():
if not connection.visited:
del self.connections[key]
def close(self):
self.sf.close()
def disconnect(self, name):
self.sf.write('18 12 ' + name + '\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
def debug(self, level=-1):
self.sf.write('18 9 ' + str(level) + '\r\n')
self.sf.flush()
resp = string.split(self.sf.readline())
return int(resp[2])
class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
ListCtrlAutoWidthMixin.__init__(self)
ColumnSorterMixin.__init__(self, 16)
def GetListCtrl(self):
return self
class SettingsPage(wx.Panel):
def on_debug_level(self, event):
vpn.debug(self.debug.GetValue())
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
grid = wx.FlexGridSizer(cols=2)
grid.AddGrowableCol(1, 1)
namelabel = wx.StaticText(self, -1, 'Name:')
self.name = wx.TextCtrl(self, -1, vpn.name)
grid.Add(namelabel)
grid.Add(self.name, 1, wx.EXPAND)
portlabel = wx.StaticText(self, -1, 'Port:')
self.port = wx.TextCtrl(self, -1, vpn.port)
grid.Add(portlabel)
grid.Add(self.port)
debuglabel = wx.StaticText(self, -1, 'Debug level:')
self.debug = wx.SpinCtrl(self, min=0, max=5, initial=vpn.debug())
self.debug.Bind(wx.EVT_SPINCTRL, self.on_debug_level)
grid.Add(debuglabel)
grid.Add(self.debug)
modelabel = wx.StaticText(self, -1, 'Mode:')
self.mode = wx.ComboBox(self, -1, style=wx.CB_READONLY, value='Router', choices=['Router', 'Switch', 'Hub'])
grid.Add(modelabel)
grid.Add(self.mode)
self.SetSizer(grid)
class ConnectionsPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Name')
self.list.InsertColumn(1, 'Address')
self.list.InsertColumn(2, 'Port')
self.list.InsertColumn(3, 'Options')
self.list.InsertColumn(4, 'Weight')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
class ContextMenu(wx.Menu):
def __init__(self, item):
wx.Menu.__init__(self)
self.item = item
disconnect = wx.MenuItem(self, -1, 'Disconnect')
self.AppendItem(disconnect)
self.Bind(wx.EVT_MENU, self.on_disconnect, id=disconnect.GetId())
def on_disconnect(self, event):
vpn.disconnect(self.item[0])
def on_context(self, event):
idx = event.GetIndex()
self.PopupMenu(self.ContextMenu(self.list.itemDataMap[event.GetIndex()]), event.GetPosition())
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, connection in vpn.connections.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, connection.name)
else:
self.list.SetStringItem(i, 0, connection.name)
self.list.SetStringItem(i, 1, connection.address)
self.list.SetStringItem(i, 2, connection.port)
self.list.SetStringItem(i, 3, str(connection.options))
self.list.SetStringItem(i, 4, str(connection.weight))
self.list.itemDataMap[i] = (connection.name, connection.address, connection.port, connection.options,
connection.weight)
self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_context)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class NodesPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Name')
self.list.InsertColumn(1, 'Address')
self.list.InsertColumn(2, 'Port')
self.list.InsertColumn(3, 'Cipher')
self.list.InsertColumn(4, 'Digest')
self.list.InsertColumn(5, 'MACLength')
self.list.InsertColumn(6, 'Compression')
self.list.InsertColumn(7, 'Options')
self.list.InsertColumn(8, 'Status')
self.list.InsertColumn(9, 'Nexthop')
self.list.InsertColumn(10, 'Via')
self.list.InsertColumn(11, 'Distance')
self.list.InsertColumn(12, 'PMTU')
self.list.InsertColumn(13, 'Min MTU')
self.list.InsertColumn(14, 'Max MTU')
self.list.InsertColumn(15, 'Since')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, node in vpn.nodes.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, node.name)
else:
self.list.SetStringItem(i, 0, node.name)
self.list.SetStringItem(i, 1, node.address)
self.list.SetStringItem(i, 2, node.port)
self.list.SetStringItem(i, 3, str(node.cipher))
self.list.SetStringItem(i, 4, str(node.digest))
self.list.SetStringItem(i, 5, str(node.maclength))
self.list.SetStringItem(i, 6, str(node.compression))
self.list.SetStringItem(i, 7, format(node.options, "x"))
self.list.SetStringItem(i, 8, format(node.status, "04x"))
self.list.SetStringItem(i, 9, node.nexthop)
self.list.SetStringItem(i, 10, node.via)
self.list.SetStringItem(i, 11, str(node.distance))
self.list.SetStringItem(i, 12, str(node.pmtu))
self.list.SetStringItem(i, 13, str(node.minmtu))
self.list.SetStringItem(i, 14, str(node.maxmtu))
if node.last_state_change:
since = time.strftime("%Y-%m-%d %H:%M", time.localtime(node.last_state_change))
else:
since = "never"
self.list.SetStringItem(i, 15, since)
self.list.itemDataMap[i] = (node.name, node.address, node.port, node.cipher, node.digest, node.maclength,
node.compression, node.options, node.status, node.nexthop, node.via,
node.distance, node.pmtu, node.minmtu, node.maxmtu, since)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class EdgesPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'From')
self.list.InsertColumn(1, 'To')
self.list.InsertColumn(2, 'Address')
self.list.InsertColumn(3, 'Port')
self.list.InsertColumn(4, 'Options')
self.list.InsertColumn(5, 'Weight')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, edge in vpn.edges.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, edge.source)
else:
self.list.SetStringItem(i, 0, edge.source)
self.list.SetStringItem(i, 1, edge.sink)
self.list.SetStringItem(i, 2, edge.address)
self.list.SetStringItem(i, 3, edge.port)
self.list.SetStringItem(i, 4, format(edge.options, "x"))
self.list.SetStringItem(i, 5, str(edge.weight))
self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class SubnetsPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.list = SuperListCtrl(self, id)
self.list.InsertColumn(0, 'Subnet', wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(1, 'Weight', wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(2, 'Owner')
hbox = wx.BoxSizer(wx.HORIZONTAL)
hbox.Add(self.list, 1, wx.EXPAND)
self.SetSizer(hbox)
self.refresh()
def refresh(self):
sortstate = self.list.GetSortState()
self.list.itemDataMap = {}
i = 0
for key, subnet in vpn.subnets.items():
if self.list.GetItemCount() <= i:
self.list.InsertStringItem(i, subnet.address + '/' + subnet.prefixlen)
else:
self.list.SetStringItem(i, 0, subnet.address + '/' + subnet.prefixlen)
self.list.SetStringItem(i, 1, str(subnet.weight))
self.list.SetStringItem(i, 2, subnet.owner)
self.list.itemDataMap[i] = (subnet.address + '/' + subnet.prefixlen, subnet.weight, subnet.owner)
self.list.SetItemData(i, i)
i += 1
while self.list.GetItemCount() > i:
self.list.DeleteItem(self.list.GetItemCount() - 1)
self.list.SortListItems(sortstate[0], sortstate[1])
class StatusPage(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
class GraphPage(wx.Window):
def __init__(self, parent, id):
wx.Window.__init__(self, parent, id)
class NetPage(wx.Notebook):
def __init__(self, parent, id):
wx.Notebook.__init__(self, parent)
self.settings = SettingsPage(self, id)
self.connections = ConnectionsPage(self, id)
self.nodes = NodesPage(self, id)
self.edges = EdgesPage(self, id)
self.subnets = SubnetsPage(self, id)
self.graph = GraphPage(self, id)
self.status = StatusPage(self, id)
self.AddPage(self.settings, 'Settings')
# self.AddPage(self.status, 'Status')
self.AddPage(self.connections, 'Connections')
self.AddPage(self.nodes, 'Nodes')
self.AddPage(self.edges, 'Edges')
self.AddPage(self.subnets, 'Subnets')
# self.AddPage(self.graph, 'Graph')
class MainWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
menubar = wx.MenuBar()
menu = wx.Menu()
menu.Append(1, '&Quit\tCtrl-X', 'Quit tinc GUI')
menubar.Append(menu, '&File')
# nb = wx.Notebook(self, -1)
# nb.SetPadding((0, 0))
self.np = NetPage(self, -1)
# nb.AddPage(np, 'VPN')
self.timer = wx.Timer(self, -1)
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.timer.Start(1000)
self.Bind(wx.EVT_MENU, self.on_quit, id=1)
self.SetMenuBar(menubar)
self.Show()
def on_quit(self, event):
app.ExitMainLoop()
def on_timer(self, event):
vpn.refresh()
self.np.nodes.refresh()
self.np.subnets.refresh()
self.np.edges.refresh()
self.np.connections.refresh()
def main(netname, pidfile):
global vpn, app
if netname is None:
netname = os.getenv('NETNAME')
vpn = VPN(netname, pidfile)
vpn.connect()
app = wx.App()
mw = MainWindow(None, -1, 'Tinc GUI')
"""
def OnTaskBarIcon(event):
mw.Raise()
"""
"""
icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
taskbaricon = wx.TaskBarIcon()
taskbaricon.SetIcon(icon, 'Tinc GUI')
wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
"""
app.MainLoop()
vpn.close()
if __name__ == '__main__':
argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.')
argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME')
argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)')
options = argparser.parse_args()
main(options.netname, options.pidfile)

View file

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# install - install a program, script, or datafile # install - install a program, script, or datafile
scriptversion=2014-09-12.12; # UTC scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the # later released in X11R6 (xc/config/util/install.sh) with the
@ -271,15 +271,18 @@ do
fi fi
dst=$dst_arg dst=$dst_arg
# If destination is a directory, append the input filename; won't work # If destination is a directory, append the input filename.
# if double slashes aren't ignored.
if test -d "$dst"; then if test -d "$dst"; then
if test "$is_target_a_directory" = never; then if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2 echo "$0: $dst_arg: Is a directory" >&2
exit 1 exit 1
fi fi
dstdir=$dst dstdir=$dst
dst=$dstdir/`basename "$src"` dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0 dstdir_status=0
else else
dstdir=`dirname "$dst"` dstdir=`dirname "$dst"`
@ -288,6 +291,11 @@ do
fi fi
fi fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false obsolete_mkdir_used=false
if test $dstdir_status != 0; then if test $dstdir_status != 0; then
@ -324,14 +332,16 @@ do
# is incompatible with FreeBSD 'install' when (umask & 300) != 0. # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;; ;;
*) *)
# $RANDOM is not portable (e.g. dash); use it when possible to # Note that $RANDOM variable is not portable (e.g. dash); Use it
# lower collision chance # here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# As "mkdir -p" follows symlinks and we work in /tmp possibly; so # Because "mkdir -p" follows existing symlinks and we likely work
# create the $tmpdir first (and fail if unsuccessful) to make sure # directly in world-writeable /tmp, make sure that the '$tmpdir'
# that nobody tries to guess the $tmpdir name. # directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask && if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" && $mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
@ -434,8 +444,8 @@ do
else else
# Make a couple of temp file names in the proper directory. # Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_ dsttmp=${dstdirslash}_inst.$$_
rmtmp=$dstdir/_rm.$$_ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit. # Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
@ -500,9 +510,9 @@ do
done done
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC" # time-stamp-end: "; # UTC"
# End: # End:

264
m4/ax_code_coverage.m4 Normal file
View file

@ -0,0 +1,264 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CODE_COVERAGE()
#
# DESCRIPTION
#
# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included
# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every
# build target (program or library) which should be built with code
# coverage support. Also defines CODE_COVERAGE_RULES which should be
# substituted in your Makefile; and $enable_code_coverage which can be
# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
# and substituted, and corresponds to the value of the
# --enable-code-coverage option, which defaults to being disabled.
#
# Test also for gcov program and create GCOV variable that could be
# substituted.
#
# Note that all optimisation flags in CFLAGS must be disabled when code
# coverage is enabled.
#
# Usage example:
#
# configure.ac:
#
# AX_CODE_COVERAGE
#
# Makefile.am:
#
# @CODE_COVERAGE_RULES@
# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ...
# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
#
# This results in a "check-code-coverage" rule being added to any
# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
# has been configured with --enable-code-coverage). Running `make
# check-code-coverage` in that directory will run the module's test suite
# (`make check`) and build a code coverage report detailing the code which
# was touched, then print the URI for the report.
#
# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined
# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of
# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is
# deprecated. They have the same value.
#
# This code was derived from Makefile.decl in GLib, originally licenced
# under LGPLv2.1+.
#
# LICENSE
#
# Copyright (c) 2012, 2016 Philip Withnall
# Copyright (c) 2012 Xan Lopez
# Copyright (c) 2012 Christian Persch
# Copyright (c) 2012 Paolo Borelli
# Copyright (c) 2012 Dan Winship
# Copyright (c) 2015 Bastien ROUCARIES
#
# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#serial 21
AC_DEFUN([AX_CODE_COVERAGE],[
dnl Check for --enable-code-coverage
AC_REQUIRE([AC_PROG_SED])
# allow to override gcov location
AC_ARG_WITH([gcov],
[AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
[_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
[_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
AC_MSG_CHECKING([whether to build with code coverage support])
AC_ARG_ENABLE([code-coverage],
AS_HELP_STRING([--enable-code-coverage],
[Whether to enable code coverage support]),,
enable_code_coverage=no)
AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
AC_MSG_RESULT($enable_code_coverage)
AS_IF([ test "$enable_code_coverage" = "yes" ], [
# check for gcov
AC_CHECK_TOOL([GCOV],
[$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
[:])
AS_IF([test "X$GCOV" = "X:"],
[AC_MSG_ERROR([gcov is needed to do coverage])])
AC_SUBST([GCOV])
dnl Check if gcc is being used
AS_IF([ test "$GCC" = "no" ], [
AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
])
AC_CHECK_PROG([LCOV], [lcov], [lcov])
AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
AS_IF([ test -z "$LCOV" ], [
AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed])
])
AS_IF([ test -z "$GENHTML" ], [
AC_MSG_ERROR([Could not find genhtml from the lcov package])
])
dnl Build the code coverage flags
dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility
CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
CODE_COVERAGE_LIBS="-lgcov"
CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS"
AC_SUBST([CODE_COVERAGE_CPPFLAGS])
AC_SUBST([CODE_COVERAGE_CFLAGS])
AC_SUBST([CODE_COVERAGE_CXXFLAGS])
AC_SUBST([CODE_COVERAGE_LIBS])
AC_SUBST([CODE_COVERAGE_LDFLAGS])
[CODE_COVERAGE_RULES_CHECK='
-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
']
[CODE_COVERAGE_RULES_CAPTURE='
$(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
$(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
$(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
']
[CODE_COVERAGE_RULES_CLEAN='
clean: code-coverage-clean
distclean: code-coverage-clean
code-coverage-clean:
-$(LCOV) --directory $(top_builddir) -z
-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
']
], [
[CODE_COVERAGE_RULES_CHECK='
@echo "Need to reconfigure with --enable-code-coverage"
']
CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK"
CODE_COVERAGE_RULES_CLEAN=''
])
[CODE_COVERAGE_RULES='
# Code coverage
#
# Optional:
# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
# Multiple directories may be specified, separated by whitespace.
# (Default: $(top_builddir))
# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
# by lcov for code coverage. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
# reports to be created. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
# set to 0 to disable it and leave empty to stay with the default.
# (Default: empty)
# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
# lcov instance. (Default: empty)
# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
#
# The generated report will be titled using the $(PACKAGE_NAME) and
# $(PACKAGE_VERSION). In order to add the current git hash to the title,
# use the git-version-gen script, available online.
# Optional variables
CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
CODE_COVERAGE_BRANCH_COVERAGE ?=
CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
CODE_COVERAGE_IGNORE_PATTERN ?=
code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\
$(CODE_COVERAGE_OUTPUT_FILE);
code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\
$(CODE_COVERAGE_IGNORE_PATTERN);
code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
code_coverage_quiet = $(code_coverage_quiet_$(V))
code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
code_coverage_quiet_0 = --quiet
# sanitizes the test-name: replaces with underscores: dashes and dots
code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
# Use recursive makes in order to ignore errors during check
check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"'
# Capture code coverage data
code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"'
# Hook rule executed before code-coverage-capture, overridable by the user
code-coverage-capture-hook:
'"$CODE_COVERAGE_RULES_CLEAN"'
GITIGNOREFILES ?=
GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
A''M_DISTCHECK_CONFIGURE_FLAGS ?=
A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
']
AC_SUBST([CODE_COVERAGE_RULES])
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
])

View file

@ -32,7 +32,7 @@ AC_DEFUN([tinc_CURSES],
) )
AC_CHECK_LIB(ncurses, initscr, AC_CHECK_LIB(ncurses, initscr,
[CURSES_LIBS="-lncurses"], [CURSES_LIBS="-lncurses"; AC_CHECK_LIB(tinfo, wtimeout, [CURSES_LIBS+=" -ltinfo"], [])],
[AC_CHECK_LIB(curses, initscr, [AC_CHECK_LIB(curses, initscr,
[CURSES_LIBS="-lcurses"], [CURSES_LIBS="-lcurses"],
[AC_MSG_ERROR("curses libraries not found.")] [AC_MSG_ERROR("curses libraries not found.")]

View file

@ -49,10 +49,11 @@ AC_DEFUN([tinc_OPENSSL],
[AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break],
) )
AC_CHECK_DECLS([OpenSSL_add_all_algorithms EVP_aes_256_cfb], , AC_CHECK_DECLS([OpenSSL_add_all_algorithms, EVP_aes_256_cfb], ,
[AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break], [AC_MSG_ERROR([Missing LibreSSL/OpenSSL functionality, make sure you have installed the latest version.]); break],
[#include <openssl/evp.h>] [#include <openssl/evp.h>]
) )
AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include <openssl/rsa.h>]) AC_CHECK_FUNCS([BN_GENCB_new ERR_remove_state RSA_set0_key], , , [#include <openssl/rsa.h>])
AC_CHECK_FUNCS([HMAC_CTX_new], , , [#include <openssl/hmac.h>])
]) ])

16
missing
View file

@ -1,9 +1,9 @@
#! /bin/sh #! /bin/sh
# Common wrapper for a few potentially missing GNU programs. # Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc. # Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@ -101,9 +101,9 @@ else
exit $st exit $st
fi fi
perl_URL=http://www.perl.org/ perl_URL=https://www.perl.org/
flex_URL=http://flex.sourceforge.net/ flex_URL=https://github.com/westes/flex
gnu_software_URL=http://www.gnu.org/software gnu_software_URL=https://www.gnu.org/software
program_details () program_details ()
{ {
@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \
exit $st exit $st
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC" # time-stamp-end: "; # UTC"
# End: # End:

View file

@ -42,6 +42,7 @@ chacha_poly1305_SOURCES = \
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
tincd_SOURCES = \ tincd_SOURCES = \
address_cache.c address_cache.h \
autoconnect.c autoconnect.h \ autoconnect.c autoconnect.h \
buffer.c buffer.h \ buffer.c buffer.h \
cipher.h \ cipher.h \
@ -278,10 +279,11 @@ endif
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt sptps_speed_LDADD = -lrt
LIBS = @LIBS@ -lm LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS)
if TUNEMU if TUNEMU
LIBS += -lpcap LIBS += -lpcap
endif endif
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS)
AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS)

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@ -202,6 +202,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \ $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_check_link_flag.m4 \ $(top_srcdir)/m4/ax_check_link_flag.m4 \
$(top_srcdir)/m4/ax_code_coverage.m4 \
$(top_srcdir)/m4/ax_require_defined.m4 \ $(top_srcdir)/m4/ax_require_defined.m4 \
$(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \ $(top_srcdir)/m4/curses.m4 $(top_srcdir)/m4/libgcrypt.m4 \
$(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \ $(top_srcdir)/m4/lzo.m4 $(top_srcdir)/m4/miniupnpc.m4 \
@ -336,22 +337,23 @@ am_tinc_OBJECTS = dropin.$(OBJEXT) fsck.$(OBJEXT) ifconfig.$(OBJEXT) \
tinc_OBJECTS = $(am_tinc_OBJECTS) tinc_OBJECTS = $(am_tinc_OBJECTS)
am__DEPENDENCIES_1 = am__DEPENDENCIES_1 =
tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \ am__tincd_SOURCES_DIST = address_cache.c address_cache.h autoconnect.c \
cipher.h conf.c conf.h connection.c connection.h control.c \ autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \
control.h control_common.h crypto.h device.h digest.h dropin.c \ connection.c connection.h control.c control.h control_common.h \
dropin.h dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c \ crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \
edge.h ethernet.h event.c event.h fd_device.c graph.c graph.h \ ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \
hash.c hash.h have.h ipv4.h ipv6.h list.c list.h logger.c \ event.h fd_device.c graph.c graph.h hash.c hash.h have.h \
logger.h meta.c meta.h multicast_device.c names.c names.h \ ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \
net.c net.h net_packet.c net_setup.c net_socket.c netutl.c \ multicast_device.c names.c names.h net.c net.h net_packet.c \
netutl.h node.c node.h prf.h process.c process.h protocol.c \ net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
protocol.h protocol_auth.c protocol_edge.c protocol_key.c \ process.c process.h protocol.c protocol.h protocol_auth.c \
protocol_misc.c protocol_subnet.c raw_socket_device.c route.c \ protocol_edge.c protocol_key.c protocol_misc.c \
route.h rsa.h rsagen.h script.c script.h splay_tree.c \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
splay_tree.h sptps.c sptps.h subnet.c subnet.h subnet_parse.c \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
system.h tincd.c utils.c utils.h xalloc.h version.c version.h \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
ed25519/ecdh.c ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c \ utils.c utils.h xalloc.h version.c version.h ed25519/ecdh.c \
ed25519/fe.h ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \ ed25519/ecdsa.c ed25519/ed25519.h ed25519/fe.c ed25519/fe.h \
ed25519/fixedint.h ed25519/ge.c ed25519/ge.h \
ed25519/key_exchange.c ed25519/keypair.c \ ed25519/key_exchange.c ed25519/keypair.c \
ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \ ed25519/precomp_data.h ed25519/sc.c ed25519/sc.h \
ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \ ed25519/sha512.c ed25519/sha512.h ed25519/sign.c \
@ -384,15 +386,15 @@ am__tincd_SOURCES_DIST = autoconnect.c autoconnect.h buffer.c buffer.h \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \ @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/prf.$(OBJEXT) \
@GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT) @GCRYPT_TRUE@@OPENSSL_FALSE@ gcrypt/rsa.$(OBJEXT)
@MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT) @MINIUPNPC_TRUE@am__objects_23 = upnp.$(OBJEXT)
am_tincd_OBJECTS = autoconnect.$(OBJEXT) buffer.$(OBJEXT) \ am_tincd_OBJECTS = address_cache.$(OBJEXT) autoconnect.$(OBJEXT) \
conf.$(OBJEXT) connection.$(OBJEXT) control.$(OBJEXT) \ buffer.$(OBJEXT) conf.$(OBJEXT) connection.$(OBJEXT) \
dropin.$(OBJEXT) dummy_device.$(OBJEXT) edge.$(OBJEXT) \ control.$(OBJEXT) dropin.$(OBJEXT) dummy_device.$(OBJEXT) \
event.$(OBJEXT) fd_device.$(OBJEXT) graph.$(OBJEXT) \ edge.$(OBJEXT) event.$(OBJEXT) fd_device.$(OBJEXT) \
hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) meta.$(OBJEXT) \ graph.$(OBJEXT) hash.$(OBJEXT) list.$(OBJEXT) logger.$(OBJEXT) \
multicast_device.$(OBJEXT) names.$(OBJEXT) net.$(OBJEXT) \ meta.$(OBJEXT) multicast_device.$(OBJEXT) names.$(OBJEXT) \
net_packet.$(OBJEXT) net_setup.$(OBJEXT) net_socket.$(OBJEXT) \ net.$(OBJEXT) net_packet.$(OBJEXT) net_setup.$(OBJEXT) \
netutl.$(OBJEXT) node.$(OBJEXT) process.$(OBJEXT) \ net_socket.$(OBJEXT) netutl.$(OBJEXT) node.$(OBJEXT) \
protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \ process.$(OBJEXT) protocol.$(OBJEXT) protocol_auth.$(OBJEXT) \
protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \ protocol_edge.$(OBJEXT) protocol_key.$(OBJEXT) \
protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \ protocol_misc.$(OBJEXT) protocol_subnet.$(OBJEXT) \
raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \ raw_socket_device.$(OBJEXT) route.$(OBJEXT) script.$(OBJEXT) \
@ -423,7 +425,54 @@ am__v_at_0 = @
am__v_at_1 = am__v_at_1 =
DEFAULT_INCLUDES = DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/address_cache.Po \
./$(DEPDIR)/autoconnect.Po ./$(DEPDIR)/buffer.Po \
./$(DEPDIR)/conf.Po ./$(DEPDIR)/connection.Po \
./$(DEPDIR)/control.Po ./$(DEPDIR)/dropin.Po \
./$(DEPDIR)/dummy_device.Po ./$(DEPDIR)/edge.Po \
./$(DEPDIR)/event.Po ./$(DEPDIR)/fd_device.Po \
./$(DEPDIR)/fsck.Po ./$(DEPDIR)/getopt.Po \
./$(DEPDIR)/getopt1.Po ./$(DEPDIR)/graph.Po \
./$(DEPDIR)/hash.Po ./$(DEPDIR)/ifconfig.Po \
./$(DEPDIR)/info.Po ./$(DEPDIR)/invitation.Po \
./$(DEPDIR)/list.Po ./$(DEPDIR)/logger.Po ./$(DEPDIR)/meta.Po \
./$(DEPDIR)/multicast_device.Po ./$(DEPDIR)/names.Po \
./$(DEPDIR)/net.Po ./$(DEPDIR)/net_packet.Po \
./$(DEPDIR)/net_setup.Po ./$(DEPDIR)/net_socket.Po \
./$(DEPDIR)/netutl.Po ./$(DEPDIR)/node.Po \
./$(DEPDIR)/process.Po ./$(DEPDIR)/protocol.Po \
./$(DEPDIR)/protocol_auth.Po ./$(DEPDIR)/protocol_edge.Po \
./$(DEPDIR)/protocol_key.Po ./$(DEPDIR)/protocol_misc.Po \
./$(DEPDIR)/protocol_subnet.Po \
./$(DEPDIR)/raw_socket_device.Po ./$(DEPDIR)/route.Po \
./$(DEPDIR)/script.Po ./$(DEPDIR)/splay_tree.Po \
./$(DEPDIR)/sptps.Po ./$(DEPDIR)/sptps_keypair.Po \
./$(DEPDIR)/sptps_speed.Po ./$(DEPDIR)/sptps_test.Po \
./$(DEPDIR)/subnet.Po ./$(DEPDIR)/subnet_parse.Po \
./$(DEPDIR)/tincctl.Po ./$(DEPDIR)/tincd.Po ./$(DEPDIR)/top.Po \
./$(DEPDIR)/uml_device.Po ./$(DEPDIR)/upnp.Po \
./$(DEPDIR)/utils.Po ./$(DEPDIR)/vde_device.Po \
./$(DEPDIR)/version.Po bsd/$(DEPDIR)/device.Po \
bsd/$(DEPDIR)/tunemu.Po \
chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po \
chacha-poly1305/$(DEPDIR)/chacha.Po \
chacha-poly1305/$(DEPDIR)/poly1305.Po \
cygwin/$(DEPDIR)/device.Po ed25519/$(DEPDIR)/ecdh.Po \
ed25519/$(DEPDIR)/ecdsa.Po ed25519/$(DEPDIR)/ecdsagen.Po \
ed25519/$(DEPDIR)/fe.Po ed25519/$(DEPDIR)/ge.Po \
ed25519/$(DEPDIR)/key_exchange.Po ed25519/$(DEPDIR)/keypair.Po \
ed25519/$(DEPDIR)/sc.Po ed25519/$(DEPDIR)/sha512.Po \
ed25519/$(DEPDIR)/sign.Po ed25519/$(DEPDIR)/verify.Po \
gcrypt/$(DEPDIR)/cipher.Po gcrypt/$(DEPDIR)/crypto.Po \
gcrypt/$(DEPDIR)/digest.Po gcrypt/$(DEPDIR)/prf.Po \
gcrypt/$(DEPDIR)/rsa.Po gcrypt/$(DEPDIR)/rsagen.Po \
linux/$(DEPDIR)/device.Po mingw/$(DEPDIR)/device.Po \
nolegacy/$(DEPDIR)/crypto.Po nolegacy/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/cipher.Po openssl/$(DEPDIR)/crypto.Po \
openssl/$(DEPDIR)/digest.Po openssl/$(DEPDIR)/prf.Po \
openssl/$(DEPDIR)/rsa.Po openssl/$(DEPDIR)/rsagen.Po \
solaris/$(DEPDIR)/device.Po
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -478,6 +527,12 @@ AWK = @AWK@
CC = @CC@ CC = @CC@
CCDEPMODE = @CCDEPMODE@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
CPP = @CPP@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
CURSES_LIBS = @CURSES_LIBS@ CURSES_LIBS = @CURSES_LIBS@
@ -489,16 +544,18 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@ ECHO_T = @ECHO_T@
EGREP = @EGREP@ EGREP = @EGREP@
EXEEXT = @EXEEXT@ EXEEXT = @EXEEXT@
GCOV = @GCOV@
GENHTML = @GENHTML@
GREP = @GREP@ GREP = @GREP@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LCOV = @LCOV@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ -lm $(am__append_30) LIBS = @LIBS@ -lm $(CODE_COVERAGE_LIBS) $(am__append_30)
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@ MAKEINFO = @MAKEINFO@
MINIUPNPC_LIBS = @MINIUPNPC_LIBS@ MINIUPNPC_LIBS = @MINIUPNPC_LIBS@
@ -513,6 +570,7 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@ PATH_SEPARATOR = @PATH_SEPARATOR@
READLINE_LIBS = @READLINE_LIBS@ READLINE_LIBS = @READLINE_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@ SHELL = @SHELL@
STRIP = @STRIP@ STRIP = @STRIP@
@ -588,16 +646,17 @@ chacha_poly1305_SOURCES = \
chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \ chacha-poly1305/chacha-poly1305.c chacha-poly1305/chacha-poly1305.h \
chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h
tincd_SOURCES = autoconnect.c autoconnect.h buffer.c buffer.h cipher.h \ tincd_SOURCES = address_cache.c address_cache.h autoconnect.c \
conf.c conf.h connection.c connection.h control.c control.h \ autoconnect.h buffer.c buffer.h cipher.h conf.c conf.h \
control_common.h crypto.h device.h digest.h dropin.c dropin.h \ connection.c connection.h control.c control.h control_common.h \
dummy_device.c ecdh.h ecdsa.h ecdsagen.h edge.c edge.h \ crypto.h device.h digest.h dropin.c dropin.h dummy_device.c \
ethernet.h event.c event.h fd_device.c graph.c graph.h hash.c \ ecdh.h ecdsa.h ecdsagen.h edge.c edge.h ethernet.h event.c \
hash.h have.h ipv4.h ipv6.h list.c list.h logger.c logger.h \ event.h fd_device.c graph.c graph.h hash.c hash.h have.h \
meta.c meta.h multicast_device.c names.c names.h net.c net.h \ ipv4.h ipv6.h list.c list.h logger.c logger.h meta.c meta.h \
net_packet.c net_setup.c net_socket.c netutl.c netutl.h node.c \ multicast_device.c names.c names.h net.c net.h net_packet.c \
node.h prf.h process.c process.h protocol.c protocol.h \ net_setup.c net_socket.c netutl.c netutl.h node.c node.h prf.h \
protocol_auth.c protocol_edge.c protocol_key.c protocol_misc.c \ process.c process.h protocol.c protocol.h protocol_auth.c \
protocol_edge.c protocol_key.c protocol_misc.c \
protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \ protocol_subnet.c raw_socket_device.c route.c route.h rsa.h \
rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \ rsagen.h script.c script.h splay_tree.c splay_tree.h sptps.c \
sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \ sptps.h subnet.c subnet.h subnet_parse.c system.h tincd.c \
@ -632,7 +691,8 @@ sptps_speed_SOURCES = logger.c logger.h sptps.c sptps.h sptps_speed.c \
@MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread @MINIUPNPC_TRUE@tincd_LDFLAGS = -pthread
tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
sptps_speed_LDADD = -lrt sptps_speed_LDADD = -lrt
AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. AM_CFLAGS = -DCONFDIR=\"$(sysconfdir)\" -DRUNSTATEDIR=\"$(runstatedir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" -iquote. $(CODE_COVERAGE_CFLAGS)
AM_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS)
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
@ -654,8 +714,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \ *config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -893,94 +953,101 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/address_cache.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autoconnect.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dropin.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsck.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invitation.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/names.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_socket.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netutl.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_auth.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_edge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_key.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_misc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_subnet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw_socket_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/script.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay_tree.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_keypair.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_speed.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sptps_test.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subnet_parse.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincctl.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tincd.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/top.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uml_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upnp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vde_device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bsd/$(DEPDIR)/tunemu.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/chacha.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@chacha-poly1305/$(DEPDIR)/poly1305.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cygwin/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdh.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ecdsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/fe.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/ge.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/key_exchange.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/keypair.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sha512.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/sign.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ed25519/$(DEPDIR)/verify.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@gcrypt/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@linux/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@mingw/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@nolegacy/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/cipher.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/crypto.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/digest.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/prf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsa.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@openssl/$(DEPDIR)/rsagen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@solaris/$(DEPDIR)/device.Po@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -1050,7 +1117,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags: distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \ list='$(DISTFILES)'; \
@ -1145,7 +1215,95 @@ clean-am: clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
mostlyclean-am mostlyclean-am
distclean: distclean-am distclean: distclean-am
-rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f ./$(DEPDIR)/address_cache.Po
-rm -f ./$(DEPDIR)/autoconnect.Po
-rm -f ./$(DEPDIR)/buffer.Po
-rm -f ./$(DEPDIR)/conf.Po
-rm -f ./$(DEPDIR)/connection.Po
-rm -f ./$(DEPDIR)/control.Po
-rm -f ./$(DEPDIR)/dropin.Po
-rm -f ./$(DEPDIR)/dummy_device.Po
-rm -f ./$(DEPDIR)/edge.Po
-rm -f ./$(DEPDIR)/event.Po
-rm -f ./$(DEPDIR)/fd_device.Po
-rm -f ./$(DEPDIR)/fsck.Po
-rm -f ./$(DEPDIR)/getopt.Po
-rm -f ./$(DEPDIR)/getopt1.Po
-rm -f ./$(DEPDIR)/graph.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/ifconfig.Po
-rm -f ./$(DEPDIR)/info.Po
-rm -f ./$(DEPDIR)/invitation.Po
-rm -f ./$(DEPDIR)/list.Po
-rm -f ./$(DEPDIR)/logger.Po
-rm -f ./$(DEPDIR)/meta.Po
-rm -f ./$(DEPDIR)/multicast_device.Po
-rm -f ./$(DEPDIR)/names.Po
-rm -f ./$(DEPDIR)/net.Po
-rm -f ./$(DEPDIR)/net_packet.Po
-rm -f ./$(DEPDIR)/net_setup.Po
-rm -f ./$(DEPDIR)/net_socket.Po
-rm -f ./$(DEPDIR)/netutl.Po
-rm -f ./$(DEPDIR)/node.Po
-rm -f ./$(DEPDIR)/process.Po
-rm -f ./$(DEPDIR)/protocol.Po
-rm -f ./$(DEPDIR)/protocol_auth.Po
-rm -f ./$(DEPDIR)/protocol_edge.Po
-rm -f ./$(DEPDIR)/protocol_key.Po
-rm -f ./$(DEPDIR)/protocol_misc.Po
-rm -f ./$(DEPDIR)/protocol_subnet.Po
-rm -f ./$(DEPDIR)/raw_socket_device.Po
-rm -f ./$(DEPDIR)/route.Po
-rm -f ./$(DEPDIR)/script.Po
-rm -f ./$(DEPDIR)/splay_tree.Po
-rm -f ./$(DEPDIR)/sptps.Po
-rm -f ./$(DEPDIR)/sptps_keypair.Po
-rm -f ./$(DEPDIR)/sptps_speed.Po
-rm -f ./$(DEPDIR)/sptps_test.Po
-rm -f ./$(DEPDIR)/subnet.Po
-rm -f ./$(DEPDIR)/subnet_parse.Po
-rm -f ./$(DEPDIR)/tincctl.Po
-rm -f ./$(DEPDIR)/tincd.Po
-rm -f ./$(DEPDIR)/top.Po
-rm -f ./$(DEPDIR)/uml_device.Po
-rm -f ./$(DEPDIR)/upnp.Po
-rm -f ./$(DEPDIR)/utils.Po
-rm -f ./$(DEPDIR)/vde_device.Po
-rm -f ./$(DEPDIR)/version.Po
-rm -f bsd/$(DEPDIR)/device.Po
-rm -f bsd/$(DEPDIR)/tunemu.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po
-rm -f ed25519/$(DEPDIR)/fe.Po
-rm -f ed25519/$(DEPDIR)/ge.Po
-rm -f ed25519/$(DEPDIR)/key_exchange.Po
-rm -f ed25519/$(DEPDIR)/keypair.Po
-rm -f ed25519/$(DEPDIR)/sc.Po
-rm -f ed25519/$(DEPDIR)/sha512.Po
-rm -f ed25519/$(DEPDIR)/sign.Po
-rm -f ed25519/$(DEPDIR)/verify.Po
-rm -f gcrypt/$(DEPDIR)/cipher.Po
-rm -f gcrypt/$(DEPDIR)/crypto.Po
-rm -f gcrypt/$(DEPDIR)/digest.Po
-rm -f gcrypt/$(DEPDIR)/prf.Po
-rm -f gcrypt/$(DEPDIR)/rsa.Po
-rm -f gcrypt/$(DEPDIR)/rsagen.Po
-rm -f linux/$(DEPDIR)/device.Po
-rm -f mingw/$(DEPDIR)/device.Po
-rm -f nolegacy/$(DEPDIR)/crypto.Po
-rm -f nolegacy/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/cipher.Po
-rm -f openssl/$(DEPDIR)/crypto.Po
-rm -f openssl/$(DEPDIR)/digest.Po
-rm -f openssl/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/rsa.Po
-rm -f openssl/$(DEPDIR)/rsagen.Po
-rm -f solaris/$(DEPDIR)/device.Po
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \ distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags distclean-tags
@ -1191,7 +1349,95 @@ install-ps-am:
installcheck-am: installcheck-sbinPROGRAMS installcheck-am: installcheck-sbinPROGRAMS
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) bsd/$(DEPDIR) chacha-poly1305/$(DEPDIR) cygwin/$(DEPDIR) ed25519/$(DEPDIR) gcrypt/$(DEPDIR) linux/$(DEPDIR) mingw/$(DEPDIR) nolegacy/$(DEPDIR) openssl/$(DEPDIR) solaris/$(DEPDIR) -rm -f ./$(DEPDIR)/address_cache.Po
-rm -f ./$(DEPDIR)/autoconnect.Po
-rm -f ./$(DEPDIR)/buffer.Po
-rm -f ./$(DEPDIR)/conf.Po
-rm -f ./$(DEPDIR)/connection.Po
-rm -f ./$(DEPDIR)/control.Po
-rm -f ./$(DEPDIR)/dropin.Po
-rm -f ./$(DEPDIR)/dummy_device.Po
-rm -f ./$(DEPDIR)/edge.Po
-rm -f ./$(DEPDIR)/event.Po
-rm -f ./$(DEPDIR)/fd_device.Po
-rm -f ./$(DEPDIR)/fsck.Po
-rm -f ./$(DEPDIR)/getopt.Po
-rm -f ./$(DEPDIR)/getopt1.Po
-rm -f ./$(DEPDIR)/graph.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/ifconfig.Po
-rm -f ./$(DEPDIR)/info.Po
-rm -f ./$(DEPDIR)/invitation.Po
-rm -f ./$(DEPDIR)/list.Po
-rm -f ./$(DEPDIR)/logger.Po
-rm -f ./$(DEPDIR)/meta.Po
-rm -f ./$(DEPDIR)/multicast_device.Po
-rm -f ./$(DEPDIR)/names.Po
-rm -f ./$(DEPDIR)/net.Po
-rm -f ./$(DEPDIR)/net_packet.Po
-rm -f ./$(DEPDIR)/net_setup.Po
-rm -f ./$(DEPDIR)/net_socket.Po
-rm -f ./$(DEPDIR)/netutl.Po
-rm -f ./$(DEPDIR)/node.Po
-rm -f ./$(DEPDIR)/process.Po
-rm -f ./$(DEPDIR)/protocol.Po
-rm -f ./$(DEPDIR)/protocol_auth.Po
-rm -f ./$(DEPDIR)/protocol_edge.Po
-rm -f ./$(DEPDIR)/protocol_key.Po
-rm -f ./$(DEPDIR)/protocol_misc.Po
-rm -f ./$(DEPDIR)/protocol_subnet.Po
-rm -f ./$(DEPDIR)/raw_socket_device.Po
-rm -f ./$(DEPDIR)/route.Po
-rm -f ./$(DEPDIR)/script.Po
-rm -f ./$(DEPDIR)/splay_tree.Po
-rm -f ./$(DEPDIR)/sptps.Po
-rm -f ./$(DEPDIR)/sptps_keypair.Po
-rm -f ./$(DEPDIR)/sptps_speed.Po
-rm -f ./$(DEPDIR)/sptps_test.Po
-rm -f ./$(DEPDIR)/subnet.Po
-rm -f ./$(DEPDIR)/subnet_parse.Po
-rm -f ./$(DEPDIR)/tincctl.Po
-rm -f ./$(DEPDIR)/tincd.Po
-rm -f ./$(DEPDIR)/top.Po
-rm -f ./$(DEPDIR)/uml_device.Po
-rm -f ./$(DEPDIR)/upnp.Po
-rm -f ./$(DEPDIR)/utils.Po
-rm -f ./$(DEPDIR)/vde_device.Po
-rm -f ./$(DEPDIR)/version.Po
-rm -f bsd/$(DEPDIR)/device.Po
-rm -f bsd/$(DEPDIR)/tunemu.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha-poly1305.Po
-rm -f chacha-poly1305/$(DEPDIR)/chacha.Po
-rm -f chacha-poly1305/$(DEPDIR)/poly1305.Po
-rm -f cygwin/$(DEPDIR)/device.Po
-rm -f ed25519/$(DEPDIR)/ecdh.Po
-rm -f ed25519/$(DEPDIR)/ecdsa.Po
-rm -f ed25519/$(DEPDIR)/ecdsagen.Po
-rm -f ed25519/$(DEPDIR)/fe.Po
-rm -f ed25519/$(DEPDIR)/ge.Po
-rm -f ed25519/$(DEPDIR)/key_exchange.Po
-rm -f ed25519/$(DEPDIR)/keypair.Po
-rm -f ed25519/$(DEPDIR)/sc.Po
-rm -f ed25519/$(DEPDIR)/sha512.Po
-rm -f ed25519/$(DEPDIR)/sign.Po
-rm -f ed25519/$(DEPDIR)/verify.Po
-rm -f gcrypt/$(DEPDIR)/cipher.Po
-rm -f gcrypt/$(DEPDIR)/crypto.Po
-rm -f gcrypt/$(DEPDIR)/digest.Po
-rm -f gcrypt/$(DEPDIR)/prf.Po
-rm -f gcrypt/$(DEPDIR)/rsa.Po
-rm -f gcrypt/$(DEPDIR)/rsagen.Po
-rm -f linux/$(DEPDIR)/device.Po
-rm -f mingw/$(DEPDIR)/device.Po
-rm -f nolegacy/$(DEPDIR)/crypto.Po
-rm -f nolegacy/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/cipher.Po
-rm -f openssl/$(DEPDIR)/crypto.Po
-rm -f openssl/$(DEPDIR)/digest.Po
-rm -f openssl/$(DEPDIR)/prf.Po
-rm -f openssl/$(DEPDIR)/rsa.Po
-rm -f openssl/$(DEPDIR)/rsagen.Po
-rm -f solaris/$(DEPDIR)/device.Po
-rm -f Makefile -rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic maintainer-clean-am: distclean-am maintainer-clean-generic
@ -1211,7 +1457,7 @@ uninstall-am: uninstall-sbinPROGRAMS
.MAKE: check-am install-am install-strip .MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \ clean-checkPROGRAMS clean-generic clean-sbinPROGRAMS \
cscopelist-am ctags ctags-am distclean distclean-compile \ cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \ distclean-generic distclean-tags distdir dvi dvi-am html \

277
src/address_cache.c Normal file
View file

@ -0,0 +1,277 @@
/*
address_cache.c -- Manage cache of recently seen addresses
Copyright (C) 2018 Guus Sliepen <guus@tinc-vpn.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "system.h"
#include "address_cache.h"
#include "conf.h"
#include "names.h"
#include "netutl.h"
#include "xalloc.h"
static const unsigned int NOT_CACHED = -1;
// Find edges pointing to this node, and use them to build a list of unique, known addresses.
static struct addrinfo *get_known_addresses(node_t *n) {
struct addrinfo *ai = NULL;
struct addrinfo *oai = NULL;
for splay_each(edge_t, e, n->edge_tree) {
if(!e->reverse) {
continue;
}
bool found = false;
for(struct addrinfo *aip = ai; aip; aip = aip->ai_next) {
if(!sockaddrcmp(&e->reverse->address, (sockaddr_t *)aip->ai_addr)) {
found = true;
break;
}
}
if(found) {
continue;
}
oai = ai;
ai = xzalloc(sizeof(*ai));
ai->ai_family = e->reverse->address.sa.sa_family;
ai->ai_socktype = SOCK_STREAM;
ai->ai_protocol = IPPROTO_TCP;
ai->ai_addrlen = SALEN(e->reverse->address.sa);
ai->ai_addr = xmalloc(ai->ai_addrlen);
memcpy(ai->ai_addr, &e->reverse->address, ai->ai_addrlen);
ai->ai_next = oai;
}
return ai;
}
static void free_known_addresses(struct addrinfo *ai) {
for(struct addrinfo *aip = ai, *next; aip; aip = next) {
next = aip->ai_next;
free(aip);
}
}
static unsigned int find_cached(address_cache_t *cache, const sockaddr_t *sa) {
for(unsigned int i = 0; i < cache->data.used; i++)
if(!sockaddrcmp(&cache->data.address[i], sa)) {
return i;
}
return NOT_CACHED;
}
void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) {
// Check if it's already cached
unsigned int pos = find_cached(cache, sa);
// It's in the first spot, so nothing to do
if(pos == 0) {
return;
}
// Shift everything, move/add the address to the first slot
if(pos == NOT_CACHED) {
if(cache->data.used < MAX_CACHED_ADDRESSES) {
cache->data.used++;
}
pos = cache->data.used - 1;
}
memmove(&cache->data.address[1], &cache->data.address[0], pos * sizeof(cache->data.address[0]));
cache->data.address[0] = *sa;
// Write the cache
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, cache->node->name);
FILE *fp = fopen(fname, "wb");
if(fp) {
fwrite(&cache->data, sizeof(cache->data), 1, fp);
fclose(fp);
}
}
const sockaddr_t *get_recent_address(address_cache_t *cache) {
// Check if there is an address in our cache of recently seen addresses
if(cache->tried < cache->data.used) {
return &cache->data.address[cache->tried++];
}
// Next, check any recently seen addresses not in our cache
while(cache->tried == cache->data.used) {
if(!cache->ai) {
cache->aip = cache->ai = get_known_addresses(cache->node);
}
if(cache->ai) {
if(cache->aip) {
sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
cache->aip = cache->aip->ai_next;
if(find_cached(cache, sa) != NOT_CACHED) {
continue;
}
return sa;
} else {
free_known_addresses(cache->ai);
cache->ai = NULL;
}
}
cache->tried++;
}
// Otherwise, check if there are any known Address statements
if(!cache->config_tree) {
init_configuration(&cache->config_tree);
read_host_config(cache->config_tree, cache->node->name, false);
cache->cfg = lookup_config(cache->config_tree, "Address");
}
while(cache->cfg && !cache->ai) {
char *address, *port;
get_config_string(cache->cfg, &address);
char *space = strchr(address, ' ');
if(space) {
port = xstrdup(space + 1);
*space = 0;
} else {
if(!get_config_string(lookup_config(cache->config_tree, "Port"), &port)) {
port = xstrdup("655");
}
}
cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM);
if(cache->ai) {
struct addrinfo *ai = NULL;
for(; cache->aip; cache->aip = cache->aip->ai_next) {
struct addrinfo *oai = ai;
ai = xzalloc(sizeof(*ai));
ai->ai_family = cache->aip->ai_family;
ai->ai_socktype = cache->aip->ai_socktype;
ai->ai_protocol = cache->aip->ai_protocol;
ai->ai_addrlen = cache->aip->ai_addrlen;
ai->ai_addr = xmalloc(ai->ai_addrlen);
memcpy(ai->ai_addr, cache->aip->ai_addr, ai->ai_addrlen);
ai->ai_next = oai;
}
freeaddrinfo(cache->ai);
cache->aip = cache->ai = ai;
}
free(address);
free(port);
cache->cfg = lookup_config_next(cache->config_tree, cache->cfg);
}
if(cache->ai) {
if(cache->aip) {
sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr;
cache->aip = cache->aip->ai_next;
return sa;
} else {
free_known_addresses(cache->ai);
cache->ai = NULL;
}
}
// We're all out of addresses.
exit_configuration(&cache->config_tree);
return false;
}
address_cache_t *open_address_cache(node_t *node) {
address_cache_t *cache = xmalloc(sizeof(*cache));
cache->node = node;
// Try to open an existing address cache
char fname[PATH_MAX];
snprintf(fname, sizeof(fname), "%s" SLASH "cache" SLASH "%s", confbase, node->name);
FILE *fp = fopen(fname, "rb");
if(!fp || fread(&cache->data, sizeof(cache->data), 1, fp) != 1 || cache->data.version != ADDRESS_CACHE_VERSION) {
memset(&cache->data, 0, sizeof(cache->data));
}
if(fp) {
fclose(fp);
}
// Ensure we have a valid state
cache->config_tree = NULL;
cache->cfg = NULL;
cache->ai = NULL;
cache->aip = NULL;
cache->tried = 0;
cache->data.version = ADDRESS_CACHE_VERSION;
if(cache->data.used > MAX_CACHED_ADDRESSES) {
cache->data.used = 0;
}
return cache;
}
void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) {
if(sa) {
add_recent_address(cache, sa);
}
if(cache->config_tree) {
exit_configuration(&cache->config_tree);
}
if(cache->ai) {
free_known_addresses(cache->ai);
}
cache->config_tree = NULL;
cache->cfg = NULL;
cache->ai = NULL;
cache->aip = NULL;
cache->tried = 0;
}
void close_address_cache(address_cache_t *cache) {
if(cache->config_tree) {
exit_configuration(&cache->config_tree);
}
if(cache->ai) {
free_known_addresses(cache->ai);
}
free(cache);
}

50
src/address_cache.h Normal file
View file

@ -0,0 +1,50 @@
#ifndef TINC_ADDRESS_CACHE_H
#define TINC_ADDRESS_CACHE_H
/*
address_cache.h -- header for address_cache.c
Copyright (C) 2018 Guus Sliepen <guus@tinc-vpn.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "net.h"
#define MAX_CACHED_ADDRESSES 8
#define ADDRESS_CACHE_VERSION 1
typedef struct address_cache_t {
struct node_t *node;
struct splay_tree_t *config_tree;
struct config_t *cfg;
struct addrinfo *ai;
struct addrinfo *aip;
unsigned int tried;
struct {
unsigned int version;
unsigned int used;
sockaddr_t address[MAX_CACHED_ADDRESSES];
} data;
} address_cache_t;
void add_recent_address(address_cache_t *cache, const sockaddr_t *sa);
const sockaddr_t *get_recent_address(address_cache_t *cache);
address_cache_t *open_address_cache(struct node_t *node);
void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa);
void close_address_cache(address_cache_t *cache);
#endif

View file

@ -27,28 +27,34 @@
static void make_new_connection() { static void make_new_connection() {
/* Select a random node we haven't connected to yet. */ /* Select a random node we haven't connected to yet. */
int count = 0; int count = 0;
for splay_each(node_t, n, node_tree) { for splay_each(node_t, n, node_tree) {
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) {
continue; continue;
}
count++; count++;
} }
if(!count) if(!count) {
return; return;
}
int r = rand() % count; int r = rand() % count;
for splay_each(node_t, n, node_tree) { for splay_each(node_t, n, node_tree) {
if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) if(n == myself || n->connection || !(n->status.has_address || n->status.reachable)) {
continue; continue;
}
if(r--) if(r--) {
continue; continue;
}
bool found = false; bool found = false;
for list_each(outgoing_t, outgoing, outgoing_list) { for list_each(outgoing_t, outgoing, outgoing_list) {
if(!strcmp(outgoing->name, n->name)) { if(outgoing->node == n) {
found = true; found = true;
break; break;
} }
@ -56,10 +62,10 @@ static void make_new_connection() {
if(!found) { if(!found) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->name = xstrdup(n->name); outgoing->node = n;
list_insert_tail(outgoing_list, outgoing); list_insert_tail(outgoing_list, outgoing);
setup_outgoing_connection(outgoing); setup_outgoing_connection(outgoing, false);
} }
break; break;
@ -77,23 +83,27 @@ static void connect_to_unreachable() {
int r = rand() % node_tree->count; int r = rand() % node_tree->count;
for splay_each(node_t, n, node_tree) { for splay_each(node_t, n, node_tree) {
if(r--) if(r--) {
continue; continue;
}
/* Is it unreachable and do we know an address for it? If not, return. */ /* Is it unreachable and do we know an address for it? If not, return. */
if(n == myself || n->connection || n->status.reachable || !n->status.has_address) if(n == myself || n->connection || n->status.reachable || !n->status.has_address) {
return; return;
}
/* Are we already trying to make an outgoing connection to it? If not, return. */ /* Are we already trying to make an outgoing connection to it? If so, return. */
for list_each(outgoing_t, outgoing, outgoing_list) for list_each(outgoing_t, outgoing, outgoing_list) {
if(!strcmp(outgoing->name, n->name)) if(outgoing->node == n) {
return; return;
}
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name); logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof *outgoing); outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->name = xstrdup(n->name); outgoing->node = n;
list_insert_tail(outgoing_list, outgoing); list_insert_tail(outgoing_list, outgoing);
setup_outgoing_connection(outgoing); setup_outgoing_connection(outgoing, false);
return; return;
} }
@ -102,23 +112,29 @@ static void connect_to_unreachable() {
static void drop_superfluous_outgoing_connection() { static void drop_superfluous_outgoing_connection() {
/* Choose a random outgoing connection to a node that has at least one other connection. */ /* Choose a random outgoing connection to a node that has at least one other connection. */
int count = 0; int count = 0;
for list_each(connection_t, c, connection_list) { for list_each(connection_t, c, connection_list) {
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue; continue;
}
count++; count++;
} }
if(!count) if(!count) {
return; return;
}
int r = rand() % count; int r = rand() % count;
for list_each(connection_t, c, connection_list) { for list_each(connection_t, c, connection_list) {
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue; continue;
}
if(r--)
if(r--) {
continue; continue;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name); logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
list_delete(outgoing_list, c->outgoing); list_delete(outgoing_list, c->outgoing);
@ -132,6 +148,7 @@ static void drop_superfluous_pending_connections() {
for list_each(outgoing_t, o, outgoing_list) { for list_each(outgoing_t, o, outgoing_list) {
/* Only look for connections that are waiting to be retried later. */ /* Only look for connections that are waiting to be retried later. */
bool found = false; bool found = false;
for list_each(connection_t, c, connection_list) { for list_each(connection_t, c, connection_list) {
if(c->outgoing == o) { if(c->outgoing == o) {
found = true; found = true;
@ -139,10 +156,11 @@ static void drop_superfluous_pending_connections() {
} }
} }
if(found) if(found) {
continue; continue;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->name); logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->node->name);
list_delete_node(outgoing_list, node); list_delete_node(outgoing_list, node);
} }
} }
@ -150,9 +168,11 @@ static void drop_superfluous_pending_connections() {
void do_autoconnect() { void do_autoconnect() {
/* Count number of active connections. */ /* Count number of active connections. */
int nc = 0; int nc = 0;
for list_each(connection_t, c, connection_list) { for list_each(connection_t, c, connection_list) {
if(c->edge) if(c->edge) {
nc++; nc++;
}
} }
/* Less than 3 connections? Eagerly try to make a new one. */ /* Less than 3 connections? Eagerly try to make a new one. */
@ -160,10 +180,11 @@ void do_autoconnect() {
make_new_connection(); make_new_connection();
return; return;
} }
/* More than 3 connections? See if we can get rid of a superfluous one. */ /* More than 3 connections? See if we can get rid of a superfluous one. */
if(nc > 3) if(nc > 3) {
drop_superfluous_outgoing_connection(); drop_superfluous_outgoing_connection();
}
/* Check if there are unreachable nodes that we should try to connect to. */ /* Check if there are unreachable nodes that we should try to connect to. */

View file

@ -1,3 +1,6 @@
#ifndef TINC_AUTOCONNECT_H
#define TINC_AUTOCONNECT_H
/* /*
autoconnect.h -- header for autoconnect.c autoconnect.h -- header for autoconnect.c
Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_AUTOCONNECT_H__
#define __TINC_AUTOCONNECT_H__
extern void do_autoconnect(void); extern void do_autoconnect(void);
#endif #endif

View file

@ -56,7 +56,7 @@ typedef enum device_type {
int device_fd = -1; int device_fd = -1;
char *device = NULL; char *device = NULL;
char *iface = NULL; char *iface = NULL;
static char *device_info = NULL; static const char *device_info = "OS X utun device";
#if defined(ENABLE_TUNEMU) #if defined(ENABLE_TUNEMU)
static device_type_t device_type = DEVICE_TYPE_TUNEMU; static device_type_t device_type = DEVICE_TYPE_TUNEMU;
#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY) #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
@ -68,13 +68,15 @@ static device_type_t device_type = DEVICE_TYPE_TUN;
#ifdef HAVE_NET_IF_UTUN_H #ifdef HAVE_NET_IF_UTUN_H
static bool setup_utun(void) { static bool setup_utun(void) {
device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if(device_fd == -1) { if(device_fd == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
return false; return false;
} }
struct ctl_info info = {}; struct ctl_info info = {};
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof info.ctl_name);
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) { if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
@ -83,15 +85,18 @@ static bool setup_utun(void) {
int unit = -1; int unit = -1;
char *p = strstr(device, "utun"), *e = NULL; char *p = strstr(device, "utun"), *e = NULL;
if(p) { if(p) {
unit = strtol(p + 4, &e, 10); unit = strtol(p + 4, &e, 10);
if(!e)
if(!e) {
unit = -1; unit = -1;
}
} }
struct sockaddr_ctl sc = { struct sockaddr_ctl sc = {
.sc_id = info.ctl_id, .sc_id = info.ctl_id,
.sc_len = sizeof sc, .sc_len = sizeof(sc),
.sc_family = AF_SYSTEM, .sc_family = AF_SYSTEM,
.ss_sysaddr = AF_SYS_CONTROL, .ss_sysaddr = AF_SYS_CONTROL,
.sc_unit = unit + 1, .sc_unit = unit + 1,
@ -103,15 +108,14 @@ static bool setup_utun(void) {
} }
char name[64] = ""; char name[64] = "";
socklen_t len = sizeof name; socklen_t len = sizeof(name);
if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) { if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
iface = xstrdup(device); iface = xstrdup(device);
} else { } else {
iface = xstrdup(name); iface = xstrdup(name);
} }
device_info = "OS X utun device";
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
return true; return true;
@ -124,35 +128,43 @@ static bool setup_device(void) {
// Find out if it's supposed to be a tun or a tap device // Find out if it's supposed to be a tun or a tap device
char *type; char *type;
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
if(!strcasecmp(type, "tun")) if(!strcasecmp(type, "tun"))
/* use default */; /* use default */;
#ifdef ENABLE_TUNEMU #ifdef ENABLE_TUNEMU
else if(!strcasecmp(type, "tunemu")) else if(!strcasecmp(type, "tunemu")) {
device_type = DEVICE_TYPE_TUNEMU; device_type = DEVICE_TYPE_TUNEMU;
}
#endif #endif
#ifdef HAVE_NET_IF_UTUN_H #ifdef HAVE_NET_IF_UTUN_H
else if(!strcasecmp(type, "utun")) else if(!strcasecmp(type, "utun")) {
device_type = DEVICE_TYPE_UTUN; device_type = DEVICE_TYPE_UTUN;
}
#endif #endif
else if(!strcasecmp(type, "tunnohead")) else if(!strcasecmp(type, "tunnohead")) {
device_type = DEVICE_TYPE_TUN; device_type = DEVICE_TYPE_TUN;
else if(!strcasecmp(type, "tunifhead")) } else if(!strcasecmp(type, "tunifhead")) {
device_type = DEVICE_TYPE_TUNIFHEAD; device_type = DEVICE_TYPE_TUNIFHEAD;
else if(!strcasecmp(type, "tap")) } else if(!strcasecmp(type, "tap")) {
device_type = DEVICE_TYPE_TAP; device_type = DEVICE_TYPE_TAP;
else { } else {
logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type); logger(DEBUG_ALWAYS, LOG_ERR, "Unknown device type %s!", type);
return false; return false;
} }
} else { } else {
#ifdef HAVE_NET_IF_UTUN_H #ifdef HAVE_NET_IF_UTUN_H
if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0))
if(device && (strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0)) {
device_type = DEVICE_TYPE_UTUN; device_type = DEVICE_TYPE_UTUN;
else } else
#endif #endif
if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) if((device && strstr(device, "tap")) || routing_mode != RMODE_ROUTER) {
device_type = DEVICE_TYPE_TAP; device_type = DEVICE_TYPE_TAP;
}
} }
if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) { if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
@ -163,28 +175,32 @@ static bool setup_device(void) {
// Find out which device file to open // Find out which device file to open
if(!device) { if(!device) {
if(device_type == DEVICE_TYPE_TAP) if(device_type == DEVICE_TYPE_TAP) {
device = xstrdup(DEFAULT_TAP_DEVICE); device = xstrdup(DEFAULT_TAP_DEVICE);
else } else {
device = xstrdup(DEFAULT_TUN_DEVICE); device = xstrdup(DEFAULT_TUN_DEVICE);
}
} }
// Open the device // Open the device
switch(device_type) { switch(device_type) {
#ifdef ENABLE_TUNEMU #ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU: {
char dynamic_name[256] = ""; case DEVICE_TYPE_TUNEMU: {
device_fd = tunemu_open(dynamic_name); char dynamic_name[256] = "";
} device_fd = tunemu_open(dynamic_name);
break; }
break;
#endif #endif
#ifdef HAVE_NET_IF_UTUN_H #ifdef HAVE_NET_IF_UTUN_H
case DEVICE_TYPE_UTUN:
return setup_utun(); case DEVICE_TYPE_UTUN:
return setup_utun();
#endif #endif
default:
device_fd = open(device, O_RDWR | O_NONBLOCK); default:
device_fd = open(device, O_RDWR | O_NONBLOCK);
} }
if(device_fd < 0) { if(device_fd < 0) {
@ -204,87 +220,105 @@ static bool setup_device(void) {
realname = fdevname(device_fd); realname = fdevname(device_fd);
#elif defined(HAVE_DEVNAME) #elif defined(HAVE_DEVNAME)
struct stat buf; struct stat buf;
if(!fstat(device_fd, &buf))
if(!fstat(device_fd, &buf)) {
realname = devname(buf.st_rdev, S_IFCHR); realname = devname(buf.st_rdev, S_IFCHR);
}
#endif #endif
if(!realname) if(!realname) {
realname = device; realname = device;
}
if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) {
iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname); iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname);
else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly."); logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
}
// Configure the device as best as we can // Configure the device as best as we can
switch(device_type) { switch(device_type) {
default: default:
device_type = DEVICE_TYPE_TUN; device_type = DEVICE_TYPE_TUN;
case DEVICE_TYPE_TUN:
case DEVICE_TYPE_TUN:
#ifdef TUNSIFHEAD #ifdef TUNSIFHEAD
{ {
const int zero = 0; const int zero = 0;
if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) {
if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
return false; return false;
} }
} }
#endif #endif
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
{ {
const int mode = IFF_BROADCAST | IFF_MULTICAST; const int mode = IFF_BROADCAST | IFF_MULTICAST;
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
} }
#endif #endif
device_info = "Generic BSD tun device"; device_info = "Generic BSD tun device";
break; break;
case DEVICE_TYPE_TUNIFHEAD:
case DEVICE_TYPE_TUNIFHEAD:
#ifdef TUNSIFHEAD #ifdef TUNSIFHEAD
{ {
const int one = 1; const int one = 1;
if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) {
if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
return false; return false;
} }
} }
#endif #endif
#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST) #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
{ {
const int mode = IFF_BROADCAST | IFF_MULTICAST; const int mode = IFF_BROADCAST | IFF_MULTICAST;
ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode); ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
} }
#endif #endif
device_info = "Generic BSD tun device"; device_info = "Generic BSD tun device";
break; break;
case DEVICE_TYPE_TAP:
if(routing_mode == RMODE_ROUTER) case DEVICE_TYPE_TAP:
overwrite_mac = true; if(routing_mode == RMODE_ROUTER) {
device_info = "Generic BSD tap device"; overwrite_mac = true;
}
device_info = "Generic BSD tap device";
#ifdef TAPGIFNAME #ifdef TAPGIFNAME
{ {
struct ifreq ifr; struct ifreq ifr;
if(ioctl(device_fd, TAPGIFNAME, (void*)&ifr) == 0) {
if(iface) if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
free(iface); free(iface);
iface = xstrdup(ifr.ifr_name); iface = xstrdup(ifr.ifr_name);
}
} }
}
#endif #endif
break; break;
#ifdef ENABLE_TUNEMU #ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
device_info = "BSD tunemu device"; case DEVICE_TYPE_TUNEMU:
break; device_info = "BSD tunemu device";
break;
#endif #endif
} }
#ifdef SIOCGIFADDR #ifdef SIOCGIFADDR
if(overwrite_mac)
if(overwrite_mac) {
ioctl(device_fd, SIOCGIFADDR, mymac.x); ioctl(device_fd, SIOCGIFADDR, mymac.x);
}
#endif #endif
logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info); logger(DEBUG_ALWAYS, LOG_INFO, "%s is a %s", device, device_info);
@ -295,17 +329,22 @@ static bool setup_device(void) {
static void close_device(void) { static void close_device(void) {
switch(device_type) { switch(device_type) {
#ifdef ENABLE_TUNEMU #ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
tunemu_close(device_fd); case DEVICE_TYPE_TUNEMU:
break; tunemu_close(device_fd);
break;
#endif #endif
default:
close(device_fd); default:
close(device_fd);
} }
device_fd = -1; device_fd = -1;
free(device); device = NULL; free(device);
free(iface); iface = NULL; device = NULL;
free(iface);
iface = NULL;
device_info = NULL; device_info = NULL;
} }
@ -313,154 +352,163 @@ static bool read_packet(vpn_packet_t *packet) {
int inlen; int inlen;
switch(device_type) { switch(device_type) {
case DEVICE_TYPE_TUN: case DEVICE_TYPE_TUN:
#ifdef ENABLE_TUNEMU #ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU: case DEVICE_TYPE_TUNEMU:
if(device_type == DEVICE_TYPE_TUNEMU) if(device_type == DEVICE_TYPE_TUNEMU) {
inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14); inlen = tunemu_read(device_fd, DATA(packet) + 14, MTU - 14);
else } else
#endif #endif
inlen = read(device_fd, DATA(packet) + 14, MTU - 14); inlen = read(device_fd, DATA(packet) + 14, MTU - 14);
if(inlen <= 0) { if(inlen <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno)); device, strerror(errno));
return false; return false;
}
switch(DATA(packet)[14] >> 4) {
case 4:
DATA(packet)[12] = 0x08;
DATA(packet)[13] = 0x00;
break;
case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown IP version %d while reading packet from %s %s",
DATA(packet)[14] >> 4, device_info, device);
return false;
}
memset(DATA(packet), 0, 12);
packet->len = inlen + 14;
break;
case DEVICE_TYPE_UTUN:
case DEVICE_TYPE_TUNIFHEAD: {
if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
}
switch (DATA(packet)[14] >> 4) {
case 4:
DATA(packet)[12] = 0x08;
DATA(packet)[13] = 0x00;
break;
case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown IP version %d while reading packet from %s %s",
DATA(packet)[14] >> 4, device_info, device);
return false;
}
memset(DATA(packet), 0, 12);
packet->len = inlen + 10;
break;
} }
case DEVICE_TYPE_TAP: switch(DATA(packet)[14] >> 4) {
if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) { case 4:
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, DATA(packet)[12] = 0x08;
device, strerror(errno)); DATA(packet)[13] = 0x00;
return false; break;
}
packet->len = inlen; case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break; break;
default: default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown IP version %d while reading packet from %s %s",
DATA(packet)[14] >> 4, device_info, device);
return false; return false;
}
memset(DATA(packet), 0, 12);
packet->len = inlen + 14;
break;
case DEVICE_TYPE_UTUN:
case DEVICE_TYPE_TUNIFHEAD: {
if((inlen = read(device_fd, DATA(packet) + 10, MTU - 10)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
}
switch(DATA(packet)[14] >> 4) {
case 4:
DATA(packet)[12] = 0x08;
DATA(packet)[13] = 0x00;
break;
case 6:
DATA(packet)[12] = 0x86;
DATA(packet)[13] = 0xDD;
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown IP version %d while reading packet from %s %s",
DATA(packet)[14] >> 4, device_info, device);
return false;
}
memset(DATA(packet), 0, 12);
packet->len = inlen + 10;
break;
}
case DEVICE_TYPE_TAP:
if((inlen = read(device_fd, DATA(packet), MTU)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno));
return false;
}
packet->len = inlen;
break;
default:
return false;
} }
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s",
packet->len, device_info); packet->len, device_info);
return true; return true;
} }
static bool write_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info); packet->len, device_info);
switch(device_type) { switch(device_type) {
case DEVICE_TYPE_TUN: case DEVICE_TYPE_TUN:
if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) { if(write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
device, strerror(errno)); device, strerror(errno));
return false; return false;
}
break;
case DEVICE_TYPE_UTUN:
case DEVICE_TYPE_TUNIFHEAD: {
int af = (DATA(packet)[12] << 8) + DATA(packet)[13];
uint32_t type;
switch (af) {
case 0x0800:
type = htonl(AF_INET);
break;
case 0x86DD:
type = htonl(AF_INET6);
break;
default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown address family %x while writing packet to %s %s",
af, device_info, device);
return false;
}
memcpy(DATA(packet) + 10, &type, sizeof type);
if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
strerror(errno));
return false;
}
break;
} }
case DEVICE_TYPE_TAP: break;
if(write(device_fd, DATA(packet), packet->len) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, case DEVICE_TYPE_UTUN:
device, strerror(errno)); case DEVICE_TYPE_TUNIFHEAD: {
return false; int af = (DATA(packet)[12] << 8) + DATA(packet)[13];
} uint32_t type;
switch(af) {
case 0x0800:
type = htonl(AF_INET);
break; break;
#ifdef ENABLE_TUNEMU case 0x86DD:
case DEVICE_TYPE_TUNEMU: type = htonl(AF_INET6);
if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
device, strerror(errno));
return false;
}
break; break;
#endif
default: default:
logger(DEBUG_TRAFFIC, LOG_ERR,
"Unknown address family %x while writing packet to %s %s",
af, device_info, device);
return false; return false;
}
memcpy(DATA(packet) + 10, &type, sizeof(type));
if(write(device_fd, DATA(packet) + 10, packet->len - 10) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Can't write to %s %s: %s", device_info, device,
strerror(errno));
return false;
}
break;
}
case DEVICE_TYPE_TAP:
if(write(device_fd, DATA(packet), packet->len) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
device, strerror(errno));
return false;
}
break;
#ifdef ENABLE_TUNEMU
case DEVICE_TYPE_TUNEMU:
if(tunemu_write(device_fd, DATA(packet) + 14, packet->len - 14) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
device, strerror(errno));
return false;
}
break;
#endif
default:
return false;
} }
return true; return true;

View file

@ -49,24 +49,21 @@
#define PPPIOCCONNECT _IOW('t', 58, int) #define PPPIOCCONNECT _IOW('t', 58, int)
#define PPPIOCGUNIT _IOR('t', 86, int) #define PPPIOCGUNIT _IOR('t', 86, int)
struct sockaddr_ppp struct sockaddr_ppp {
{
u_int8_t ppp_len; u_int8_t ppp_len;
u_int8_t ppp_family; u_int8_t ppp_family;
u_int16_t ppp_proto; u_int16_t ppp_proto;
u_int32_t ppp_cookie; u_int32_t ppp_cookie;
}; };
enum NPmode enum NPmode {
{
NPMODE_PASS, NPMODE_PASS,
NPMODE_DROP, NPMODE_DROP,
NPMODE_ERROR, NPMODE_ERROR,
NPMODE_QUEUE NPMODE_QUEUE
}; };
struct npioctl struct npioctl {
{
int protocol; int protocol;
enum NPmode mode; enum NPmode mode;
}; };
@ -83,58 +80,55 @@ static pcap_t *pcap = NULL;
static int data_buffer_length = 0; static int data_buffer_length = 0;
static char *data_buffer = NULL; static char *data_buffer = NULL;
static void tun_error(char *format, ...) static void tun_error(char *format, ...) {
{
va_list vl; va_list vl;
va_start(vl, format); va_start(vl, format);
vsnprintf(tunemu_error, sizeof tunemu_error, format, vl); vsnprintf(tunemu_error, sizeof(tunemu_error), format, vl);
va_end(vl); va_end(vl);
} }
static void tun_noerror() static void tun_noerror() {
{
*tunemu_error = 0; *tunemu_error = 0;
} }
static void closeall() static void closeall() {
{ int fd = getdtablesize();
int fd = getdtablesize();
while (fd--)
close(fd);
open("/dev/null", O_RDWR, 0); while(fd--) {
dup(0); close(fd);
dup(0); }
open("/dev/null", O_RDWR, 0);
dup(0);
dup(0);
} }
static int ppp_load_kext() static int ppp_load_kext() {
{
int pid = fork(); int pid = fork();
if (pid < 0)
{ if(pid < 0) {
tun_error("fork for ppp kext: %s", strerror(errno)); tun_error("fork for ppp kext: %s", strerror(errno));
return -1; return -1;
} }
if (pid == 0) if(pid == 0) {
{
closeall(); closeall();
execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL);
exit(1); exit(1);
} }
int status; int status;
while (waitpid(pid, &status, 0) < 0)
{ while(waitpid(pid, &status, 0) < 0) {
if (errno == EINTR) if(errno == EINTR) {
continue; continue;
}
tun_error("waitpid for ppp kext: %s", strerror(errno)); tun_error("waitpid for ppp kext: %s", strerror(errno));
return -1; return -1;
} }
if (WEXITSTATUS(status) != 0) if(WEXITSTATUS(status) != 0) {
{
tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH);
return -1; return -1;
} }
@ -143,74 +137,73 @@ static int ppp_load_kext()
return 0; return 0;
} }
static int ppp_new_instance() static int ppp_new_instance() {
{
// create ppp socket // create ppp socket
int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); int ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
if (ppp_sockfd < 0)
{ if(ppp_sockfd < 0) {
if (ppp_load_kext() < 0) if(ppp_load_kext() < 0) {
return -1; return -1;
}
ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL); ppp_sockfd = socket(PF_PPP, SOCK_RAW, PPPPROTO_CTL);
if (ppp_sockfd < 0)
{ if(ppp_sockfd < 0) {
tun_error("creating ppp socket: %s", strerror(errno)); tun_error("creating ppp socket: %s", strerror(errno));
return -1; return -1;
} }
} }
// connect to ppp procotol // connect to ppp procotol
struct sockaddr_ppp pppaddr; struct sockaddr_ppp pppaddr;
pppaddr.ppp_len = sizeof(struct sockaddr_ppp); pppaddr.ppp_len = sizeof(struct sockaddr_ppp);
pppaddr.ppp_family = AF_PPP; pppaddr.ppp_family = AF_PPP;
pppaddr.ppp_proto = PPPPROTO_CTL; pppaddr.ppp_proto = PPPPROTO_CTL;
pppaddr.ppp_cookie = 0; pppaddr.ppp_cookie = 0;
if (connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0)
{ if(connect(ppp_sockfd, (struct sockaddr *)&pppaddr, sizeof(struct sockaddr_ppp)) < 0) {
tun_error("connecting ppp socket: %s", strerror(errno)); tun_error("connecting ppp socket: %s", strerror(errno));
close(ppp_sockfd); close(ppp_sockfd);
return -1; return -1;
} }
tun_noerror(); tun_noerror();
return ppp_sockfd; return ppp_sockfd;
} }
static int ppp_new_unit(int *unit_number) static int ppp_new_unit(int *unit_number) {
{
int fd = ppp_new_instance(); int fd = ppp_new_instance();
if (fd < 0)
if(fd < 0) {
return -1; return -1;
}
// create ppp unit // create ppp unit
if (ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) if(ioctl(fd, PPPIOCNEWUNIT, unit_number) < 0) {
{
tun_error("creating ppp unit: %s", strerror(errno)); tun_error("creating ppp unit: %s", strerror(errno));
close(fd); close(fd);
return -1; return -1;
} }
tun_noerror(); tun_noerror();
return fd; return fd;
} }
static int ppp_setup_unit(int unit_fd) static int ppp_setup_unit(int unit_fd) {
{
// send traffic to program // send traffic to program
int flags = SC_LOOP_TRAFFIC; int flags = SC_LOOP_TRAFFIC;
if (ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0)
{ if(ioctl(unit_fd, PPPIOCSFLAGS, &flags) < 0) {
tun_error("setting ppp loopback mode: %s", strerror(errno)); tun_error("setting ppp loopback mode: %s", strerror(errno));
return -1; return -1;
} }
// allow packets // allow packets
struct npioctl npi; struct npioctl npi;
npi.protocol = PPP_IP; npi.protocol = PPP_IP;
npi.mode = NPMODE_PASS; npi.mode = NPMODE_PASS;
if (ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0)
{ if(ioctl(unit_fd, PPPIOCSNPMODE, &npi) < 0) {
tun_error("starting ppp unit: %s", strerror(errno)); tun_error("starting ppp unit: %s", strerror(errno));
return -1; return -1;
} }
@ -219,10 +212,8 @@ static int ppp_setup_unit(int unit_fd)
return 0; return 0;
} }
static int open_pcap() static int open_pcap() {
{ if(pcap != NULL) {
if (pcap != NULL)
{
pcap_use_count++; pcap_use_count++;
return 0; return 0;
} }
@ -231,8 +222,7 @@ static int open_pcap()
pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf); pcap = pcap_open_live("lo0", BUFSIZ, 0, 1, errbuf);
pcap_use_count = 1; pcap_use_count = 1;
if (pcap == NULL) if(pcap == NULL) {
{
tun_error("opening pcap: %s", errbuf); tun_error("opening pcap: %s", errbuf);
return -1; return -1;
} }
@ -241,59 +231,57 @@ static int open_pcap()
return 0; return 0;
} }
static void close_pcap() static void close_pcap() {
{ if(pcap == NULL) {
if (pcap == NULL)
return; return;
}
pcap_use_count--; pcap_use_count--;
if (pcap_use_count == 0)
{ if(pcap_use_count == 0) {
pcap_close(pcap); pcap_close(pcap);
pcap = NULL; pcap = NULL;
} }
} }
static void allocate_data_buffer(int size) static void allocate_data_buffer(int size) {
{ if(data_buffer_length < size) {
if (data_buffer_length < size)
{
free(data_buffer); free(data_buffer);
data_buffer_length = size; data_buffer_length = size;
data_buffer = malloc(data_buffer_length); data_buffer = malloc(data_buffer_length);
} }
} }
static void make_device_name(tunemu_device device, int unit_number) static void make_device_name(tunemu_device device, int unit_number) {
{
snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number); snprintf(device, sizeof(tunemu_device), "ppp%d", unit_number);
} }
static int check_device_name(tunemu_device device) static int check_device_name(tunemu_device device) {
{ if(strlen(device) < 4) {
if (strlen(device) < 4)
return -1; return -1;
}
int unit_number = atoi(device + 3); int unit_number = atoi(device + 3);
if (unit_number < 0 || unit_number > 999)
if(unit_number < 0 || unit_number > 999) {
return -1; return -1;
}
tunemu_device compare; tunemu_device compare;
make_device_name(compare, unit_number); make_device_name(compare, unit_number);
if (strcmp(device, compare) != 0) if(strcmp(device, compare) != 0) {
return -1; return -1;
}
return 0; return 0;
} }
int tunemu_open(tunemu_device device) int tunemu_open(tunemu_device device) {
{
int ppp_unit_number = -1; int ppp_unit_number = -1;
if (device[0] != 0)
{ if(device[0] != 0) {
if (check_device_name(device) < 0) if(check_device_name(device) < 0) {
{
tun_error("invalid device name \"%s\"", device); tun_error("invalid device name \"%s\"", device);
return -1; return -1;
} }
@ -302,17 +290,17 @@ int tunemu_open(tunemu_device device)
} }
int ppp_unit_fd = ppp_new_unit(&ppp_unit_number); int ppp_unit_fd = ppp_new_unit(&ppp_unit_number);
if (ppp_unit_fd < 0)
return -1;
if (ppp_setup_unit(ppp_unit_fd) < 0) if(ppp_unit_fd < 0) {
{ return -1;
}
if(ppp_setup_unit(ppp_unit_fd) < 0) {
close(ppp_unit_fd); close(ppp_unit_fd);
return -1; return -1;
} }
if (open_pcap() < 0) if(open_pcap() < 0) {
{
close(ppp_unit_fd); close(ppp_unit_fd);
return -1; return -1;
} }
@ -322,39 +310,40 @@ int tunemu_open(tunemu_device device)
return ppp_unit_fd; return ppp_unit_fd;
} }
int tunemu_close(int ppp_sockfd) int tunemu_close(int ppp_sockfd) {
{
int ret = close(ppp_sockfd); int ret = close(ppp_sockfd);
if (ret == 0) if(ret == 0) {
close_pcap(); close_pcap();
}
return ret; return ret;
} }
int tunemu_read(int ppp_sockfd, char *buffer, int length) int tunemu_read(int ppp_sockfd, char *buffer, int length) {
{
allocate_data_buffer(length + 2); allocate_data_buffer(length + 2);
length = read(ppp_sockfd, data_buffer, length + 2); length = read(ppp_sockfd, data_buffer, length + 2);
if (length < 0)
{ if(length < 0) {
tun_error("reading packet: %s", strerror(errno)); tun_error("reading packet: %s", strerror(errno));
return length; return length;
} }
tun_noerror(); tun_noerror();
length -= 2; length -= 2;
if (length < 0)
if(length < 0) {
return 0; return 0;
}
memcpy(buffer, data_buffer + 2, length); memcpy(buffer, data_buffer + 2, length);
return length; return length;
} }
int tunemu_write(int ppp_sockfd, char *buffer, int length) int tunemu_write(int ppp_sockfd, char *buffer, int length) {
{
allocate_data_buffer(length + 4); allocate_data_buffer(length + 4);
data_buffer[0] = 0x02; data_buffer[0] = 0x02;
@ -364,23 +353,25 @@ int tunemu_write(int ppp_sockfd, char *buffer, int length)
memcpy(data_buffer + 4, buffer, length); memcpy(data_buffer + 4, buffer, length);
if (pcap == NULL) if(pcap == NULL) {
{
tun_error("pcap not open"); tun_error("pcap not open");
return -1; return -1;
} }
length = pcap_inject(pcap, data_buffer, length + 4); length = pcap_inject(pcap, data_buffer, length + 4);
if (length < 0)
{ if(length < 0) {
tun_error("injecting packet: %s", pcap_geterr(pcap)); tun_error("injecting packet: %s", pcap_geterr(pcap));
return length; return length;
} }
tun_noerror(); tun_noerror();
length -= 4; length -= 4;
if (length < 0)
if(length < 0) {
return 0; return 0;
}
return length; return length;
} }

View file

@ -22,7 +22,7 @@
#include "buffer.h" #include "buffer.h"
#include "xalloc.h" #include "xalloc.h"
void buffer_compact(buffer_t *buffer, int maxsize) { void buffer_compact(buffer_t *buffer, uint32_t maxsize) {
if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) { if(buffer->len >= maxsize || buffer->offset / 7 > buffer->len / 8) {
memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset); memmove(buffer->data, buffer->data + buffer->offset, buffer->len - buffer->offset);
buffer->len -= buffer->offset; buffer->len -= buffer->offset;
@ -32,7 +32,7 @@ void buffer_compact(buffer_t *buffer, int maxsize) {
// Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes. // Make sure we can add size bytes to the buffer, and return a pointer to the start of those bytes.
char *buffer_prepare(buffer_t *buffer, int size) { char *buffer_prepare(buffer_t *buffer, uint32_t size) {
if(!buffer->data) { if(!buffer->data) {
buffer->maxlen = size; buffer->maxlen = size;
buffer->data = xmalloc(size); buffer->data = xmalloc(size);
@ -58,13 +58,13 @@ char *buffer_prepare(buffer_t *buffer, int size) {
// Copy data into the buffer. // Copy data into the buffer.
void buffer_add(buffer_t *buffer, const char *data, int size) { void buffer_add(buffer_t *buffer, const char *data, uint32_t size) {
memcpy(buffer_prepare(buffer, size), data, size); memcpy(buffer_prepare(buffer, size), data, size);
} }
// Remove given number of bytes from the buffer, return a pointer to the start of them. // Remove given number of bytes from the buffer, return a pointer to the start of them.
static char *buffer_consume(buffer_t *buffer, int size) { static char *buffer_consume(buffer_t *buffer, uint32_t size) {
char *start = buffer->data + buffer->offset; char *start = buffer->data + buffer->offset;
buffer->offset += size; buffer->offset += size;
@ -82,19 +82,21 @@ static char *buffer_consume(buffer_t *buffer, int size) {
char *buffer_readline(buffer_t *buffer) { char *buffer_readline(buffer_t *buffer) {
char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset); char *newline = memchr(buffer->data + buffer->offset, '\n', buffer->len - buffer->offset);
if(!newline) if(!newline) {
return NULL; return NULL;
}
int len = newline + 1 - (buffer->data + buffer->offset); uint32_t len = newline + 1 - (buffer->data + buffer->offset);
*newline = 0; *newline = 0;
return buffer_consume(buffer, len); return buffer_consume(buffer, len);
} }
// Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them. // Check if we have enough bytes in the buffer, and if so, return a pointer to the start of them.
char *buffer_read(buffer_t *buffer, int size) { char *buffer_read(buffer_t *buffer, uint32_t size) {
if(buffer->len - buffer->offset < size) if(buffer->len - buffer->offset < size) {
return NULL; return NULL;
}
return buffer_consume(buffer, size); return buffer_consume(buffer, size);
} }

View file

@ -1,18 +1,18 @@
#ifndef __TINC_BUFFER_H__ #ifndef TINC_BUFFER_H
#define __TINC_BUFFER_H__ #define TINC_BUFFER_H
typedef struct buffer_t { typedef struct buffer_t {
char *data; char *data;
int maxlen; uint32_t maxlen;
int len; uint32_t len;
int offset; uint32_t offset;
} buffer_t; } buffer_t;
extern void buffer_compact(buffer_t *buffer, int maxsize); extern void buffer_compact(buffer_t *buffer, uint32_t maxsize);
extern char *buffer_prepare(buffer_t *buffer, int size); extern char *buffer_prepare(buffer_t *buffer, uint32_t size);
extern void buffer_add(buffer_t *buffer, const char *data, int size); extern void buffer_add(buffer_t *buffer, const char *data, uint32_t size);
extern char *buffer_readline(buffer_t *buffer); extern char *buffer_readline(buffer_t *buffer);
extern char *buffer_read(buffer_t *buffer, int size); extern char *buffer_read(buffer_t *buffer, uint32_t size);
extern void buffer_clear(buffer_t *buffer); extern void buffer_clear(buffer_t *buffer);
#endif #endif

View file

@ -11,42 +11,40 @@ struct chacha_poly1305_ctx {
struct chacha_ctx main_ctx, header_ctx; struct chacha_ctx main_ctx, header_ctx;
}; };
chacha_poly1305_ctx_t *chacha_poly1305_init(void) chacha_poly1305_ctx_t *chacha_poly1305_init(void) {
{ chacha_poly1305_ctx_t *ctx = xzalloc(sizeof(*ctx));
chacha_poly1305_ctx_t *ctx = xzalloc(sizeof *ctx);
return ctx; return ctx;
} }
void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) {
{
free(ctx); free(ctx);
} }
bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *vkey) {
{ const uint8_t *key = vkey;
chacha_keysetup(&ctx->main_ctx, key, 256); chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256); chacha_keysetup(&ctx->header_ctx, key + 32, 256);
return true; return true;
} }
static void put_u64(void *vp, uint64_t v) static void put_u64(void *vp, uint64_t v) {
{
uint8_t *p = (uint8_t *) vp; uint8_t *p = (uint8_t *) vp;
p[0] = (uint8_t) (v >> 56) & 0xff; p[0] = (uint8_t)(v >> 56) & 0xff;
p[1] = (uint8_t) (v >> 48) & 0xff; p[1] = (uint8_t)(v >> 48) & 0xff;
p[2] = (uint8_t) (v >> 40) & 0xff; p[2] = (uint8_t)(v >> 40) & 0xff;
p[3] = (uint8_t) (v >> 32) & 0xff; p[3] = (uint8_t)(v >> 32) & 0xff;
p[4] = (uint8_t) (v >> 24) & 0xff; p[4] = (uint8_t)(v >> 24) & 0xff;
p[5] = (uint8_t) (v >> 16) & 0xff; p[5] = (uint8_t)(v >> 16) & 0xff;
p[6] = (uint8_t) (v >> 8) & 0xff; p[6] = (uint8_t)(v >> 8) & 0xff;
p[7] = (uint8_t) v & 0xff; p[7] = (uint8_t) v & 0xff;
} }
bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *voutdata, size_t *outlen) {
uint8_t seqbuf[8]; uint8_t seqbuf[8];
const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
uint8_t poly_key[POLY1305_KEYLEN]; uint8_t poly_key[POLY1305_KEYLEN];
uint8_t *outdata = voutdata;
/* /*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the * Run ChaCha20 once to generate the Poly1305 key. The IV is the
@ -63,16 +61,18 @@ bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
poly1305_auth(outdata + inlen, outdata, inlen, poly_key); poly1305_auth(outdata + inlen, outdata, inlen, poly_key);
if (outlen) if(outlen) {
*outlen = inlen + POLY1305_TAGLEN; *outlen = inlen + POLY1305_TAGLEN;
}
return true; return true;
} }
bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *indata, size_t inlen, void *outdata, size_t *outlen) { bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const void *vindata, size_t inlen, void *outdata, size_t *outlen) {
uint8_t seqbuf[8]; uint8_t seqbuf[8];
const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */ const uint8_t one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
const uint8_t *indata = vindata;
/* /*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the * Run ChaCha20 once to generate the Poly1305 key. The IV is the
@ -91,13 +91,16 @@ bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v
const uint8_t *tag = indata + inlen; const uint8_t *tag = indata + inlen;
poly1305_auth(expected_tag, indata, inlen, poly_key); poly1305_auth(expected_tag, indata, inlen, poly_key);
if (memcmp(expected_tag, tag, POLY1305_TAGLEN))
if(memcmp(expected_tag, tag, POLY1305_TAGLEN)) {
return false; return false;
}
chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen);
if (outlen) if(outlen) {
*outlen = inlen; *outlen = inlen;
}
return true; return true;
} }

View file

@ -47,20 +47,21 @@ typedef struct chacha_ctx chacha_ctx;
static const char sigma[16] = "expand 32-byte k"; static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k"; static const char tau[16] = "expand 16-byte k";
void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits) {
{
const char *constants; const char *constants;
x->input[4] = U8TO32_LITTLE(k + 0); x->input[4] = U8TO32_LITTLE(k + 0);
x->input[5] = U8TO32_LITTLE(k + 4); x->input[5] = U8TO32_LITTLE(k + 4);
x->input[6] = U8TO32_LITTLE(k + 8); x->input[6] = U8TO32_LITTLE(k + 8);
x->input[7] = U8TO32_LITTLE(k + 12); x->input[7] = U8TO32_LITTLE(k + 12);
if (kbits == 256) { /* recommended */
if(kbits == 256) { /* recommended */
k += 16; k += 16;
constants = sigma; constants = sigma;
} else { /* kbits == 128 */ } else { /* kbits == 128 */
constants = tau; constants = tau;
} }
x->input[8] = U8TO32_LITTLE(k + 0); x->input[8] = U8TO32_LITTLE(k + 0);
x->input[9] = U8TO32_LITTLE(k + 4); x->input[9] = U8TO32_LITTLE(k + 4);
x->input[10] = U8TO32_LITTLE(k + 8); x->input[10] = U8TO32_LITTLE(k + 8);
@ -71,8 +72,7 @@ void chacha_keysetup(chacha_ctx *x, const uint8_t *k, uint32_t kbits)
x->input[3] = U8TO32_LITTLE(constants + 12); x->input[3] = U8TO32_LITTLE(constants + 12);
} }
void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter) {
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->input[14] = U8TO32_LITTLE(iv + 0); x->input[14] = U8TO32_LITTLE(iv + 0);
@ -80,16 +80,16 @@ void chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter)
} }
void void
chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes) {
{
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
uint8_t *ctarget = NULL; uint8_t *ctarget = NULL;
uint8_t tmp[64]; uint8_t tmp[64];
uint32_t i; uint32_t i;
if (!bytes) if(!bytes) {
return; return;
}
j0 = x->input[0]; j0 = x->input[0];
j1 = x->input[1]; j1 = x->input[1];
@ -108,14 +108,17 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
j14 = x->input[14]; j14 = x->input[14];
j15 = x->input[15]; j15 = x->input[15];
for (;;) { for(;;) {
if (bytes < 64) { if(bytes < 64) {
for (i = 0; i < bytes; ++i) for(i = 0; i < bytes; ++i) {
tmp[i] = m[i]; tmp[i] = m[i];
}
m = tmp; m = tmp;
ctarget = c; ctarget = c;
c = tmp; c = tmp;
} }
x0 = j0; x0 = j0;
x1 = j1; x1 = j1;
x2 = j2; x2 = j2;
@ -132,7 +135,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
x13 = j13; x13 = j13;
x14 = j14; x14 = j14;
x15 = j15; x15 = j15;
for (i = 20; i > 0; i -= 2) {
for(i = 20; i > 0; i -= 2) {
QUARTERROUND(x0, x4, x8, x12) QUARTERROUND(x0, x4, x8, x12)
QUARTERROUND(x1, x5, x9, x13) QUARTERROUND(x1, x5, x9, x13)
QUARTERROUND(x2, x6, x10, x14) QUARTERROUND(x2, x6, x10, x14)
@ -142,6 +146,7 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
QUARTERROUND(x2, x7, x8, x13) QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14) QUARTERROUND(x3, x4, x9, x14)
} }
x0 = PLUS(x0, j0); x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1); x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2); x2 = PLUS(x2, j2);
@ -177,7 +182,8 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
x15 = XOR(x15, U8TO32_LITTLE(m + 60)); x15 = XOR(x15, U8TO32_LITTLE(m + 60));
j12 = PLUSONE(j12); j12 = PLUSONE(j12);
if (!j12) {
if(!j12) {
j13 = PLUSONE(j13); j13 = PLUSONE(j13);
/* stopping at 2^70 bytes per nonce is user's responsibility */ /* stopping at 2^70 bytes per nonce is user's responsibility */
} }
@ -199,15 +205,18 @@ chacha_encrypt_bytes(chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes
U32TO8_LITTLE(c + 56, x14); U32TO8_LITTLE(c + 56, x14);
U32TO8_LITTLE(c + 60, x15); U32TO8_LITTLE(c + 60, x15);
if (bytes <= 64) { if(bytes <= 64) {
if (bytes < 64) { if(bytes < 64) {
for (i = 0; i < bytes; ++i) for(i = 0; i < bytes; ++i) {
ctarget[i] = c[i]; ctarget[i] = c[i];
}
} }
x->input[12] = j12; x->input[12] = j12;
x->input[13] = j13; x->input[13] = j13;
return; return;
} }
bytes -= 64; bytes -= 64;
c += 64; c += 64;
m += 64; m += 64;

View file

@ -11,14 +11,14 @@ struct chacha_ctx {
uint32_t input[16]; uint32_t input[16];
}; };
#define CHACHA_MINKEYLEN 16 #define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8 #define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8 #define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) #define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64 #define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits); void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits);
void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr); void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t * c, uint32_t bytes); void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, uint32_t bytes);
#endif /* CHACHA_H */ #endif /* CHACHA_H */

View file

@ -1,4 +1,4 @@
/* /*
* Public Domain poly1305 from Andrew Moon * Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
*/ */
@ -24,8 +24,7 @@
} while (0) } while (0)
void void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
{
uint32_t t0, t1, t2, t3; uint32_t t0, t1, t2, t3;
uint32_t h0, h1, h2, h3, h4; uint32_t h0, h1, h2, h3, h4;
uint32_t r0, r1, r2, r3, r4; uint32_t r0, r1, r2, r3, r4;
@ -71,10 +70,11 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
h4 = 0; h4 = 0;
/* full blocks */ /* full blocks */
if (inlen < 16) if(inlen < 16) {
goto poly1305_donna_atmost15bytes; goto poly1305_donna_atmost15bytes;
}
poly1305_donna_16bytes: poly1305_donna_16bytes:
m += 16; m += 16;
inlen -= 16; inlen -= 16;
@ -89,7 +89,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff; h3 += ((((uint64_t) t3 << 32) | t2) >> 14) & 0x3ffffff;
h4 += (t3 >> 8) | (1 << 24); h4 += (t3 >> 8) | (1 << 24);
poly1305_donna_mul: poly1305_donna_mul:
t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1); t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2); t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3); t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
@ -100,31 +100,39 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
c = (t[0] >> 26); c = (t[0] >> 26);
t[1] += c; t[1] += c;
h1 = (uint32_t) t[1] & 0x3ffffff; h1 = (uint32_t) t[1] & 0x3ffffff;
b = (uint32_t) (t[1] >> 26); b = (uint32_t)(t[1] >> 26);
t[2] += b; t[2] += b;
h2 = (uint32_t) t[2] & 0x3ffffff; h2 = (uint32_t) t[2] & 0x3ffffff;
b = (uint32_t) (t[2] >> 26); b = (uint32_t)(t[2] >> 26);
t[3] += b; t[3] += b;
h3 = (uint32_t) t[3] & 0x3ffffff; h3 = (uint32_t) t[3] & 0x3ffffff;
b = (uint32_t) (t[3] >> 26); b = (uint32_t)(t[3] >> 26);
t[4] += b; t[4] += b;
h4 = (uint32_t) t[4] & 0x3ffffff; h4 = (uint32_t) t[4] & 0x3ffffff;
b = (uint32_t) (t[4] >> 26); b = (uint32_t)(t[4] >> 26);
h0 += b * 5; h0 += b * 5;
if (inlen >= 16) if(inlen >= 16) {
goto poly1305_donna_16bytes; goto poly1305_donna_16bytes;
}
/* final bytes */ /* final bytes */
poly1305_donna_atmost15bytes: poly1305_donna_atmost15bytes:
if (!inlen)
goto poly1305_donna_finish;
for (j = 0; j < inlen; j++) if(!inlen) {
goto poly1305_donna_finish;
}
for(j = 0; j < inlen; j++) {
mp[j] = m[j]; mp[j] = m[j];
}
mp[j++] = 1; mp[j++] = 1;
for (; j < 16; j++)
for(; j < 16; j++) {
mp[j] = 0; mp[j] = 0;
}
inlen = 0; inlen = 0;
t0 = U8TO32_LE(mp + 0); t0 = U8TO32_LE(mp + 0);
@ -140,7 +148,7 @@ poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t
goto poly1305_donna_mul; goto poly1305_donna_mul;
poly1305_donna_finish: poly1305_donna_finish:
b = h0 >> 26; b = h0 >> 26;
h0 = h0 & 0x3ffffff; h0 = h0 & 0x3ffffff;
h1 += b; h1 += b;

View file

@ -1,6 +1,6 @@
/* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */ /* $OpenBSD: poly1305.h,v 1.2 2013/12/19 22:57:13 djm Exp $ */
/* /*
* Public Domain poly1305 from Andrew Moon * Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
*/ */
@ -8,9 +8,9 @@
#ifndef POLY1305_H #ifndef POLY1305_H
#define POLY1305_H #define POLY1305_H
#define POLY1305_KEYLEN 32 #define POLY1305_KEYLEN 32
#define POLY1305_TAGLEN 16 #define POLY1305_TAGLEN 16
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]); void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, const uint8_t key[POLY1305_KEYLEN]);
#endif /* POLY1305_H */ #endif /* POLY1305_H */

View file

@ -1,3 +1,6 @@
#ifndef TINC_CIPHER_H
#define TINC_CIPHER_H
/* /*
cipher.h -- header file cipher.c cipher.h -- header file cipher.c
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CIPHER_H__
#define __TINC_CIPHER_H__
#define CIPHER_MAX_BLOCK_SIZE 32 #define CIPHER_MAX_BLOCK_SIZE 32
#define CIPHER_MAX_IV_SIZE 16 #define CIPHER_MAX_IV_SIZE 16
#define CIPHER_MAX_KEY_SIZE 32 #define CIPHER_MAX_KEY_SIZE 32
@ -28,19 +28,18 @@
typedef struct cipher cipher_t; typedef struct cipher cipher_t;
extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); extern cipher_t *cipher_open_by_name(const char *name) __attribute__((__malloc__));
extern cipher_t *cipher_open_by_nid(int) __attribute__ ((__malloc__)); extern cipher_t *cipher_open_by_nid(int nid) __attribute__((__malloc__));
extern void cipher_close(cipher_t *); extern void cipher_close(cipher_t *cipher);
extern size_t cipher_keylength(const cipher_t *); extern size_t cipher_keylength(const cipher_t *cipher);
extern size_t cipher_blocksize(const cipher_t *); extern size_t cipher_blocksize(const cipher_t *cipher);
extern uint64_t cipher_budget(const cipher_t *); extern uint64_t cipher_budget(const cipher_t *cipher);
extern void cipher_get_key(const cipher_t *, void *); extern bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) __attribute__((__warn_unused_result__));
extern bool cipher_set_key(cipher_t *, void *, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_set_key_from_rsa(cipher_t *cipher, void *rsa, size_t len, bool encrypt) __attribute__((__warn_unused_result__));
extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool) __attribute__ ((__warn_unused_result__)); extern bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__));
extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); extern bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__((__warn_unused_result__));
extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) __attribute__ ((__warn_unused_result__)); extern int cipher_get_nid(const cipher_t *cipher);
extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *cipher);
extern bool cipher_active(const cipher_t *);
#endif #endif

View file

@ -46,27 +46,31 @@ static int config_compare(const config_t *a, const config_t *b) {
result = strcasecmp(a->variable, b->variable); result = strcasecmp(a->variable, b->variable);
if(result) if(result) {
return result; return result;
}
/* give priority to command line options */ /* give priority to command line options */
result = !b->file - !a->file; result = !b->file - !a->file;
if (result)
if(result) {
return result; return result;
}
result = a->line - b->line; result = a->line - b->line;
if(result) if(result) {
return result; return result;
else } else {
return a->file ? strcmp(a->file, b->file) : 0; return a->file ? strcmp(a->file, b->file) : 0;
}
} }
void init_configuration(splay_tree_t ** config_tree) { void init_configuration(splay_tree_t **config_tree) {
*config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config); *config_tree = splay_alloc_tree((splay_compare_t) config_compare, (splay_action_t) free_config);
} }
void exit_configuration(splay_tree_t ** config_tree) { void exit_configuration(splay_tree_t **config_tree) {
splay_delete_tree(*config_tree); splay_delete_tree(*config_tree);
*config_tree = NULL; *config_tree = NULL;
} }
@ -76,15 +80,9 @@ config_t *new_config(void) {
} }
void free_config(config_t *cfg) { void free_config(config_t *cfg) {
if(cfg->variable) free(cfg->variable);
free(cfg->variable); free(cfg->value);
free(cfg->file);
if(cfg->value)
free(cfg->value);
if(cfg->file)
free(cfg->file);
free(cfg); free(cfg);
} }
@ -101,11 +99,13 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) {
found = splay_search_closest_greater(config_tree, &cfg); found = splay_search_closest_greater(config_tree, &cfg);
if(!found) if(!found) {
return NULL; return NULL;
}
if(strcasecmp(found->variable, variable)) if(strcasecmp(found->variable, variable)) {
return NULL; return NULL;
}
return found; return found;
} }
@ -120,8 +120,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) {
if(node->next) { if(node->next) {
found = node->next->data; found = node->next->data;
if(!strcasecmp(found->variable, cfg->variable)) if(!strcasecmp(found->variable, cfg->variable)) {
return found; return found;
}
} }
} }
@ -129,8 +130,9 @@ config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *cfg) {
} }
bool get_config_bool(const config_t *cfg, bool *result) { bool get_config_bool(const config_t *cfg, bool *result) {
if(!cfg) if(!cfg) {
return false; return false;
}
if(!strcasecmp(cfg->value, "yes")) { if(!strcasecmp(cfg->value, "yes")) {
*result = true; *result = true;
@ -141,27 +143,30 @@ bool get_config_bool(const config_t *cfg, bool *result) {
} }
logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d", logger(DEBUG_ALWAYS, LOG_ERR, "\"yes\" or \"no\" expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return false; return false;
} }
bool get_config_int(const config_t *cfg, int *result) { bool get_config_int(const config_t *cfg, int *result) {
if(!cfg) if(!cfg) {
return false; return false;
}
if(sscanf(cfg->value, "%d", result) == 1) if(sscanf(cfg->value, "%d", result) == 1) {
return true; return true;
}
logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d", logger(DEBUG_ALWAYS, LOG_ERR, "Integer expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return false; return false;
} }
bool get_config_string(const config_t *cfg, char **result) { bool get_config_string(const config_t *cfg, char **result) {
if(!cfg) if(!cfg) {
return false; return false;
}
*result = xstrdup(cfg->value); *result = xstrdup(cfg->value);
@ -171,8 +176,9 @@ bool get_config_string(const config_t *cfg, char **result) {
bool get_config_address(const config_t *cfg, struct addrinfo **result) { bool get_config_address(const config_t *cfg, struct addrinfo **result) {
struct addrinfo *ai; struct addrinfo *ai;
if(!cfg) if(!cfg) {
return false; return false;
}
ai = str2addrinfo(cfg->value, NULL, 0); ai = str2addrinfo(cfg->value, NULL, 0);
@ -182,31 +188,32 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) {
} }
logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d", logger(DEBUG_ALWAYS, LOG_ERR, "Hostname or IP address expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return false; return false;
} }
bool get_config_subnet(const config_t *cfg, subnet_t ** result) { bool get_config_subnet(const config_t *cfg, subnet_t **result) {
subnet_t subnet = {NULL}; subnet_t subnet = {0};
if(!cfg) if(!cfg) {
return false; return false;
}
if(!str2net(&subnet, cfg->value)) { if(!str2net(&subnet, cfg->value)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d", logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return false; return false;
} }
/* Teach newbies what subnets are... */ /* Teach newbies what subnets are... */
if(((subnet.type == SUBNET_IPV4) if(((subnet.type == SUBNET_IPV4)
&& !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address)) && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address)))
|| ((subnet.type == SUBNET_IPV6) || ((subnet.type == SUBNET_IPV6)
&& !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) { && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return false; return false;
} }
@ -218,27 +225,32 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
/* /*
Read exactly one line and strip the trailing newline if any. Read exactly one line and strip the trailing newline if any.
*/ */
static char *readline(FILE * fp, char *buf, size_t buflen) { static char *readline(FILE *fp, char *buf, size_t buflen) {
char *newline = NULL; char *newline = NULL;
char *p; char *p;
if(feof(fp)) if(feof(fp)) {
return NULL; return NULL;
}
p = fgets(buf, buflen, fp); p = fgets(buf, buflen, fp);
if(!p) if(!p) {
return NULL; return NULL;
}
newline = strchr(p, '\n'); newline = strchr(p, '\n');
if(!newline) if(!newline) {
return buf; return buf;
}
/* kill newline and carriage return if necessary */ /* kill newline and carriage return if necessary */
*newline = '\0'; *newline = '\0';
if(newline > p && newline[-1] == '\r')
if(newline > p && newline[-1] == '\r') {
newline[-1] = '\0'; newline[-1] = '\0';
}
return buf; return buf;
} }
@ -250,26 +262,32 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) {
variable = value = line; variable = value = line;
eol = line + strlen(line); eol = line + strlen(line);
while(strchr("\t ", *--eol))
while(strchr("\t ", *--eol)) {
*eol = '\0'; *eol = '\0';
}
len = strcspn(value, "\t ="); len = strcspn(value, "\t =");
value += len; value += len;
value += strspn(value, "\t "); value += strspn(value, "\t ");
if(*value == '=') { if(*value == '=') {
value++; value++;
value += strspn(value, "\t "); value += strspn(value, "\t ");
} }
variable[len] = '\0'; variable[len] = '\0';
if(!*value) { if(!*value) {
const char err[] = "No value for variable"; const char err[] = "No value for variable";
if (fname)
if(fname)
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s", logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' on line %d while reading config file %s",
err, variable, lineno, fname); err, variable, lineno, fname);
else else
logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d", logger(DEBUG_ALWAYS, LOG_ERR, "%s `%s' in command line option %d",
err, variable, lineno); err, variable, lineno);
return NULL; return NULL;
} }
@ -286,7 +304,7 @@ config_t *parse_config_line(char *line, const char *fname, int lineno) {
Parse a configuration file and put the results in the configuration tree Parse a configuration file and put the results in the configuration tree
starting at *base. starting at *base.
*/ */
bool read_config_file(splay_tree_t *config_tree, const char *fname) { bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose) {
FILE *fp; FILE *fp;
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
char *line; char *line;
@ -298,27 +316,32 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(!fp) { if(!fp) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Cannot open config file %s: %s", fname, strerror(errno)); logger(verbose ? DEBUG_ALWAYS : DEBUG_CONNECTIONS, LOG_ERR, "Cannot open config file %s: %s", fname, strerror(errno));
return false; return false;
} }
for(;;) { for(;;) {
line = readline(fp, buffer, sizeof buffer); line = readline(fp, buffer, sizeof(buffer));
if(!line) { if(!line) {
if(feof(fp)) if(feof(fp)) {
result = true; result = true;
}
break; break;
} }
lineno++; lineno++;
if(!*line || *line == '#') if(!*line || *line == '#') {
continue; continue;
}
if(ignore) { if(ignore) {
if(!strncmp(line, "-----END", 8)) if(!strncmp(line, "-----END", 8)) {
ignore = false; ignore = false;
}
continue; continue;
} }
@ -328,8 +351,11 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname) {
} }
cfg = parse_config_line(line, fname, lineno); cfg = parse_config_line(line, fname, lineno);
if (!cfg)
if(!cfg) {
break; break;
}
config_add(config_tree, cfg); config_add(config_tree, cfg);
} }
@ -346,19 +372,24 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) {
config_t *new; config_t *new;
if(!prefix) { if(!prefix) {
if(strchr(cfg->variable, '.')) if(strchr(cfg->variable, '.')) {
continue; continue;
}
} else { } else {
if(strncmp(prefix, cfg->variable, prefix_len) || if(strncmp(prefix, cfg->variable, prefix_len) ||
cfg->variable[prefix_len] != '.') cfg->variable[prefix_len] != '.') {
continue; continue;
}
} }
new = new_config(); new = new_config();
if(prefix)
if(prefix) {
new->variable = xstrdup(cfg->variable + prefix_len + 1); new->variable = xstrdup(cfg->variable + prefix_len + 1);
else } else {
new->variable = xstrdup(cfg->variable); new->variable = xstrdup(cfg->variable);
}
new->value = xstrdup(cfg->value); new->value = xstrdup(cfg->value);
new->file = NULL; new->file = NULL;
new->line = cfg->line; new->line = cfg->line;
@ -373,52 +404,57 @@ bool read_server_config(void) {
read_config_options(config_tree, NULL); read_config_options(config_tree, NULL);
snprintf(fname, sizeof fname, "%s" SLASH "tinc.conf", confbase); snprintf(fname, sizeof(fname), "%s" SLASH "tinc.conf", confbase);
errno = 0; errno = 0;
x = read_config_file(config_tree, fname); x = read_config_file(config_tree, fname, true);
// We will try to read the conf files in the "conf.d" dir // We will try to read the conf files in the "conf.d" dir
if (x) { if(x) {
char dname[PATH_MAX]; char dname[PATH_MAX];
snprintf(dname, sizeof dname, "%s" SLASH "conf.d", confbase); snprintf(dname, sizeof(dname), "%s" SLASH "conf.d", confbase);
DIR *dir = opendir (dname); DIR *dir = opendir(dname);
// If we can find this dir // If we can find this dir
if (dir) { if(dir) {
struct dirent *ep; struct dirent *ep;
// We list all the files in it // We list all the files in it
while (x && (ep = readdir (dir))) { while(x && (ep = readdir(dir))) {
size_t l = strlen(ep->d_name); size_t l = strlen(ep->d_name);
// And we try to read the ones that end with ".conf" // And we try to read the ones that end with ".conf"
if (l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) { if(l > 5 && !strcmp(".conf", & ep->d_name[ l - 5 ])) {
snprintf(fname, sizeof fname, "%s" SLASH "%s", dname, ep->d_name); if((size_t)snprintf(fname, sizeof(fname), "%s" SLASH "%s", dname, ep->d_name) >= sizeof(fname)) {
x = read_config_file(config_tree, fname); logger(DEBUG_ALWAYS, LOG_ERR, "Pathname too long: %s/%s", dname, ep->d_name);
return false;
}
x = read_config_file(config_tree, fname, true);
} }
} }
closedir (dir);
closedir(dir);
} }
} }
if(!x && errno) if(!x && errno) {
logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno));
}
return x; return x;
} }
bool read_host_config(splay_tree_t *config_tree, const char *name) { bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose) {
char fname[PATH_MAX];
bool x;
read_config_options(config_tree, name); read_config_options(config_tree, name);
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); char fname[PATH_MAX];
x = read_config_file(config_tree, fname); snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
return read_config_file(config_tree, fname, verbose);
return x;
} }
bool append_config_file(const char *name, const char *key, const char *value) { bool append_config_file(const char *name, const char *key, const char *value) {
char fname[PATH_MAX]; char fname[PATH_MAX];
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, name); snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, name);
FILE *fp = fopen(fname, "a"); FILE *fp = fopen(fname, "a");

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONF_H
#define TINC_CONF_H
/* /*
conf.h -- header for conf.c conf.h -- header for conf.c
Copyright (C) 1998-2005 Ivo Timmermans Copyright (C) 1998-2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CONF_H__
#define __TINC_CONF_H__
#include "list.h" #include "list.h"
#include "splay_tree.h" #include "splay_tree.h"
#include "subnet.h" #include "subnet.h"
@ -41,24 +41,24 @@ extern int maxtimeout;
extern bool bypass_security; extern bool bypass_security;
extern list_t *cmdline_conf; extern list_t *cmdline_conf;
extern void init_configuration(splay_tree_t **); extern void init_configuration(splay_tree_t **config_tree);
extern void exit_configuration(splay_tree_t **); extern void exit_configuration(splay_tree_t **config_tree);
extern config_t *new_config(void) __attribute__ ((__malloc__)); extern config_t *new_config(void) __attribute__((__malloc__));
extern void free_config(config_t *); extern void free_config(config_t *config);
extern void config_add(splay_tree_t *, config_t *); extern void config_add(splay_tree_t *config_tree, config_t *config);
extern config_t *lookup_config(splay_tree_t *, char *); extern config_t *lookup_config(splay_tree_t *config_tree, char *variable);
extern config_t *lookup_config_next(splay_tree_t *, const config_t *); extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config);
extern bool get_config_bool(const config_t *, bool *); extern bool get_config_bool(const config_t *config, bool *result);
extern bool get_config_int(const config_t *, int *); extern bool get_config_int(const config_t *config, int *result);
extern bool get_config_string(const config_t *, char **); extern bool get_config_string(const config_t *config, char **result);
extern bool get_config_address(const config_t *, struct addrinfo **); extern bool get_config_address(const config_t *config, struct addrinfo **result);
extern bool get_config_subnet(const config_t *, struct subnet_t **); extern bool get_config_subnet(const config_t *config, struct subnet_t **result);
extern config_t *parse_config_line(char *, const char *, int); extern config_t *parse_config_line(char *line, const char *fname, int lineno);
extern bool read_config_file(splay_tree_t *, const char *); extern bool read_config_file(splay_tree_t *config_tree, const char *filename, bool verbose);
extern void read_config_options(splay_tree_t *, const char *); extern void read_config_options(splay_tree_t *config_tree, const char *prefix);
extern bool read_server_config(void); extern bool read_server_config(void);
extern bool read_host_config(splay_tree_t *, const char *); extern bool read_host_config(splay_tree_t *config_tree, const char *name, bool verbose);
extern bool append_config_file(const char *, const char *, const char *); extern bool append_config_file(const char *name, const char *key, const char *value);
#endif /* __TINC_CONF_H__ */ #endif

View file

@ -27,6 +27,7 @@
#include "control_common.h" #include "control_common.h"
#include "list.h" #include "list.h"
#include "logger.h" #include "logger.h"
#include "net.h"
#include "rsa.h" #include "rsa.h"
#include "subnet.h" #include "subnet.h"
#include "utils.h" #include "utils.h"
@ -52,8 +53,9 @@ connection_t *new_connection(void) {
} }
void free_connection(connection_t *c) { void free_connection(connection_t *c) {
if(!c) if(!c) {
return; return;
}
#ifndef DISABLE_LEGACY #ifndef DISABLE_LEGACY
cipher_close(c->incipher); cipher_close(c->incipher);
@ -67,20 +69,27 @@ void free_connection(connection_t *c) {
ecdsa_free(c->ecdsa); ecdsa_free(c->ecdsa);
free(c->hischallenge); free(c->hischallenge);
free(c->mychallenge);
buffer_clear(&c->inbuf); buffer_clear(&c->inbuf);
buffer_clear(&c->outbuf); buffer_clear(&c->outbuf);
io_del(&c->io); io_del(&c->io);
if(c->socket > 0) if(c->socket > 0) {
closesocket(c->socket); if(c->status.tarpit) {
tarpit(c->socket);
} else {
closesocket(c->socket);
}
}
free(c->name); free(c->name);
free(c->hostname); free(c->hostname);
if(c->config_tree) if(c->config_tree) {
exit_configuration(&c->config_tree); exit_configuration(&c->config_tree);
}
free(c); free(c);
} }
@ -96,9 +105,9 @@ void connection_del(connection_t *c) {
bool dump_connections(connection_t *cdump) { bool dump_connections(connection_t *cdump) {
for list_each(connection_t, c, connection_list) { for list_each(connection_t, c, connection_list) {
send_request(cdump, "%d %d %s %s %x %d %x", send_request(cdump, "%d %d %s %s %x %d %x",
CONTROL, REQ_DUMP_CONNECTIONS, CONTROL, REQ_DUMP_CONNECTIONS,
c->name, c->hostname, c->options, c->socket, c->name, c->hostname, c->options, c->socket,
bitfield_to_int(&c->status, sizeof c->status)); bitfield_to_int(&c->status, sizeof(c->status)));
} }
return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS); return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONNECTION_H
#define TINC_CONNECTION_H
/* /*
connection.h -- header for connection.c connection.h -- header for connection.c
Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>, Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CONNECTION_H__
#define __TINC_CONNECTION_H__
#include "buffer.h" #include "buffer.h"
#include "cipher.h" #include "cipher.h"
#include "digest.h" #include "digest.h"
@ -35,21 +35,22 @@
#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */ #define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
typedef struct connection_status_t { typedef struct connection_status_t {
unsigned int pinged:1; /* sent ping */ unsigned int pinged: 1; /* sent ping */
unsigned int unused_active:1; unsigned int unused_active: 1;
unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */ unsigned int connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */
unsigned int unused_termreq:1; /* the termination of this connection was requested */ unsigned int unused_termreq: 1; /* the termination of this connection was requested */
unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */ unsigned int remove_unused: 1; /* Set to 1 if you want this connection removed */
unsigned int timeout_unused:1; /* 1 if gotten timeout */ unsigned int timeout_unused: 1; /* 1 if gotten timeout */
unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */ unsigned int encryptout: 1; /* 1 if we can encrypt outgoing traffic */
unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */ unsigned int decryptin: 1; /* 1 if we have to decrypt incoming traffic */
unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */ unsigned int mst: 1; /* 1 if this connection is part of a minimum spanning tree */
unsigned int control:1; /* 1 if this is a control connection */ unsigned int control: 1; /* 1 if this is a control connection */
unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */ unsigned int pcap: 1; /* 1 if this is a control connection requesting packet capture */
unsigned int log:1; /* 1 if this is a control connection requesting log dump */ unsigned int log: 1; /* 1 if this is a control connection requesting log dump */
unsigned int invitation:1; /* 1 if this is an invitation */ unsigned int invitation: 1; /* 1 if this is an invitation */
unsigned int invitation_used:1; /* 1 if the invitation has been consumed */ unsigned int invitation_used: 1; /* 1 if the invitation has been consumed */
unsigned int unused:18; unsigned int tarpit: 1; /* 1 if the connection should be added to the tarpit */
unsigned int unused: 17;
} connection_status_t; } connection_status_t;
#include "ecdsa.h" #include "ecdsa.h"
@ -94,12 +95,13 @@ typedef struct connection_t {
int outcompression; int outcompression;
char *hischallenge; /* The challenge we sent to him */ char *hischallenge; /* The challenge we sent to him */
char *mychallenge; /* The challenge we received */
struct buffer_t inbuf; struct buffer_t inbuf;
struct buffer_t outbuf; struct buffer_t outbuf;
io_t io; /* input/output event on this metadata connection */ io_t io; /* input/output event on this metadata connection */
int tcplen; /* length of incoming TCPpacket */ int tcplen; /* length of incoming TCPpacket */
int sptpslen; /* length of incoming SPTPS packet */ int sptpslen; /* length of incoming SPTPS packet */
int allow_request; /* defined if there's only one request possible */ int allow_request; /* defined if there's only one request possible */
time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */ time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
@ -112,10 +114,10 @@ extern connection_t *everyone;
extern void init_connections(void); extern void init_connections(void);
extern void exit_connections(void); extern void exit_connections(void);
extern connection_t *new_connection(void) __attribute__ ((__malloc__)); extern connection_t *new_connection(void) __attribute__((__malloc__));
extern void free_connection(connection_t *); extern void free_connection(connection_t *c);
extern void connection_add(connection_t *); extern void connection_add(connection_t *c);
extern void connection_del(connection_t *); extern void connection_del(connection_t *c);
extern bool dump_connections(struct connection_t *); extern bool dump_connections(struct connection_t *c);
#endif /* __TINC_CONNECTION_H__ */ #endif

View file

@ -56,86 +56,95 @@ bool control_h(connection_t *c, const char *request) {
return false; return false;
} }
switch (type) { switch(type) {
case REQ_STOP: case REQ_STOP:
event_exit(); event_exit();
return control_ok(c, REQ_STOP); return control_ok(c, REQ_STOP);
case REQ_DUMP_NODES: case REQ_DUMP_NODES:
return dump_nodes(c); return dump_nodes(c);
case REQ_DUMP_EDGES: case REQ_DUMP_EDGES:
return dump_edges(c); return dump_edges(c);
case REQ_DUMP_SUBNETS: case REQ_DUMP_SUBNETS:
return dump_subnets(c); return dump_subnets(c);
case REQ_DUMP_CONNECTIONS: case REQ_DUMP_CONNECTIONS:
return dump_connections(c); return dump_connections(c);
case REQ_PURGE: case REQ_PURGE:
purge(); purge();
return control_ok(c, REQ_PURGE); return control_ok(c, REQ_PURGE);
case REQ_SET_DEBUG: { case REQ_SET_DEBUG: {
int new_level; int new_level;
if(sscanf(request, "%*d %*d %d", &new_level) != 1)
return false; if(sscanf(request, "%*d %*d %d", &new_level) != 1) {
send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level); return false;
if(new_level >= 0)
debug_level = new_level;
return true;
} }
case REQ_RETRY: send_request(c, "%d %d %d", CONTROL, REQ_SET_DEBUG, debug_level);
retry();
return control_ok(c, REQ_RETRY);
case REQ_RELOAD: if(new_level >= 0) {
logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload"); debug_level = new_level;
int result = reload_configuration(); }
return control_return(c, REQ_RELOAD, result);
case REQ_DISCONNECT: { return true;
char name[MAX_STRING_SIZE]; }
bool found = false;
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) case REQ_RETRY:
return control_return(c, REQ_DISCONNECT, -1); retry();
return control_ok(c, REQ_RETRY);
for list_each(connection_t, other, connection_list) { case REQ_RELOAD:
if(strcmp(other->name, name)) logger(DEBUG_ALWAYS, LOG_NOTICE, "Got '%s' command", "reload");
continue; int result = reload_configuration();
terminate_connection(other, other->edge); return control_return(c, REQ_RELOAD, result);
found = true;
case REQ_DISCONNECT: {
char name[MAX_STRING_SIZE];
bool found = false;
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1) {
return control_return(c, REQ_DISCONNECT, -1);
}
for list_each(connection_t, other, connection_list) {
if(strcmp(other->name, name)) {
continue;
} }
return control_return(c, REQ_DISCONNECT, found ? 0 : -2); terminate_connection(other, other->edge);
found = true;
} }
case REQ_DUMP_TRAFFIC: return control_return(c, REQ_DISCONNECT, found ? 0 : -2);
return dump_traffic(c); }
case REQ_PCAP: case REQ_DUMP_TRAFFIC:
sscanf(request, "%*d %*d %d", &c->outmaclength); return dump_traffic(c);
c->status.pcap = true;
pcap = true;
return true;
case REQ_LOG: case REQ_PCAP:
sscanf(request, "%*d %*d %d", &c->outcompression); sscanf(request, "%*d %*d %d", &c->outmaclength);
c->status.log = true; c->status.pcap = true;
logcontrol = true; pcap = true;
return true; return true;
default: case REQ_LOG:
return send_request(c, "%d %d", CONTROL, REQ_INVALID); sscanf(request, "%*d %*d %d", &c->outcompression);
c->status.log = true;
logcontrol = true;
return true;
default:
return send_request(c, "%d %d", CONTROL, REQ_INVALID);
} }
} }
bool init_control(void) { bool init_control(void) {
randomize(controlcookie, sizeof controlcookie / 2); randomize(controlcookie, sizeof(controlcookie) / 2);
bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); bin2hex(controlcookie, controlcookie, sizeof(controlcookie) / 2);
mode_t mask = umask(0); mode_t mask = umask(0);
umask(mask | 077); umask(mask | 077);
@ -150,21 +159,24 @@ bool init_control(void) {
// Get the address and port of the first listening socket // Get the address and port of the first listening socket
char *localhost = NULL; char *localhost = NULL;
sockaddr_t sa; sockaddr_t sa = {0};
socklen_t len = sizeof sa; socklen_t len = sizeof(sa);
// Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1. // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1.
if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) { if(getsockname(listen_socket[0].tcp.fd, &sa.sa, &len)) {
xasprintf(&localhost, "127.0.0.1 port %s", myport); xasprintf(&localhost, "127.0.0.1 port %s", myport);
} else { } else {
if(sa.sa.sa_family == AF_INET) { if(sa.sa.sa_family == AF_INET) {
if(sa.in.sin_addr.s_addr == 0) if(sa.in.sin_addr.s_addr == 0) {
sa.in.sin_addr.s_addr = htonl(0x7f000001); sa.in.sin_addr.s_addr = htonl(0x7f000001);
}
} else if(sa.sa.sa_family == AF_INET6) { } else if(sa.sa.sa_family == AF_INET6) {
static const uint8_t zero[16] = {0}; static const uint8_t zero[16] = {0};
if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof zero))
if(!memcmp(sa.in6.sin6_addr.s6_addr, zero, sizeof(zero))) {
sa.in6.sin6_addr.s6_addr[15] = 1; sa.in6.sin6_addr.s6_addr[15] = 1;
}
} }
localhost = sockaddr2hostname(&sa); localhost = sockaddr2hostname(&sa);
@ -177,16 +189,21 @@ bool init_control(void) {
#ifndef HAVE_MINGW #ifndef HAVE_MINGW
int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0); int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(unix_fd < 0) { if(unix_fd < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno)); logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(sockerrno));
return false; return false;
} }
struct sockaddr_un sa_un; struct sockaddr_un sa_un;
sa_un.sun_family = AF_UNIX;
strncpy(sa_un.sun_path, unixsocketname, sizeof sa_un.sun_path);
if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un) >= 0) { sa_un.sun_family = AF_UNIX;
strncpy(sa_un.sun_path, unixsocketname, sizeof(sa_un.sun_path));
sa_un.sun_path[sizeof(sa_un.sun_path) - 1] = 0;
if(connect(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) >= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname); logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname);
return false; return false;
} }
@ -194,7 +211,7 @@ bool init_control(void) {
unlink(unixsocketname); unlink(unixsocketname);
umask(mask | 077); umask(mask | 077);
int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof sa_un); int result = bind(unix_fd, (struct sockaddr *)&sa_un, sizeof(sa_un));
umask(mask); umask(mask);
if(result < 0) { if(result < 0) {

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONTROL_H
#define TINC_CONTROL_H
/* /*
control.h -- header for control.c. control.h -- header for control.c.
Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
@ -17,11 +20,8 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CONTROL_H__ extern bool init_control(void);
#define __TINC_CONTROL_H__ extern void exit_control(void);
extern bool init_control();
extern void exit_control();
extern char controlcookie[]; extern char controlcookie[];
#endif #endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_CONTROL_COMMON_H
#define TINC_CONTROL_COMMON_H
/* /*
control_protocol.h -- control socket protocol. control_protocol.h -- control socket protocol.
Copyright (C) 2007 Scott Lamb <slamb@slamb.org> Copyright (C) 2007 Scott Lamb <slamb@slamb.org>
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CONTROL_PROTOCOL_H__
#define __TINC_CONTROL_PROTOCOL_H__
#include "protocol.h" #include "protocol.h"
enum request_type { enum request_type {

View file

@ -1,3 +1,6 @@
#ifndef TINC_CRYPTO_H
#define TINC_CRYPTO_H
/* /*
crypto.h -- header for crypto.c crypto.h -- header for crypto.c
Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,11 +20,8 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_CRYPTO_H__ extern void crypto_init(void);
#define __TINC_CRYPTO_H__ extern void crypto_exit(void);
extern void randomize(void *buf, size_t buflen);
extern void crypto_init();
extern void crypto_exit();
extern void randomize(void *, size_t);
#endif #endif

View file

@ -38,7 +38,7 @@ int device_fd = -1;
static HANDLE device_handle = INVALID_HANDLE_VALUE; static HANDLE device_handle = INVALID_HANDLE_VALUE;
char *device = NULL; char *device = NULL;
char *iface = NULL; char *iface = NULL;
static char *device_info = NULL; static const char *device_info = "Windows tap device";
static pid_t reader_pid; static pid_t reader_pid;
static int sp[2]; static int sp[2];
@ -59,8 +59,9 @@ static bool setup_device(void) {
get_config_string(lookup_config(config_tree, "Device"), &device); get_config_string(lookup_config(config_tree, "Device"), &device);
get_config_string(lookup_config(config_tree, "Interface"), &iface); get_config_string(lookup_config(config_tree, "Interface"), &iface);
if(device && iface) if(device && iface) {
logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected"); logger(LOG_WARNING, "Warning: both Device and Interface specified, results may not be as expected");
}
/* Open registry and look for network adapters */ /* Open registry and look for network adapters */
@ -69,44 +70,51 @@ static bool setup_device(void) {
return false; return false;
} }
for (i = 0; ; i++) { for(i = 0; ; i++) {
len = sizeof adapterid; len = sizeof(adapterid);
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL))
if(RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) {
break; break;
}
/* Find out more about this adapter */ /* Find out more about this adapter */
snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid); snprintf(regpath, sizeof(regpath), "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2)) {
continue; continue;
}
len = sizeof adaptername; len = sizeof(adaptername);
err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len); err = RegQueryValueEx(key2, "Name", 0, 0, adaptername, &len);
RegCloseKey(key2); RegCloseKey(key2);
if(err) if(err) {
continue; continue;
}
if(device) { if(device) {
if(!strcmp(device, adapterid)) { if(!strcmp(device, adapterid)) {
found = true; found = true;
break; break;
} else } else {
continue; continue;
}
} }
if(iface) { if(iface) {
if(!strcmp(iface, adaptername)) { if(!strcmp(iface, adaptername)) {
found = true; found = true;
break; break;
} else } else {
continue; continue;
}
} }
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid); snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle != INVALID_HANDLE_VALUE) { if(device_handle != INVALID_HANDLE_VALUE) {
CloseHandle(device_handle); CloseHandle(device_handle);
found = true; found = true;
@ -121,13 +129,15 @@ static bool setup_device(void) {
return false; return false;
} }
if(!device) if(!device) {
device = xstrdup(adapterid); device = xstrdup(adapterid);
}
if(!iface) if(!iface) {
iface = xstrdup(adaptername); iface = xstrdup(adaptername);
}
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device); snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
/* Now we are going to open this device twice: once for reading and once for writing. /* Now we are going to open this device twice: once for reading and once for writing.
We do this because apparently it isn't possible to check for activity in the select() loop. We do this because apparently it isn't possible to check for activity in the select() loop.
@ -140,7 +150,7 @@ static bool setup_device(void) {
/* The parent opens the tap device for writing. */ /* The parent opens the tap device for writing. */
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0); device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
if(device_handle == INVALID_HANDLE_VALUE) { if(device_handle == INVALID_HANDLE_VALUE) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError())); logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError()));
@ -151,7 +161,7 @@ static bool setup_device(void) {
/* Get MAC address from tap device */ /* Get MAC address from tap device */
if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof mymac.x, mymac.x, sizeof mymac.x, &len, 0)) { if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError())); logger(DEBUG_ALWAYS, LOG_ERR, "Could not get MAC address from Windows tap device %s (%s): %s", device, iface, winerror(GetLastError()));
return false; return false;
} }
@ -203,13 +213,12 @@ static bool setup_device(void) {
} }
read(device_fd, &gelukt, 1); read(device_fd, &gelukt, 1);
if(gelukt != 1) { if(gelukt != 1) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!"); logger(DEBUG_ALWAYS, LOG_DEBUG, "Tap reader failed!");
return false; return false;
} }
device_info = "Windows tap device";
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
return true; return true;
@ -218,12 +227,15 @@ static bool setup_device(void) {
static void close_device(void) { static void close_device(void) {
close(sp[0]); close(sp[0]);
close(sp[1]); close(sp[1]);
CloseHandle(device_handle); device_handle = INVALID_HANDLE_VALUE; CloseHandle(device_handle);
device_handle = INVALID_HANDLE_VALUE;
kill(reader_pid, SIGKILL); kill(reader_pid, SIGKILL);
free(device); device = NULL; free(device);
free(iface); iface = NULL; device = NULL;
free(iface);
iface = NULL;
device_info = NULL; device_info = NULL;
} }
@ -232,14 +244,14 @@ static bool read_packet(vpn_packet_t *packet) {
if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) { if((inlen = read(sp[0], DATA(packet), MTU)) <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info, logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from %s %s: %s", device_info,
device, strerror(errno)); device, strerror(errno));
return false; return false;
} }
packet->len = inlen; packet->len = inlen;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s", packet->len,
device_info); device_info);
return true; return true;
} }
@ -248,9 +260,9 @@ static bool write_packet(vpn_packet_t *packet) {
long outlen; long outlen;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s", logger(DEBUG_TRAFFIC, LOG_DEBUG, "Writing packet of %d bytes to %s",
packet->len, device_info); packet->len, device_info);
if(!WriteFile (device_handle, DATA(packet), packet->len, &outlen, NULL)) { if(!WriteFile(device_handle, DATA(packet), packet->len, &outlen, NULL)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError())); logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info, device, winerror(GetLastError()));
return false; return false;
} }

View file

@ -1,3 +1,6 @@
#ifndef TINC_DEVICE_H
#define TINC_DEVICE_H
/* /*
device.h -- generic header for device.c device.h -- generic header for device.c
Copyright (C) 2001-2005 Ivo Timmermans Copyright (C) 2001-2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_DEVICE_H__
#define __TINC_DEVICE_H__
#include "net.h" #include "net.h"
extern int device_fd; extern int device_fd;
@ -45,4 +45,4 @@ extern const devops_t uml_devops;
extern const devops_t vde_devops; extern const devops_t vde_devops;
extern devops_t devops; extern devops_t devops;
#endif /* __TINC_DEVICE_H__ */ #endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_DIGEST_H
#define TINC_DIGEST_H
/* /*
digest.h -- header file digest.c digest.h -- header file digest.c
Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
@ -17,25 +20,22 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_DIGEST_H__
#define __TINC_DIGEST_H__
#define DIGEST_MAX_SIZE 64 #define DIGEST_MAX_SIZE 64
#ifndef DISABLE_LEGACY #ifndef DISABLE_LEGACY
typedef struct digest digest_t; typedef struct digest digest_t;
extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__((__malloc__));
extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__ ((__malloc__)); extern digest_t *digest_open_by_nid(int nid, int maclength) __attribute__((__malloc__));
extern void digest_close(digest_t *); extern void digest_close(digest_t *digest);
extern bool digest_create(digest_t *, const void *indata, size_t inlen, void *outdata) __attribute__ ((__warn_unused_result__)); extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__));
extern bool digest_verify(digest_t *, const void *indata, size_t inlen, const void *digestdata) __attribute__ ((__warn_unused_result__)); extern bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *digestdata) __attribute__((__warn_unused_result__));
extern bool digest_set_key(digest_t *, const void *key, size_t len) __attribute__ ((__warn_unused_result__)); extern bool digest_set_key(digest_t *digest, const void *key, size_t len) __attribute__((__warn_unused_result__));
extern int digest_get_nid(const digest_t *); extern int digest_get_nid(const digest_t *digest);
extern size_t digest_keylength(const digest_t *); extern size_t digest_keylength(const digest_t *digest);
extern size_t digest_length(const digest_t *); extern size_t digest_length(const digest_t *digest);
extern bool digest_active(const digest_t *); extern bool digest_active(const digest_t *digest);
#endif #endif

View file

@ -50,8 +50,9 @@ int daemon(int nochdir, int noclose) {
} }
/* If we are the parent, terminate */ /* If we are the parent, terminate */
if(pid) if(pid) {
exit(0); exit(0);
}
/* Detach by becoming the new process group leader */ /* Detach by becoming the new process group leader */
if(setsid() < 0) { if(setsid() < 0) {
@ -108,8 +109,9 @@ int vasprintf(char **buf, const char *fmt, va_list ap) {
status = vsnprintf(*buf, len, fmt, aq); status = vsnprintf(*buf, len, fmt, aq);
va_end(aq); va_end(aq);
if(status >= 0) if(status >= 0) {
*buf = xrealloc(*buf, status + 1); *buf = xrealloc(*buf, status + 1);
}
if(status > len - 1) { if(status > len - 1) {
len = status + 1; len = status + 1;

View file

@ -1,3 +1,6 @@
#ifndef TINC_DROPIN_H
#define TINC_DROPIN_H
/* /*
dropin.h -- header file for dropin.c dropin.h -- header file for dropin.c
Copyright (C) 2000-2005 Ivo Timmermans, Copyright (C) 2000-2005 Ivo Timmermans,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __DROPIN_H__
#define __DROPIN_H__
#ifndef HAVE_DAEMON #ifndef HAVE_DAEMON
extern int daemon(int, int); extern int daemon(int, int);
#endif #endif
@ -40,20 +40,20 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
#ifndef timeradd #ifndef timeradd
#define timeradd(a, b, r) do {\ #define timeradd(a, b, r) do {\
(r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\ (r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\
(r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\ (r)->tv_usec = (a)->tv_usec + (b)->tv_usec;\
if((r)->tv_usec >= 1000000)\ if((r)->tv_usec >= 1000000)\
(r)->tv_sec++, (r)->tv_usec -= 1000000;\ (r)->tv_sec++, (r)->tv_usec -= 1000000;\
} while (0) } while (0)
#endif #endif
#ifndef timersub #ifndef timersub
#define timersub(a, b, r) do {\ #define timersub(a, b, r) do {\
(r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\ (r)->tv_sec = (a)->tv_sec - (b)->tv_sec;\
(r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\ (r)->tv_usec = (a)->tv_usec - (b)->tv_usec;\
if((r)->tv_usec < 0)\ if((r)->tv_usec < 0)\
(r)->tv_sec--, (r)->tv_usec += 1000000;\ (r)->tv_sec--, (r)->tv_usec += 1000000;\
} while (0) } while (0)
#endif #endif
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
@ -67,4 +67,4 @@ extern int nanosleep(const struct timespec *req, struct timespec *rem);
#define EAI_SYSTEM 0 #define EAI_SYSTEM 0
#endif #endif
#endif /* __DROPIN_H__ */ #endif

View file

@ -22,12 +22,13 @@
#include "device.h" #include "device.h"
#include "logger.h" #include "logger.h"
#include "net.h" #include "net.h"
#include "xalloc.h"
static char *device_info = "dummy device"; static const char *device_info = "dummy device";
static bool setup_device(void) { static bool setup_device(void) {
device = "dummy"; device = xstrdup("dummy");
iface = "dummy"; iface = xstrdup("dummy");
logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info); logger(DEBUG_ALWAYS, LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
return true; return true;
} }
@ -36,10 +37,12 @@ static void close_device(void) {
} }
static bool read_packet(vpn_packet_t *packet) { static bool read_packet(vpn_packet_t *packet) {
(void)packet;
return false; return false;
} }
static bool write_packet(vpn_packet_t *packet) { static bool write_packet(vpn_packet_t *packet) {
(void)packet;
return true; return true;
} }

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDH_H
#define TINC_ECDH_H
/* /*
ecdh.h -- header file for ecdh.c ecdh.h -- header file for ecdh.c
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,18 +20,15 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_ECDH_H__
#define __TINC_ECDH_H__
#define ECDH_SIZE 32 #define ECDH_SIZE 32
#define ECDH_SHARED_SIZE 32 #define ECDH_SHARED_SIZE 32
#ifndef __TINC_ECDH_INTERNAL__ #ifndef TINC_ECDH_INTERNAL
typedef struct ecdh ecdh_t; typedef struct ecdh ecdh_t;
#endif #endif
extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__ ((__malloc__)); extern ecdh_t *ecdh_generate_public(void *pubkey) __attribute__((__malloc__));
extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__ ((__warn_unused_result__)); extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) __attribute__((__warn_unused_result__));
extern void ecdh_free(ecdh_t *ecdh); extern void ecdh_free(ecdh_t *ecdh);
#endif #endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDSA_H
#define TINC_ECDSA_H
/* /*
ecdsa.h -- ECDSA key handling ecdsa.h -- ECDSA key handling
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,20 +20,17 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_ECDSA_H__ #ifndef TINC_ECDSA_INTERNAL
#define __TINC_ECDSA_H__
#ifndef __TINC_ECDSA_INTERNAL__
typedef struct ecdsa ecdsa_t; typedef struct ecdsa ecdsa_t;
#endif #endif
extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__ ((__malloc__)); extern ecdsa_t *ecdsa_set_base64_public_key(const char *p) __attribute__((__malloc__));
extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa); extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa);
extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__ ((__malloc__)); extern ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__));
extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__ ((__malloc__)); extern ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__));
extern size_t ecdsa_size(ecdsa_t *ecdsa); extern size_t ecdsa_size(ecdsa_t *ecdsa);
extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__ ((__warn_unused_result__)); extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out) __attribute__((__warn_unused_result__));
extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__ ((__warn_unused_result__)); extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out) __attribute__((__warn_unused_result__));
extern bool ecdsa_active(ecdsa_t *ecdsa); extern bool ecdsa_active(ecdsa_t *ecdsa);
extern void ecdsa_free(ecdsa_t *ecdsa); extern void ecdsa_free(ecdsa_t *ecdsa);

View file

@ -1,3 +1,6 @@
#ifndef TINC_ECDSAGEN_H
#define TINC_ECDSAGEN_H
/* /*
ecdsagen.h -- ECDSA key generation and export ecdsagen.h -- ECDSA key generation and export
Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,13 +20,10 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_ECDSAGEN_H__
#define __TINC_ECDSAGEN_H__
#include "ecdsa.h" #include "ecdsa.h"
extern ecdsa_t *ecdsa_generate(void) __attribute__ ((__malloc__)); extern ecdsa_t *ecdsa_generate(void) __attribute__((__malloc__));
extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__));
extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__ ((__warn_unused_result__)); extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) __attribute__((__warn_unused_result__));
#endif #endif

View file

@ -21,7 +21,7 @@
#include "ed25519.h" #include "ed25519.h"
#define __TINC_ECDH_INTERNAL__ #define TINC_ECDH_INTERNAL
typedef struct ecdh_t { typedef struct ecdh_t {
uint8_t private[64]; uint8_t private[64];
} ecdh_t; } ecdh_t;
@ -31,10 +31,10 @@ typedef struct ecdh_t {
#include "../xalloc.h" #include "../xalloc.h"
ecdh_t *ecdh_generate_public(void *pubkey) { ecdh_t *ecdh_generate_public(void *pubkey) {
ecdh_t *ecdh = xzalloc(sizeof *ecdh); ecdh_t *ecdh = xzalloc(sizeof(*ecdh));
uint8_t seed[32]; uint8_t seed[32];
randomize(seed, sizeof seed); randomize(seed, sizeof(seed));
ed25519_create_keypair(pubkey, ecdh->private, seed); ed25519_create_keypair(pubkey, ecdh->private, seed);
return ecdh; return ecdh;

View file

@ -21,7 +21,7 @@
#include "ed25519.h" #include "ed25519.h"
#define __TINC_ECDSA_INTERNAL__ #define TINC_ECDSA_INTERNAL
typedef struct { typedef struct {
uint8_t private[64]; uint8_t private[64];
uint8_t public[32]; uint8_t public[32];
@ -42,8 +42,9 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
return 0; return 0;
} }
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
len = b64decode(p, ecdsa->public, len); len = b64decode(p, ecdsa->public, len);
if(len != 32) { if(len != 32) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len); logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %d", len);
free(ecdsa); free(ecdsa);
@ -55,33 +56,40 @@ ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
char *base64 = xmalloc(44); char *base64 = xmalloc(44);
b64encode(ecdsa->public, base64, sizeof ecdsa->public); b64encode(ecdsa->public, base64, sizeof(ecdsa->public));
return base64; return base64;
} }
// Read PEM ECDSA keys // Read PEM ECDSA keys
static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) { static bool read_pem(FILE *fp, const char *type, void *vbuf, size_t size) {
char line[1024]; char line[1024];
bool data = false; bool data = false;
size_t typelen = strlen(type); size_t typelen = strlen(type);
char *buf = vbuf;
while(fgets(line, sizeof line, fp)) { while(fgets(line, sizeof(line), fp)) {
if(!data) { if(!data) {
if(strncmp(line, "-----BEGIN ", 11)) if(strncmp(line, "-----BEGIN ", 11)) {
continue; continue;
if(strncmp(line + 11, type, typelen)) }
if(strncmp(line + 11, type, typelen)) {
continue; continue;
}
data = true; data = true;
continue; continue;
} }
if(!strncmp(line, "-----END ", 9)) if(!strncmp(line, "-----END ", 9)) {
break; break;
}
size_t linelen = strcspn(line, "\r\n"); size_t linelen = strcspn(line, "\r\n");
size_t len = b64decode(line, line, linelen); size_t len = b64decode(line, line, linelen);
if(!len) { if(!len) {
logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n"); logger(DEBUG_ALWAYS, LOG_ERR, "Invalid base64 data in PEM file\n");
errno = EINVAL; errno = EINVAL;
@ -106,6 +114,7 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
} else { } else {
errno = ENOENT; errno = ENOENT;
} }
return false; return false;
} }
@ -113,22 +122,29 @@ static bool read_pem(FILE *fp, const char *type, void *buf, size_t size) {
} }
ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public))
if(read_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public))) {
return ecdsa; return ecdsa;
}
free(ecdsa); free(ecdsa);
return 0; return 0;
} }
ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
ecdsa_t *ecdsa = xmalloc(sizeof *ecdsa); ecdsa_t *ecdsa = xmalloc(sizeof(*ecdsa));
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa))
if(read_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa))) {
return ecdsa; return ecdsa;
}
free(ecdsa); free(ecdsa);
return 0; return 0;
} }
size_t ecdsa_size(ecdsa_t *ecdsa) { size_t ecdsa_size(ecdsa_t *ecdsa) {
(void)ecdsa;
return 64; return 64;
} }

View file

@ -21,7 +21,7 @@
#include "ed25519.h" #include "ed25519.h"
#define __TINC_ECDSA_INTERNAL__ #define TINC_ECDSA_INTERNAL
typedef struct { typedef struct {
uint8_t private[64]; uint8_t private[64];
uint8_t public[32]; uint8_t public[32];
@ -35,10 +35,10 @@ typedef struct {
// Generate ECDSA key // Generate ECDSA key
ecdsa_t *ecdsa_generate(void) { ecdsa_t *ecdsa_generate(void) {
ecdsa_t *ecdsa = xzalloc(sizeof *ecdsa); ecdsa_t *ecdsa = xzalloc(sizeof(*ecdsa));
uint8_t seed[32]; uint8_t seed[32];
randomize(seed, sizeof seed); randomize(seed, sizeof(seed));
ed25519_create_keypair(ecdsa->public, ecdsa->private, seed); ed25519_create_keypair(ecdsa->public, ecdsa->private, seed);
return ecdsa; return ecdsa;
@ -46,10 +46,12 @@ ecdsa_t *ecdsa_generate(void) {
// Write PEM ECDSA keys // Write PEM ECDSA keys
static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) { static bool write_pem(FILE *fp, const char *type, void *vbuf, size_t size) {
fprintf(fp, "-----BEGIN %s-----\n", type); fprintf(fp, "-----BEGIN %s-----\n", type);
char *buf = vbuf;
char base64[65]; char base64[65];
while(size) { while(size) {
size_t todo = size > 48 ? 48 : size; size_t todo = size > 48 ? 48 : size;
b64encode(buf, base64, todo); b64encode(buf, base64, todo);
@ -63,9 +65,9 @@ static bool write_pem(FILE *fp, const char *type, void *buf, size_t size) {
} }
bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof ecdsa->public); return write_pem(fp, "ED25519 PUBLIC KEY", ecdsa->public, sizeof(ecdsa->public));
} }
bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof *ecdsa); return write_pem(fp, "ED25519 PRIVATE KEY", ecdsa->private, sizeof(*ecdsa));
} }

View file

@ -4,15 +4,15 @@
#include <stddef.h> #include <stddef.h>
#if defined(_WIN32) #if defined(_WIN32)
#if defined(ED25519_BUILD_DLL) #if defined(ED25519_BUILD_DLL)
#define ED25519_DECLSPEC __declspec(dllexport) #define ED25519_DECLSPEC __declspec(dllexport)
#elif defined(ED25519_DLL) #elif defined(ED25519_DLL)
#define ED25519_DECLSPEC __declspec(dllimport) #define ED25519_DECLSPEC __declspec(dllimport)
#else
#define ED25519_DECLSPEC
#endif
#else #else
#define ED25519_DECLSPEC #define ED25519_DECLSPEC
#endif
#else
#define ED25519_DECLSPEC
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,75 +1,75 @@
#ifndef TINC_FIXEDINT_H
#define TINC_FIXEDINT_H
/* /*
Portable header to provide the 32 and 64 bits type. Portable header to provide the 32 and 64 bits type.
Not a compatible replacement for <stdint.h>, do not blindly use it as such. Not a compatible replacement for <stdint.h>, do not blindly use it as such.
*/ */
#ifndef __TINC_FIXEDINT_H__
#define __TINC_FIXEDINT_H__
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED) #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__WATCOMC__) && (defined(_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined(__UINT_FAST64_TYPE__)) )) && !defined(FIXEDINT_H_INCLUDED)
#include <stdint.h> #include <stdint.h>
#define FIXEDINT_H_INCLUDED #define FIXEDINT_H_INCLUDED
#if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C) #if defined(__WATCOMC__) && __WATCOMC__ >= 1250 && !defined(UINT64_C)
#include <limits.h> #include <limits.h>
#define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX)) #define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
#endif #endif
#endif #endif
#ifndef FIXEDINT_H_INCLUDED #ifndef FIXEDINT_H_INCLUDED
#define FIXEDINT_H_INCLUDED #define FIXEDINT_H_INCLUDED
/* (u)int32_t */ /* (u)int32_t */
#ifndef uint32_t #ifndef uint32_t
#if (ULONG_MAX == 0xffffffffUL) #if (ULONG_MAX == 0xffffffffUL)
typedef unsigned long uint32_t; typedef unsigned long uint32_t;
#elif (UINT_MAX == 0xffffffffUL) #elif (UINT_MAX == 0xffffffffUL)
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
#elif (USHRT_MAX == 0xffffffffUL) #elif (USHRT_MAX == 0xffffffffUL)
typedef unsigned short uint32_t; typedef unsigned short uint32_t;
#endif #endif
#endif #endif
#ifndef int32_t #ifndef int32_t
#if (LONG_MAX == 0x7fffffffL) #if (LONG_MAX == 0x7fffffffL)
typedef signed long int32_t; typedef signed long int32_t;
#elif (INT_MAX == 0x7fffffffL) #elif (INT_MAX == 0x7fffffffL)
typedef signed int int32_t; typedef signed int int32_t;
#elif (SHRT_MAX == 0x7fffffffL) #elif (SHRT_MAX == 0x7fffffffL)
typedef signed short int32_t; typedef signed short int32_t;
#endif #endif
#endif #endif
/* (u)int64_t */ /* (u)int64_t */
#if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L) #if (defined(__STDC__) && defined(__STDC_VERSION__) && __STDC__ && __STDC_VERSION__ >= 199901L)
typedef long long int64_t; typedef long long int64_t;
typedef unsigned long long uint64_t; typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL #define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL #define INT64_C(v) v ##LL
#elif defined(__GNUC__) #elif defined(__GNUC__)
__extension__ typedef long long int64_t; __extension__ typedef long long int64_t;
__extension__ typedef unsigned long long uint64_t; __extension__ typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL #define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL #define INT64_C(v) v ##LL
#elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC) #elif defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__APPLE_CC__) || defined(_LONG_LONG) || defined(_CRAYC)
typedef long long int64_t; typedef long long int64_t;
typedef unsigned long long uint64_t; typedef unsigned long long uint64_t;
#define UINT64_C(v) v ##ULL #define UINT64_C(v) v ##ULL
#define INT64_C(v) v ##LL #define INT64_C(v) v ##LL
#elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC) #elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__alpha) || defined(__DECC)
typedef __int64 int64_t; typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
#define UINT64_C(v) v ##UI64 #define UINT64_C(v) v ##UI64
#define INT64_C(v) v ##I64 #define INT64_C(v) v ##I64
#endif #endif
#endif #endif
static inline unsigned char shlu8(unsigned char a, uint32_t b) { static inline unsigned char shlu8(unsigned char a, uint32_t b) {

View file

@ -7,54 +7,54 @@ r = p + q
*/ */
void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0; fe t0;
fe_add(r->X, p->Y, p->X); fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X); fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->YplusX); fe_mul(r->Z, r->X, q->YplusX);
fe_mul(r->Y, r->Y, q->YminusX); fe_mul(r->Y, r->Y, q->YminusX);
fe_mul(r->T, q->T2d, p->T); fe_mul(r->T, q->T2d, p->T);
fe_mul(r->X, p->Z, q->Z); fe_mul(r->X, p->Z, q->Z);
fe_add(t0, r->X, r->X); fe_add(t0, r->X, r->X);
fe_sub(r->X, r->Z, r->Y); fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y); fe_add(r->Y, r->Z, r->Y);
fe_add(r->Z, t0, r->T); fe_add(r->Z, t0, r->T);
fe_sub(r->T, t0, r->T); fe_sub(r->T, t0, r->T);
} }
static void slide(signed char *r, const unsigned char *a) { static void slide(signed char *r, const unsigned char *a) {
int i; int i;
int b; int b;
int k; int k;
for (i = 0; i < 256; ++i) { for(i = 0; i < 256; ++i) {
r[i] = 1 & (a[i >> 3] >> (i & 7)); r[i] = 1 & (a[i >> 3] >> (i & 7));
} }
for (i = 0; i < 256; ++i) for(i = 0; i < 256; ++i)
if (r[i]) { if(r[i]) {
for (b = 1; b <= 6 && i + b < 256; ++b) { for(b = 1; b <= 6 && i + b < 256; ++b) {
if (r[i + b]) { if(r[i + b]) {
if (r[i] + (r[i + b] << b) <= 15) { if(r[i] + (r[i + b] << b) <= 15) {
r[i] += r[i + b] << b; r[i] += r[i + b] << b;
r[i + b] = 0; r[i + b] = 0;
} else if (r[i] - (r[i + b] << b) >= -15) { } else if(r[i] - (r[i + b] << b) >= -15) {
r[i] -= r[i + b] << b; r[i] -= r[i + b] << b;
for (k = i + b; k < 256; ++k) { for(k = i + b; k < 256; ++k) {
if (!r[k]) { if(!r[k]) {
r[k] = 1; r[k] = 1;
break; break;
} }
r[k] = 0; r[k] = 0;
} }
} else { } else {
break; break;
} }
} }
} }
} }
} }
/* /*
@ -65,119 +65,119 @@ B is the Ed25519 base point (x,4/5) with x positive.
*/ */
void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { void ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
signed char aslide[256]; signed char aslide[256];
signed char bslide[256]; signed char bslide[256];
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
ge_p1p1 t; ge_p1p1 t;
ge_p3 u; ge_p3 u;
ge_p3 A2; ge_p3 A2;
int i; int i;
slide(aslide, a); slide(aslide, a);
slide(bslide, b); slide(bslide, b);
ge_p3_to_cached(&Ai[0], A); ge_p3_to_cached(&Ai[0], A);
ge_p3_dbl(&t, A); ge_p3_dbl(&t, A);
ge_p1p1_to_p3(&A2, &t); ge_p1p1_to_p3(&A2, &t);
ge_add(&t, &A2, &Ai[0]); ge_add(&t, &A2, &Ai[0]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[1], &u); ge_p3_to_cached(&Ai[1], &u);
ge_add(&t, &A2, &Ai[1]); ge_add(&t, &A2, &Ai[1]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[2], &u); ge_p3_to_cached(&Ai[2], &u);
ge_add(&t, &A2, &Ai[2]); ge_add(&t, &A2, &Ai[2]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[3], &u); ge_p3_to_cached(&Ai[3], &u);
ge_add(&t, &A2, &Ai[3]); ge_add(&t, &A2, &Ai[3]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[4], &u); ge_p3_to_cached(&Ai[4], &u);
ge_add(&t, &A2, &Ai[4]); ge_add(&t, &A2, &Ai[4]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[5], &u); ge_p3_to_cached(&Ai[5], &u);
ge_add(&t, &A2, &Ai[5]); ge_add(&t, &A2, &Ai[5]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[6], &u); ge_p3_to_cached(&Ai[6], &u);
ge_add(&t, &A2, &Ai[6]); ge_add(&t, &A2, &Ai[6]);
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_p3_to_cached(&Ai[7], &u); ge_p3_to_cached(&Ai[7], &u);
ge_p2_0(r); ge_p2_0(r);
for (i = 255; i >= 0; --i) { for(i = 255; i >= 0; --i) {
if (aslide[i] || bslide[i]) { if(aslide[i] || bslide[i]) {
break; break;
} }
} }
for (; i >= 0; --i) { for(; i >= 0; --i) {
ge_p2_dbl(&t, r); ge_p2_dbl(&t, r);
if (aslide[i] > 0) { if(aslide[i] > 0) {
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_add(&t, &u, &Ai[aslide[i] / 2]); ge_add(&t, &u, &Ai[aslide[i] / 2]);
} else if (aslide[i] < 0) { } else if(aslide[i] < 0) {
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]);
} }
if (bslide[i] > 0) { if(bslide[i] > 0) {
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_madd(&t, &u, &Bi[bslide[i] / 2]); ge_madd(&t, &u, &Bi[bslide[i] / 2]);
} else if (bslide[i] < 0) { } else if(bslide[i] < 0) {
ge_p1p1_to_p3(&u, &t); ge_p1p1_to_p3(&u, &t);
ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]);
} }
ge_p1p1_to_p2(r, &t); ge_p1p1_to_p2(r, &t);
} }
} }
static const fe d = { static const fe d = {
-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116
}; };
static const fe sqrtm1 = { static const fe sqrtm1 = {
-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482
}; };
int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) { int ge_frombytes_negate_vartime(ge_p3 *h, const unsigned char *s) {
fe u; fe u;
fe v; fe v;
fe v3; fe v3;
fe vxx; fe vxx;
fe check; fe check;
fe_frombytes(h->Y, s); fe_frombytes(h->Y, s);
fe_1(h->Z); fe_1(h->Z);
fe_sq(u, h->Y); fe_sq(u, h->Y);
fe_mul(v, u, d); fe_mul(v, u, d);
fe_sub(u, u, h->Z); /* u = y^2-1 */ fe_sub(u, u, h->Z); /* u = y^2-1 */
fe_add(v, v, h->Z); /* v = dy^2+1 */ fe_add(v, v, h->Z); /* v = dy^2+1 */
fe_sq(v3, v); fe_sq(v3, v);
fe_mul(v3, v3, v); /* v3 = v^3 */ fe_mul(v3, v3, v); /* v3 = v^3 */
fe_sq(h->X, v3); fe_sq(h->X, v3);
fe_mul(h->X, h->X, v); fe_mul(h->X, h->X, v);
fe_mul(h->X, h->X, u); /* x = uv^7 */ fe_mul(h->X, h->X, u); /* x = uv^7 */
fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ fe_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */
fe_mul(h->X, h->X, v3); fe_mul(h->X, h->X, v3);
fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ fe_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */
fe_sq(vxx, h->X); fe_sq(vxx, h->X);
fe_mul(vxx, vxx, v); fe_mul(vxx, vxx, v);
fe_sub(check, vxx, u); /* vx^2-u */ fe_sub(check, vxx, u); /* vx^2-u */
if (fe_isnonzero(check)) { if(fe_isnonzero(check)) {
fe_add(check, vxx, u); /* vx^2+u */ fe_add(check, vxx, u); /* vx^2+u */
if (fe_isnonzero(check)) { if(fe_isnonzero(check)) {
return -1; return -1;
} }
fe_mul(h->X, h->X, sqrtm1); fe_mul(h->X, h->X, sqrtm1);
} }
if (fe_isnegative(h->X) == (s[31] >> 7)) { if(fe_isnegative(h->X) == (s[31] >> 7)) {
fe_neg(h->X, h->X); fe_neg(h->X, h->X);
} }
fe_mul(h->T, h->X, h->Y); fe_mul(h->T, h->X, h->Y);
return 0; return 0;
} }
@ -186,17 +186,17 @@ r = p + q
*/ */
void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
fe t0; fe t0;
fe_add(r->X, p->Y, p->X); fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X); fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->yplusx); fe_mul(r->Z, r->X, q->yplusx);
fe_mul(r->Y, r->Y, q->yminusx); fe_mul(r->Y, r->Y, q->yminusx);
fe_mul(r->T, q->xy2d, p->T); fe_mul(r->T, q->xy2d, p->T);
fe_add(t0, p->Z, p->Z); fe_add(t0, p->Z, p->Z);
fe_sub(r->X, r->Z, r->Y); fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y); fe_add(r->Y, r->Z, r->Y);
fe_add(r->Z, t0, r->T); fe_add(r->Z, t0, r->T);
fe_sub(r->T, t0, r->T); fe_sub(r->T, t0, r->T);
} }
@ -205,18 +205,18 @@ r = p - q
*/ */
void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
fe t0; fe t0;
fe_add(r->X, p->Y, p->X); fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X); fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->yminusx); fe_mul(r->Z, r->X, q->yminusx);
fe_mul(r->Y, r->Y, q->yplusx); fe_mul(r->Y, r->Y, q->yplusx);
fe_mul(r->T, q->xy2d, p->T); fe_mul(r->T, q->xy2d, p->T);
fe_add(t0, p->Z, p->Z); fe_add(t0, p->Z, p->Z);
fe_sub(r->X, r->Z, r->Y); fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y); fe_add(r->Y, r->Z, r->Y);
fe_sub(r->Z, t0, r->T); fe_sub(r->Z, t0, r->T);
fe_add(r->T, t0, r->T); fe_add(r->T, t0, r->T);
} }
@ -225,9 +225,9 @@ r = p
*/ */
void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
fe_mul(r->X, p->X, p->T); fe_mul(r->X, p->X, p->T);
fe_mul(r->Y, p->Y, p->Z); fe_mul(r->Y, p->Y, p->Z);
fe_mul(r->Z, p->Z, p->T); fe_mul(r->Z, p->Z, p->T);
} }
@ -237,17 +237,17 @@ r = p
*/ */
void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
fe_mul(r->X, p->X, p->T); fe_mul(r->X, p->X, p->T);
fe_mul(r->Y, p->Y, p->Z); fe_mul(r->Y, p->Y, p->Z);
fe_mul(r->Z, p->Z, p->T); fe_mul(r->Z, p->Z, p->T);
fe_mul(r->T, p->X, p->Y); fe_mul(r->T, p->X, p->Y);
} }
void ge_p2_0(ge_p2 *h) { void ge_p2_0(ge_p2 *h) {
fe_0(h->X); fe_0(h->X);
fe_1(h->Y); fe_1(h->Y);
fe_1(h->Z); fe_1(h->Z);
} }
@ -257,25 +257,25 @@ r = 2 * p
*/ */
void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
fe t0; fe t0;
fe_sq(r->X, p->X); fe_sq(r->X, p->X);
fe_sq(r->Z, p->Y); fe_sq(r->Z, p->Y);
fe_sq2(r->T, p->Z); fe_sq2(r->T, p->Z);
fe_add(r->Y, p->X, p->Y); fe_add(r->Y, p->X, p->Y);
fe_sq(t0, r->Y); fe_sq(t0, r->Y);
fe_add(r->Y, r->Z, r->X); fe_add(r->Y, r->Z, r->X);
fe_sub(r->Z, r->Z, r->X); fe_sub(r->Z, r->Z, r->X);
fe_sub(r->X, t0, r->Y); fe_sub(r->X, t0, r->Y);
fe_sub(r->T, r->T, r->Z); fe_sub(r->T, r->T, r->Z);
} }
void ge_p3_0(ge_p3 *h) { void ge_p3_0(ge_p3 *h) {
fe_0(h->X); fe_0(h->X);
fe_1(h->Y); fe_1(h->Y);
fe_1(h->Z); fe_1(h->Z);
fe_0(h->T); fe_0(h->T);
} }
@ -284,9 +284,9 @@ r = 2 * p
*/ */
void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
ge_p2 q; ge_p2 q;
ge_p3_to_p2(&q, p); ge_p3_to_p2(&q, p);
ge_p2_dbl(r, &q); ge_p2_dbl(r, &q);
} }
@ -296,14 +296,14 @@ r = p
*/ */
static const fe d2 = { static const fe d2 = {
-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199
}; };
void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) {
fe_add(r->YplusX, p->Y, p->X); fe_add(r->YplusX, p->Y, p->X);
fe_sub(r->YminusX, p->Y, p->X); fe_sub(r->YminusX, p->Y, p->X);
fe_copy(r->Z, p->Z); fe_copy(r->Z, p->Z);
fe_mul(r->T2d, p->T, d2); fe_mul(r->T2d, p->T, d2);
} }
@ -312,66 +312,66 @@ r = p
*/ */
void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
fe_copy(r->X, p->X); fe_copy(r->X, p->X);
fe_copy(r->Y, p->Y); fe_copy(r->Y, p->Y);
fe_copy(r->Z, p->Z); fe_copy(r->Z, p->Z);
} }
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) {
fe recip; fe recip;
fe x; fe x;
fe y; fe y;
fe_invert(recip, h->Z); fe_invert(recip, h->Z);
fe_mul(x, h->X, recip); fe_mul(x, h->X, recip);
fe_mul(y, h->Y, recip); fe_mul(y, h->Y, recip);
fe_tobytes(s, y); fe_tobytes(s, y);
s[31] ^= fe_isnegative(x) << 7; s[31] ^= fe_isnegative(x) << 7;
} }
static unsigned char equal(signed char b, signed char c) { static unsigned char equal(signed char b, signed char c) {
unsigned char ub = b; unsigned char ub = b;
unsigned char uc = c; unsigned char uc = c;
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
uint64_t y = x; /* 0: yes; 1..255: no */ uint64_t y = x; /* 0: yes; 1..255: no */
y -= 1; /* large: yes; 0..254: no */ y -= 1; /* large: yes; 0..254: no */
y >>= 63; /* 1: yes; 0: no */ y >>= 63; /* 1: yes; 0: no */
return (unsigned char) y; return (unsigned char) y;
} }
static unsigned char negative(signed char b) { static unsigned char negative(signed char b) {
uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */ x >>= 63; /* 1: yes; 0: no */
return (unsigned char) x; return (unsigned char) x;
} }
static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) { static void cmov(ge_precomp *t, ge_precomp *u, unsigned char b) {
fe_cmov(t->yplusx, u->yplusx, b); fe_cmov(t->yplusx, u->yplusx, b);
fe_cmov(t->yminusx, u->yminusx, b); fe_cmov(t->yminusx, u->yminusx, b);
fe_cmov(t->xy2d, u->xy2d, b); fe_cmov(t->xy2d, u->xy2d, b);
} }
static void select(ge_precomp *t, int pos, signed char b) { static void select(ge_precomp *t, int pos, signed char b) {
ge_precomp minust; ge_precomp minust;
unsigned char bnegative = negative(b); unsigned char bnegative = negative(b);
unsigned char babs = b - shlu8(((-bnegative) & b), 1); unsigned char babs = b - shlu8(((-bnegative) & b), 1);
fe_1(t->yplusx); fe_1(t->yplusx);
fe_1(t->yminusx); fe_1(t->yminusx);
fe_0(t->xy2d); fe_0(t->xy2d);
cmov(t, &base[pos][0], equal(babs, 1)); cmov(t, &base[pos][0], equal(babs, 1));
cmov(t, &base[pos][1], equal(babs, 2)); cmov(t, &base[pos][1], equal(babs, 2));
cmov(t, &base[pos][2], equal(babs, 3)); cmov(t, &base[pos][2], equal(babs, 3));
cmov(t, &base[pos][3], equal(babs, 4)); cmov(t, &base[pos][3], equal(babs, 4));
cmov(t, &base[pos][4], equal(babs, 5)); cmov(t, &base[pos][4], equal(babs, 5));
cmov(t, &base[pos][5], equal(babs, 6)); cmov(t, &base[pos][5], equal(babs, 6));
cmov(t, &base[pos][6], equal(babs, 7)); cmov(t, &base[pos][6], equal(babs, 7));
cmov(t, &base[pos][7], equal(babs, 8)); cmov(t, &base[pos][7], equal(babs, 8));
fe_copy(minust.yplusx, t->yminusx); fe_copy(minust.yplusx, t->yminusx);
fe_copy(minust.yminusx, t->yplusx); fe_copy(minust.yminusx, t->yplusx);
fe_neg(minust.xy2d, t->xy2d); fe_neg(minust.xy2d, t->xy2d);
cmov(t, &minust, bnegative); cmov(t, &minust, bnegative);
} }
/* /*
@ -384,53 +384,53 @@ Preconditions:
*/ */
void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) {
signed char e[64]; signed char e[64];
signed char carry; signed char carry;
ge_p1p1 r; ge_p1p1 r;
ge_p2 s; ge_p2 s;
ge_precomp t; ge_precomp t;
int i; int i;
for (i = 0; i < 32; ++i) { for(i = 0; i < 32; ++i) {
e[2 * i + 0] = (a[i] >> 0) & 15; e[2 * i + 0] = (a[i] >> 0) & 15;
e[2 * i + 1] = (a[i] >> 4) & 15; e[2 * i + 1] = (a[i] >> 4) & 15;
} }
/* each e[i] is between 0 and 15 */ /* each e[i] is between 0 and 15 */
/* e[63] is between 0 and 7 */ /* e[63] is between 0 and 7 */
carry = 0; carry = 0;
for (i = 0; i < 63; ++i) { for(i = 0; i < 63; ++i) {
e[i] += carry; e[i] += carry;
carry = e[i] + 8; carry = e[i] + 8;
carry >>= 4; carry >>= 4;
e[i] -= shl32(carry, 4); e[i] -= shl32(carry, 4);
} }
e[63] += carry; e[63] += carry;
/* each e[i] is between -8 and 8 */ /* each e[i] is between -8 and 8 */
ge_p3_0(h); ge_p3_0(h);
for (i = 1; i < 64; i += 2) { for(i = 1; i < 64; i += 2) {
select(&t, i / 2, e[i]); select(&t, i / 2, e[i]);
ge_madd(&r, h, &t); ge_madd(&r, h, &t);
ge_p1p1_to_p3(h, &r); ge_p1p1_to_p3(h, &r);
} }
ge_p3_dbl(&r, h); ge_p3_dbl(&r, h);
ge_p1p1_to_p2(&s, &r); ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s); ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r); ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s); ge_p2_dbl(&r, &s);
ge_p1p1_to_p2(&s, &r); ge_p1p1_to_p2(&s, &r);
ge_p2_dbl(&r, &s); ge_p2_dbl(&r, &s);
ge_p1p1_to_p3(h, &r); ge_p1p1_to_p3(h, &r);
for (i = 0; i < 64; i += 2) { for(i = 0; i < 64; i += 2) {
select(&t, i / 2, e[i]); select(&t, i / 2, e[i]);
ge_madd(&r, h, &t); ge_madd(&r, h, &t);
ge_p1p1_to_p3(h, &r); ge_p1p1_to_p3(h, &r);
} }
} }
@ -439,29 +439,29 @@ r = p - q
*/ */
void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) {
fe t0; fe t0;
fe_add(r->X, p->Y, p->X); fe_add(r->X, p->Y, p->X);
fe_sub(r->Y, p->Y, p->X); fe_sub(r->Y, p->Y, p->X);
fe_mul(r->Z, r->X, q->YminusX); fe_mul(r->Z, r->X, q->YminusX);
fe_mul(r->Y, r->Y, q->YplusX); fe_mul(r->Y, r->Y, q->YplusX);
fe_mul(r->T, q->T2d, p->T); fe_mul(r->T, q->T2d, p->T);
fe_mul(r->X, p->Z, q->Z); fe_mul(r->X, p->Z, q->Z);
fe_add(t0, r->X, r->X); fe_add(t0, r->X, r->X);
fe_sub(r->X, r->Z, r->Y); fe_sub(r->X, r->Z, r->Y);
fe_add(r->Y, r->Z, r->Y); fe_add(r->Y, r->Z, r->Y);
fe_sub(r->Z, t0, r->T); fe_sub(r->Z, t0, r->T);
fe_add(r->T, t0, r->T); fe_add(r->T, t0, r->T);
} }
void ge_tobytes(unsigned char *s, const ge_p2 *h) { void ge_tobytes(unsigned char *s, const ge_p2 *h) {
fe recip; fe recip;
fe x; fe x;
fe y; fe y;
fe_invert(recip, h->Z); fe_invert(recip, h->Z);
fe_mul(x, h->X, recip); fe_mul(x, h->X, recip);
fe_mul(y, h->Y, recip); fe_mul(y, h->Y, recip);
fe_tobytes(s, y); fe_tobytes(s, y);
s[31] ^= fe_isnegative(x) << 7; s[31] ^= fe_isnegative(x) << 7;
} }

View file

@ -19,36 +19,36 @@ Representations:
*/ */
typedef struct { typedef struct {
fe X; fe X;
fe Y; fe Y;
fe Z; fe Z;
} ge_p2; } ge_p2;
typedef struct { typedef struct {
fe X; fe X;
fe Y; fe Y;
fe Z; fe Z;
fe T; fe T;
} ge_p3; } ge_p3;
typedef struct { typedef struct {
fe X; fe X;
fe Y; fe Y;
fe Z; fe Z;
fe T; fe T;
} ge_p1p1; } ge_p1p1;
typedef struct { typedef struct {
fe yplusx; fe yplusx;
fe yminusx; fe yminusx;
fe xy2d; fe xy2d;
} ge_precomp; } ge_precomp;
typedef struct { typedef struct {
fe YplusX; fe YplusX;
fe YminusX; fe YminusX;
fe Z; fe Z;
fe T2d; fe T2d;
} ge_cached; } ge_cached;
void ge_p3_tobytes(unsigned char *s, const ge_p3 *h); void ge_p3_tobytes(unsigned char *s, const ge_p3 *h);

View file

@ -2,78 +2,79 @@
#include "fe.h" #include "fe.h"
void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) { void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
unsigned char e[32]; unsigned char e[32];
unsigned int i; unsigned int i;
fe x1;
fe x2;
fe z2;
fe x3;
fe z3;
fe tmp0;
fe tmp1;
int pos; fe x1;
unsigned int swap; fe x2;
unsigned int b; fe z2;
fe x3;
fe z3;
fe tmp0;
fe tmp1;
/* copy the private key and make sure it's valid */ int pos;
for (i = 0; i < 32; ++i) { unsigned int swap;
e[i] = private_key[i]; unsigned int b;
}
e[0] &= 248; /* copy the private key and make sure it's valid */
e[31] &= 63; for(i = 0; i < 32; ++i) {
e[31] |= 64; e[i] = private_key[i];
}
/* unpack the public key and convert edwards to montgomery */ e[0] &= 248;
/* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */ e[31] &= 63;
fe_frombytes(x1, public_key); e[31] |= 64;
fe_1(tmp1);
fe_add(tmp0, x1, tmp1);
fe_sub(tmp1, tmp1, x1);
fe_invert(tmp1, tmp1);
fe_mul(x1, tmp0, tmp1);
fe_1(x2); /* unpack the public key and convert edwards to montgomery */
fe_0(z2); /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
fe_copy(x3, x1); fe_frombytes(x1, public_key);
fe_1(z3); fe_1(tmp1);
fe_add(tmp0, x1, tmp1);
fe_sub(tmp1, tmp1, x1);
fe_invert(tmp1, tmp1);
fe_mul(x1, tmp0, tmp1);
swap = 0; fe_1(x2);
for (pos = 254; pos >= 0; --pos) { fe_0(z2);
b = e[pos / 8] >> (pos & 7); fe_copy(x3, x1);
b &= 1; fe_1(z3);
swap ^= b;
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
swap = b;
/* from montgomery.h */ swap = 0;
fe_sub(tmp0, x3, z3);
fe_sub(tmp1, x2, z2);
fe_add(x2, x2, z2);
fe_add(z2, x3, z3);
fe_mul(z3, tmp0, x2);
fe_mul(z2, z2, tmp1);
fe_sq(tmp0, tmp1);
fe_sq(tmp1, x2);
fe_add(x3, z3, z2);
fe_sub(z2, z3, z2);
fe_mul(x2, tmp1, tmp0);
fe_sub(tmp1, tmp1, tmp0);
fe_sq(z2, z2);
fe_mul121666(z3, tmp1);
fe_sq(x3, x3);
fe_add(tmp0, tmp0, z3);
fe_mul(z3, x1, z2);
fe_mul(z2, tmp1, tmp0);
}
fe_cswap(x2, x3, swap); for(pos = 254; pos >= 0; --pos) {
fe_cswap(z2, z3, swap); b = e[pos / 8] >> (pos & 7);
b &= 1;
swap ^= b;
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
swap = b;
fe_invert(z2, z2); /* from montgomery.h */
fe_mul(x2, x2, z2); fe_sub(tmp0, x3, z3);
fe_tobytes(shared_secret, x2); fe_sub(tmp1, x2, z2);
fe_add(x2, x2, z2);
fe_add(z2, x3, z3);
fe_mul(z3, tmp0, x2);
fe_mul(z2, z2, tmp1);
fe_sq(tmp0, tmp1);
fe_sq(tmp1, x2);
fe_add(x3, z3, z2);
fe_sub(z2, z3, z2);
fe_mul(x2, tmp1, tmp0);
fe_sub(tmp1, tmp1, tmp0);
fe_sq(z2, z2);
fe_mul121666(z3, tmp1);
fe_sq(x3, x3);
fe_add(tmp0, tmp0, z3);
fe_mul(z3, x1, z2);
fe_mul(z2, tmp1, tmp0);
}
fe_cswap(x2, x3, swap);
fe_cswap(z2, z3, swap);
fe_invert(z2, z2);
fe_mul(x2, x2, z2);
fe_tobytes(shared_secret, x2);
} }

View file

@ -4,13 +4,13 @@
void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) { void ed25519_create_keypair(unsigned char *public_key, unsigned char *private_key, const unsigned char *seed) {
ge_p3 A; ge_p3 A;
sha512(seed, 32, private_key); sha512(seed, 32, private_key);
private_key[0] &= 248; private_key[0] &= 248;
private_key[31] &= 63; private_key[31] &= 63;
private_key[31] |= 64; private_key[31] |= 64;
ge_scalarmult_base(&A, private_key); ge_scalarmult_base(&A, private_key);
ge_p3_tobytes(public_key, &A); ge_p3_tobytes(public_key, &A);
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,65 +14,65 @@
/* the K array */ /* the K array */
static const uint64_t K[80] = { static const uint64_t K[80] = {
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817) UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817)
}; };
/* Various logical functions */ /* Various logical functions */
#define ROR64c(x, y) \ #define ROR64c(x, y) \
( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \ ( ((((x)&UINT64_C(0xFFFFFFFFFFFFFFFF))>>((uint64_t)(y)&UINT64_C(63))) | \
((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF)) ((x)<<((uint64_t)(64-((y)&UINT64_C(63)))))) & UINT64_C(0xFFFFFFFFFFFFFFFF))
#define STORE64H(x, y) \ #define STORE64H(x, y) \
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
#define LOAD64H(x, y) \ #define LOAD64H(x, y) \
{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \ { x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \ (((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \ (((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); } (((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
#define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Ch(x,y,z) (z ^ (x & (y ^ z)))
@ -84,58 +84,57 @@ static const uint64_t K[80] = {
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
#ifndef MIN #ifndef MIN
#define MIN(x, y) ( ((x)<(y))?(x):(y) ) #define MIN(x, y) ( ((x)<(y))?(x):(y) )
#endif #endif
/* compress 1024-bits */ /* compress 1024-bits */
static int sha512_compress(sha512_context *md, const unsigned char *buf) static int sha512_compress(sha512_context *md, const unsigned char *buf) {
{ uint64_t S[8], W[80], t0, t1;
uint64_t S[8], W[80], t0, t1; int i;
int i;
/* copy state into S */ /* copy state into S */
for (i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
S[i] = md->state[i]; S[i] = md->state[i];
} }
/* copy the state into 1024-bits into W[0..15] */ /* copy the state into 1024-bits into W[0..15] */
for (i = 0; i < 16; i++) { for(i = 0; i < 16; i++) {
LOAD64H(W[i], buf + (8*i)); LOAD64H(W[i], buf + (8 * i));
} }
/* fill W[16..79] */ /* fill W[16..79] */
for (i = 16; i < 80; i++) { for(i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
} }
/* Compress */ /* Compress */
#define RND(a,b,c,d,e,f,g,h,i) \ #define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c);\ t1 = Sigma0(a) + Maj(a, b, c);\
d += t0; \ d += t0; \
h = t0 + t1; h = t0 + t1;
for (i = 0; i < 80; i += 8) { for(i = 0; i < 80; i += 8) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7);
} }
#undef RND #undef RND
/* feedback */ /* feedback */
for (i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
md->state[i] = md->state[i] + S[i]; md->state[i] = md->state[i] + S[i];
} }
return 0; return 0;
} }
@ -144,21 +143,23 @@ static int sha512_compress(sha512_context *md, const unsigned char *buf)
@param md The hash state you wish to initialize @param md The hash state you wish to initialize
@return 0 if successful @return 0 if successful
*/ */
int sha512_init(sha512_context * md) { int sha512_init(sha512_context *md) {
if (md == NULL) return 1; if(md == NULL) {
return 1;
}
md->curlen = 0; md->curlen = 0;
md->length = 0; md->length = 0;
md->state[0] = UINT64_C(0x6a09e667f3bcc908); md->state[0] = UINT64_C(0x6a09e667f3bcc908);
md->state[1] = UINT64_C(0xbb67ae8584caa73b); md->state[1] = UINT64_C(0xbb67ae8584caa73b);
md->state[2] = UINT64_C(0x3c6ef372fe94f82b); md->state[2] = UINT64_C(0x3c6ef372fe94f82b);
md->state[3] = UINT64_C(0xa54ff53a5f1d36f1); md->state[3] = UINT64_C(0xa54ff53a5f1d36f1);
md->state[4] = UINT64_C(0x510e527fade682d1); md->state[4] = UINT64_C(0x510e527fade682d1);
md->state[5] = UINT64_C(0x9b05688c2b3e6c1f); md->state[5] = UINT64_C(0x9b05688c2b3e6c1f);
md->state[6] = UINT64_C(0x1f83d9abfb41bd6b); md->state[6] = UINT64_C(0x1f83d9abfb41bd6b);
md->state[7] = UINT64_C(0x5be0cd19137e2179); md->state[7] = UINT64_C(0x5be0cd19137e2179);
return 0; return 0;
} }
/** /**
@ -168,46 +169,57 @@ int sha512_init(sha512_context * md) {
@param inlen The length of the data (octets) @param inlen The length of the data (octets)
@return 0 if successful @return 0 if successful
*/ */
int sha512_update(sha512_context *md, const void *vin, size_t inlen) int sha512_update(sha512_context *md, const void *vin, size_t inlen) {
{ const unsigned char *in = vin;
const unsigned char *in = vin; size_t n;
size_t n; size_t i;
size_t i; int err;
int err;
if (md == NULL) return 1;
if (in == NULL) return 1;
if (md->curlen > sizeof(md->buf)) {
return 1;
}
while (inlen > 0) {
if (md->curlen == 0 && inlen >= 128) {
if ((err = sha512_compress (md, in)) != 0) {
return err;
}
md->length += 128 * 8;
in += 128;
inlen -= 128;
} else {
n = MIN(inlen, (128 - md->curlen));
for (i = 0; i < n; i++) { if(md == NULL) {
md->buf[i + md->curlen] = in[i]; return 1;
} }
if(in == NULL) {
return 1;
}
if(md->curlen > sizeof(md->buf)) {
return 1;
}
while(inlen > 0) {
if(md->curlen == 0 && inlen >= 128) {
if((err = sha512_compress(md, in)) != 0) {
return err;
}
md->length += 128 * 8;
in += 128;
inlen -= 128;
} else {
n = MIN(inlen, (128 - md->curlen));
for(i = 0; i < n; i++) {
md->buf[i + md->curlen] = in[i];
}
md->curlen += n; md->curlen += n;
in += n; in += n;
inlen -= n; inlen -= n;
if (md->curlen == 128) {
if ((err = sha512_compress (md, md->buf)) != 0) { if(md->curlen == 128) {
return err; if((err = sha512_compress(md, md->buf)) != 0) {
} return err;
md->length += 8*128; }
md->curlen = 0;
} md->length += 8 * 128;
} md->curlen = 0;
} }
return 0; }
}
return 0;
} }
/** /**
@ -216,62 +228,76 @@ int sha512_update(sha512_context *md, const void *vin, size_t inlen)
@param out [out] The destination of the hash (64 bytes) @param out [out] The destination of the hash (64 bytes)
@return 0 if successful @return 0 if successful
*/ */
int sha512_final(sha512_context * md, void *vout) int sha512_final(sha512_context *md, void *vout) {
{ int i;
int i; unsigned char *out = vout;
unsigned char *out = vout;
if (md == NULL) return 1; if(md == NULL) {
if (out == NULL) return 1; return 1;
}
if (md->curlen >= sizeof(md->buf)) { if(out == NULL) {
return 1; return 1;
} }
/* increase the length of the message */ if(md->curlen >= sizeof(md->buf)) {
md->length += md->curlen * UINT64_C(8); return 1;
}
/* append the '1' bit */ /* increase the length of the message */
md->buf[md->curlen++] = (unsigned char)0x80; md->length += md->curlen * UINT64_C(8);
/* if the length is currently above 112 bytes we append zeros /* append the '1' bit */
* then compress. Then we can fall back to padding zeros and length md->buf[md->curlen++] = (unsigned char)0x80;
* encoding like normal.
*/
if (md->curlen > 112) {
while (md->curlen < 128) {
md->buf[md->curlen++] = (unsigned char)0;
}
sha512_compress(md, md->buf);
md->curlen = 0;
}
/* pad upto 120 bytes of zeroes /* if the length is currently above 112 bytes we append zeros
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash * then compress. Then we can fall back to padding zeros and length
* > 2^64 bits of data... :-) * encoding like normal.
*/ */
while (md->curlen < 120) { if(md->curlen > 112) {
md->buf[md->curlen++] = (unsigned char)0; while(md->curlen < 128) {
} md->buf[md->curlen++] = (unsigned char)0;
}
/* store length */ sha512_compress(md, md->buf);
STORE64H(md->length, md->buf+120); md->curlen = 0;
sha512_compress(md, md->buf); }
/* copy output */ /* pad up to 120 bytes of zeroes
for (i = 0; i < 8; i++) { * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
STORE64H(md->state[i], out+(8*i)); * > 2^64 bits of data... :-)
} */
while(md->curlen < 120) {
md->buf[md->curlen++] = (unsigned char)0;
}
return 0; /* store length */
STORE64H(md->length, md->buf + 120);
sha512_compress(md, md->buf);
/* copy output */
for(i = 0; i < 8; i++) {
STORE64H(md->state[i], out + (8 * i));
}
return 0;
} }
int sha512(const void *message, size_t message_len, void *out) int sha512(const void *message, size_t message_len, void *out) {
{ sha512_context ctx;
sha512_context ctx; int ret;
int ret;
if ((ret = sha512_init(&ctx))) return ret; if((ret = sha512_init(&ctx))) {
if ((ret = sha512_update(&ctx, message, message_len))) return ret; return ret;
if ((ret = sha512_final(&ctx, out))) return ret; }
return 0;
if((ret = sha512_update(&ctx, message, message_len))) {
return ret;
}
if((ret = sha512_final(&ctx, out))) {
return ret;
}
return 0;
} }

View file

@ -7,15 +7,15 @@
/* state */ /* state */
typedef struct sha512_context_ { typedef struct sha512_context_ {
uint64_t length, state[8]; uint64_t length, state[8];
size_t curlen; size_t curlen;
unsigned char buf[128]; unsigned char buf[128];
} sha512_context; } sha512_context;
int sha512_init(sha512_context * md); int sha512_init(sha512_context *md);
int sha512_final(sha512_context * md, void *out); int sha512_final(sha512_context *md, void *out);
int sha512_update(sha512_context * md, const void *in, size_t inlen); int sha512_update(sha512_context *md, const void *in, size_t inlen);
int sha512(const void *message, size_t message_len, void *out); int sha512(const void *message, size_t message_len, void *out);
#endif #endif

View file

@ -5,27 +5,27 @@
void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) { void ed25519_sign(unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key, const unsigned char *private_key) {
sha512_context hash; sha512_context hash;
unsigned char hram[64]; unsigned char hram[64];
unsigned char r[64]; unsigned char r[64];
ge_p3 R; ge_p3 R;
sha512_init(&hash); sha512_init(&hash);
sha512_update(&hash, private_key + 32, 32); sha512_update(&hash, private_key + 32, 32);
sha512_update(&hash, message, message_len); sha512_update(&hash, message, message_len);
sha512_final(&hash, r); sha512_final(&hash, r);
sc_reduce(r); sc_reduce(r);
ge_scalarmult_base(&R, r); ge_scalarmult_base(&R, r);
ge_p3_tobytes(signature, &R); ge_p3_tobytes(signature, &R);
sha512_init(&hash); sha512_init(&hash);
sha512_update(&hash, signature, 32); sha512_update(&hash, signature, 32);
sha512_update(&hash, public_key, 32); sha512_update(&hash, public_key, 32);
sha512_update(&hash, message, message_len); sha512_update(&hash, message, message_len);
sha512_final(&hash, hram); sha512_final(&hash, hram);
sc_reduce(hram); sc_reduce(hram);
sc_muladd(signature + 32, hram, private_key, r); sc_muladd(signature + 32, hram, private_key, r);
} }

View file

@ -4,74 +4,74 @@
#include "sc.h" #include "sc.h"
static int consttime_equal(const unsigned char *x, const unsigned char *y) { static int consttime_equal(const unsigned char *x, const unsigned char *y) {
unsigned char r = 0; unsigned char r = 0;
r = x[0] ^ y[0]; r = x[0] ^ y[0];
#define F(i) r |= x[i] ^ y[i] #define F(i) r |= x[i] ^ y[i]
F(1); F(1);
F(2); F(2);
F(3); F(3);
F(4); F(4);
F(5); F(5);
F(6); F(6);
F(7); F(7);
F(8); F(8);
F(9); F(9);
F(10); F(10);
F(11); F(11);
F(12); F(12);
F(13); F(13);
F(14); F(14);
F(15); F(15);
F(16); F(16);
F(17); F(17);
F(18); F(18);
F(19); F(19);
F(20); F(20);
F(21); F(21);
F(22); F(22);
F(23); F(23);
F(24); F(24);
F(25); F(25);
F(26); F(26);
F(27); F(27);
F(28); F(28);
F(29); F(29);
F(30); F(30);
F(31); F(31);
#undef F #undef F
return !r; return !r;
} }
int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) { int ed25519_verify(const unsigned char *signature, const unsigned char *message, size_t message_len, const unsigned char *public_key) {
unsigned char h[64]; unsigned char h[64];
unsigned char checker[32]; unsigned char checker[32];
sha512_context hash; sha512_context hash;
ge_p3 A; ge_p3 A;
ge_p2 R; ge_p2 R;
if (signature[63] & 224) { if(signature[63] & 224) {
return 0; return 0;
} }
if (ge_frombytes_negate_vartime(&A, public_key) != 0) { if(ge_frombytes_negate_vartime(&A, public_key) != 0) {
return 0; return 0;
} }
sha512_init(&hash); sha512_init(&hash);
sha512_update(&hash, signature, 32); sha512_update(&hash, signature, 32);
sha512_update(&hash, public_key, 32); sha512_update(&hash, public_key, 32);
sha512_update(&hash, message, message_len); sha512_update(&hash, message, message_len);
sha512_final(&hash, h); sha512_final(&hash, h);
sc_reduce(h);
ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
ge_tobytes(checker, &R);
if (!consttime_equal(checker, signature)) { sc_reduce(h);
return 0; ge_double_scalarmult_vartime(&R, h, &A, signature + 32);
} ge_tobytes(checker, &R);
return 1; if(!consttime_equal(checker, signature)) {
return 0;
}
return 1;
} }

View file

@ -40,13 +40,15 @@ static int edge_weight_compare(const edge_t *a, const edge_t *b) {
result = a->weight - b->weight; result = a->weight - b->weight;
if(result) if(result) {
return result; return result;
}
result = strcmp(a->from->name, b->from->name); result = strcmp(a->from->name, b->from->name);
if(result) if(result) {
return result; return result;
}
return strcmp(a->to->name, b->to->name); return strcmp(a->to->name, b->to->name);
} }
@ -86,13 +88,15 @@ void edge_add(edge_t *e) {
e->reverse = lookup_edge(e->to, e->from); e->reverse = lookup_edge(e->to, e->from);
if(e->reverse) if(e->reverse) {
e->reverse->reverse = e; e->reverse->reverse = e;
}
} }
void edge_del(edge_t *e) { void edge_del(edge_t *e) {
if(e->reverse) if(e->reverse) {
e->reverse->reverse = NULL; e->reverse->reverse = NULL;
}
splay_delete(edge_weight_tree, e); splay_delete(edge_weight_tree, e);
splay_delete(e->from->edge_tree, e); splay_delete(e->from->edge_tree, e);
@ -111,11 +115,11 @@ bool dump_edges(connection_t *c) {
for splay_each(node_t, n, node_tree) { for splay_each(node_t, n, node_tree) {
for splay_each(edge_t, e, n->edge_tree) { for splay_each(edge_t, e, n->edge_tree) {
char *address = sockaddr2hostname(&e->address); char *address = sockaddr2hostname(&e->address);
char* local_address = sockaddr2hostname(&e->local_address); char *local_address = sockaddr2hostname(&e->local_address);
send_request(c, "%d %d %s %s %s %s %x %d", send_request(c, "%d %d %s %s %s %s %x %d",
CONTROL, REQ_DUMP_EDGES, CONTROL, REQ_DUMP_EDGES,
e->from->name, e->to->name, address, e->from->name, e->to->name, address,
local_address, e->options, e->weight); local_address, e->options, e->weight);
free(address); free(address);
free(local_address); free(local_address);
} }

View file

@ -1,3 +1,6 @@
#ifndef TINC_EDGE_H
#define TINC_EDGE_H
/* /*
edge.h -- header for edge.c edge.h -- header for edge.c
Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>, Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_EDGE_H__
#define __TINC_EDGE_H__
#include "splay_tree.h" #include "splay_tree.h"
#include "connection.h" #include "connection.h"
#include "net.h" #include "net.h"
@ -43,13 +43,13 @@ extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sor
extern void init_edges(void); extern void init_edges(void);
extern void exit_edges(void); extern void exit_edges(void);
extern edge_t *new_edge(void) __attribute__ ((__malloc__)); extern edge_t *new_edge(void) __attribute__((__malloc__));
extern void free_edge(edge_t *); extern void free_edge(edge_t *e);
extern splay_tree_t *new_edge_tree(void) __attribute__ ((__malloc__)); extern splay_tree_t *new_edge_tree(void) __attribute__((__malloc__));
extern void free_edge_tree(splay_tree_t *); extern void free_edge_tree(splay_tree_t *edge_tree);
extern void edge_add(edge_t *); extern void edge_add(edge_t *e);
extern void edge_del(edge_t *); extern void edge_del(edge_t *e);
extern edge_t *lookup_edge(struct node_t *, struct node_t *); extern edge_t *lookup_edge(struct node_t *from, struct node_t *to);
extern bool dump_edges(struct connection_t *); extern bool dump_edges(struct connection_t *c);
#endif /* __TINC_EDGE_H__ */ #endif

View file

@ -1,3 +1,6 @@
#ifndef TINC_ETHERNET_H
#define TINC_ETHERNET_H
/* /*
ethernet.h -- missing Ethernet related definitions ethernet.h -- missing Ethernet related definitions
Copyright (C) 2005 Ivo Timmermans Copyright (C) 2005 Ivo Timmermans
@ -18,9 +21,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_ETHERNET_H__
#define __TINC_ETHERNET_H__
#ifndef ETH_ALEN #ifndef ETH_ALEN
#define ETH_ALEN 6 #define ETH_ALEN 6
#endif #endif
@ -63,7 +63,7 @@ struct ether_header {
uint8_t ether_dhost[ETH_ALEN]; uint8_t ether_dhost[ETH_ALEN];
uint8_t ether_shost[ETH_ALEN]; uint8_t ether_shost[ETH_ALEN];
uint16_t ether_type; uint16_t ether_type;
} __attribute__ ((__gcc_struct__, __packed__)); } __attribute__((__gcc_struct__, __packed__));
#endif #endif
#ifndef HAVE_STRUCT_ARPHDR #ifndef HAVE_STRUCT_ARPHDR
@ -73,7 +73,7 @@ struct arphdr {
uint8_t ar_hln; uint8_t ar_hln;
uint8_t ar_pln; uint8_t ar_pln;
uint16_t ar_op; uint16_t ar_op;
} __attribute__ ((__gcc_struct__, __packed__)); } __attribute__((__gcc_struct__, __packed__));
#define ARPOP_REQUEST 1 #define ARPOP_REQUEST 1
#define ARPOP_REPLY 2 #define ARPOP_REPLY 2
@ -91,7 +91,7 @@ struct ether_arp {
uint8_t arp_spa[4]; uint8_t arp_spa[4];
uint8_t arp_tha[ETH_ALEN]; uint8_t arp_tha[ETH_ALEN];
uint8_t arp_tpa[4]; uint8_t arp_tpa[4];
} __attribute__ ((__gcc_struct__, __packed__)); } __attribute__((__gcc_struct__, __packed__));
#define arp_hrd ea_hdr.ar_hrd #define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro #define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln #define arp_hln ea_hdr.ar_hln
@ -99,4 +99,4 @@ struct ether_arp {
#define arp_op ea_hdr.ar_op #define arp_op ea_hdr.ar_op
#endif #endif
#endif /* __TINC_ETHERNET_H__ */ #endif

View file

@ -41,25 +41,47 @@ static int io_compare(const io_t *a, const io_t *b) {
#ifndef HAVE_MINGW #ifndef HAVE_MINGW
return a->fd - b->fd; return a->fd - b->fd;
#else #else
return a->event - b->event;
if(a->event < b->event) {
return -1;
}
if(a->event > b->event) {
return 1;
}
return 0;
#endif #endif
} }
static int timeout_compare(const timeout_t *a, const timeout_t *b) { static int timeout_compare(const timeout_t *a, const timeout_t *b) {
struct timeval diff; struct timeval diff;
timersub(&a->tv, &b->tv, &diff); timersub(&a->tv, &b->tv, &diff);
if(diff.tv_sec < 0)
if(diff.tv_sec < 0) {
return -1; return -1;
if(diff.tv_sec > 0) }
if(diff.tv_sec > 0) {
return 1; return 1;
if(diff.tv_usec < 0) }
if(diff.tv_usec < 0) {
return -1; return -1;
if(diff.tv_usec > 0) }
if(diff.tv_usec > 0) {
return 1; return 1;
if(a < b) }
if(a < b) {
return -1; return -1;
if(a > b) }
if(a > b) {
return 1; return 1;
}
return 0; return 0;
} }
@ -67,16 +89,21 @@ static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare};
static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare}; static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare};
void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) { void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
if(io->cb) if(io->cb) {
return; return;
}
io->fd = fd; io->fd = fd;
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
if (io->fd != -1) {
if(io->fd != -1) {
io->event = WSACreateEvent(); io->event = WSACreateEvent();
if (io->event == WSA_INVALID_EVENT)
if(io->event == WSA_INVALID_EVENT) {
abort(); abort();
}
} }
event_count++; event_count++;
#endif #endif
io->cb = cb; io->cb = cb;
@ -85,8 +112,9 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
io_set(io, flags); io_set(io, flags);
if(!splay_insert_node(&io_tree, &io->node)) if(!splay_insert_node(&io_tree, &io->node)) {
abort(); abort();
}
} }
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
@ -97,41 +125,60 @@ void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
#endif #endif
void io_set(io_t *io, int flags) { void io_set(io_t *io, int flags) {
if (flags == io->flags) if(flags == io->flags) {
return; return;
}
io->flags = flags; io->flags = flags;
if (io->fd == -1)
if(io->fd == -1) {
return; return;
}
#ifndef HAVE_MINGW #ifndef HAVE_MINGW
if(flags & IO_READ)
FD_SET(io->fd, &readfds);
else
FD_CLR(io->fd, &readfds);
if(flags & IO_WRITE) if(flags & IO_READ) {
FD_SET(io->fd, &readfds);
} else {
FD_CLR(io->fd, &readfds);
}
if(flags & IO_WRITE) {
FD_SET(io->fd, &writefds); FD_SET(io->fd, &writefds);
else } else {
FD_CLR(io->fd, &writefds); FD_CLR(io->fd, &writefds);
}
#else #else
long events = 0; long events = 0;
if (flags & IO_WRITE)
if(flags & IO_WRITE) {
events |= WRITE_EVENTS; events |= WRITE_EVENTS;
if (flags & IO_READ) }
if(flags & IO_READ) {
events |= READ_EVENTS; events |= READ_EVENTS;
if (WSAEventSelect(io->fd, io->event, events) != 0) }
if(WSAEventSelect(io->fd, io->event, events) != 0) {
abort(); abort();
}
#endif #endif
} }
void io_del(io_t *io) { void io_del(io_t *io) {
if(!io->cb) if(!io->cb) {
return; return;
}
io_set(io, 0); io_set(io, 0);
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
if (io->fd != -1 && WSACloseEvent(io->event) == FALSE)
if(io->fd != -1 && WSACloseEvent(io->event) == FALSE) {
abort(); abort();
}
event_count--; event_count--;
#endif #endif
@ -148,25 +195,31 @@ void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval
} }
void timeout_set(timeout_t *timeout, struct timeval *tv) { void timeout_set(timeout_t *timeout, struct timeval *tv) {
if(timerisset(&timeout->tv)) if(timerisset(&timeout->tv)) {
splay_unlink_node(&timeout_tree, &timeout->node); splay_unlink_node(&timeout_tree, &timeout->node);
}
if(!now.tv_sec) if(!now.tv_sec) {
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
}
timeradd(&now, tv, &timeout->tv); timeradd(&now, tv, &timeout->tv);
if(!splay_insert_node(&timeout_tree, &timeout->node)) if(!splay_insert_node(&timeout_tree, &timeout->node)) {
abort(); abort();
}
} }
void timeout_del(timeout_t *timeout) { void timeout_del(timeout_t *timeout) {
if(!timeout->cb) if(!timeout->cb) {
return; return;
}
splay_unlink_node(&timeout_tree, &timeout->node); splay_unlink_node(&timeout_tree, &timeout->node);
timeout->cb = 0; timeout->cb = 0;
timeout->tv = (struct timeval){0, 0}; timeout->tv = (struct timeval) {
0, 0
};
} }
#ifndef HAVE_MINGW #ifndef HAVE_MINGW
@ -184,41 +237,54 @@ static void signal_handler(int signum) {
} }
static void signalio_handler(void *data, int flags) { static void signalio_handler(void *data, int flags) {
(void)data;
(void)flags;
unsigned char signum; unsigned char signum;
if(read(pipefd[0], &signum, 1) != 1)
return;
signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum})); if(read(pipefd[0], &signum, 1) != 1) {
if(sig) return;
}
signal_t *sig = splay_search(&signal_tree, &((signal_t) {
.signum = signum
}));
if(sig) {
sig->cb(sig->data); sig->cb(sig->data);
}
} }
static void pipe_init(void) { static void pipe_init(void) {
if(!pipe(pipefd)) if(!pipe(pipefd)) {
io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ); io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
}
} }
void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) { void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
if(sig->cb) if(sig->cb) {
return; return;
}
sig->cb = cb; sig->cb = cb;
sig->data = data; sig->data = data;
sig->signum = signum; sig->signum = signum;
sig->node.data = sig; sig->node.data = sig;
if(pipefd[0] == -1) if(pipefd[0] == -1) {
pipe_init(); pipe_init();
}
signal(sig->signum, signal_handler); signal(sig->signum, signal_handler);
if(!splay_insert_node(&signal_tree, &sig->node)) if(!splay_insert_node(&signal_tree, &sig->node)) {
abort(); abort();
}
} }
void signal_del(signal_t *sig) { void signal_del(signal_t *sig) {
if(!sig->cb) if(!sig->cb) {
return; return;
}
signal(sig->signum, SIG_DFL); signal(sig->signum, SIG_DFL);
@ -227,7 +293,7 @@ void signal_del(signal_t *sig) {
} }
#endif #endif
static struct timeval * get_time_remaining(struct timeval *diff) { static struct timeval *get_time_remaining(struct timeval *diff) {
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
struct timeval *tv = NULL; struct timeval *tv = NULL;
@ -237,8 +303,10 @@ static struct timeval * get_time_remaining(struct timeval *diff) {
if(diff->tv_sec < 0) { if(diff->tv_sec < 0) {
timeout->cb(timeout->data); timeout->cb(timeout->data);
if(timercmp(&timeout->tv, &now, <))
if(timercmp(&timeout->tv, &now, <)) {
timeout_del(timeout); timeout_del(timeout);
}
} else { } else {
tv = diff; tv = diff;
break; break;
@ -258,8 +326,8 @@ bool event_loop(void) {
while(running) { while(running) {
struct timeval diff; struct timeval diff;
struct timeval *tv = get_time_remaining(&diff); struct timeval *tv = get_time_remaining(&diff);
memcpy(&readable, &readfds, sizeof readable); memcpy(&readable, &readfds, sizeof(readable));
memcpy(&writable, &writefds, sizeof writable); memcpy(&writable, &writefds, sizeof(writable));
int fds = 0; int fds = 0;
@ -271,39 +339,48 @@ bool event_loop(void) {
int n = select(fds, &readable, &writable, NULL, tv); int n = select(fds, &readable, &writable, NULL, tv);
if(n < 0) { if(n < 0) {
if(sockwouldblock(sockerrno)) if(sockwouldblock(sockerrno)) {
continue; continue;
else } else {
return false; return false;
}
} }
if(!n) if(!n) {
continue; continue;
}
unsigned int curgen = io_tree.generation;
for splay_each(io_t, io, &io_tree) { for splay_each(io_t, io, &io_tree) {
if(FD_ISSET(io->fd, &writable)) if(FD_ISSET(io->fd, &writable)) {
io->cb(io->data, IO_WRITE); io->cb(io->data, IO_WRITE);
else if(FD_ISSET(io->fd, &readable)) } else if(FD_ISSET(io->fd, &readable)) {
io->cb(io->data, IO_READ); io->cb(io->data, IO_READ);
else } else {
continue; continue;
}
/* /*
There are scenarios in which the callback will remove another io_t from the tree There are scenarios in which the callback will remove another io_t from the tree
(e.g. closing a double connection). Since splay_each does not support that, we (e.g. closing a double connection). Since splay_each does not support that, we
need to exit the loop now. That's okay, since any remaining events will get picked need to exit the loop if that happens. That's okay, since any remaining events will
up by the next select() call. get picked up by the next select() call.
*/ */
break; if(curgen != io_tree.generation) {
break;
}
} }
} }
#else #else
while (running) {
while(running) {
struct timeval diff; struct timeval diff;
struct timeval *tv = get_time_remaining(&diff); struct timeval *tv = get_time_remaining(&diff);
DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE; DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE;
if (!event_count) { if(!event_count) {
Sleep(timeout_ms); Sleep(timeout_ms);
continue; continue;
} }
@ -318,54 +395,90 @@ bool event_loop(void) {
Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on Note that technically FD_CLOSE has the same problem, but it's okay because user code does not rely on
this event being fired again if ignored. this event being fired again if ignored.
*/ */
io_t* writeable_io = NULL; unsigned int curgen = io_tree.generation;
for splay_each(io_t, io, &io_tree)
if (io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) { for splay_each(io_t, io, &io_tree) {
writeable_io = io; if(io->flags & IO_WRITE && send(io->fd, NULL, 0, 0) == 0) {
break; io->cb(io->data, IO_WRITE);
if(curgen != io_tree.generation) {
break;
}
} }
if (writeable_io) {
writeable_io->cb(writeable_io->data, IO_WRITE);
continue;
} }
WSAEVENT* events = xmalloc(event_count * sizeof(*events)); if(event_count > WSA_MAXIMUM_WAIT_EVENTS) {
WSASetLastError(WSA_INVALID_PARAMETER);
return(false);
}
WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS];
io_t *io_map[WSA_MAXIMUM_WAIT_EVENTS];
DWORD event_index = 0; DWORD event_index = 0;
for splay_each(io_t, io, &io_tree) { for splay_each(io_t, io, &io_tree) {
events[event_index] = io->event; events[event_index] = io->event;
io_map[event_index] = io;
event_index++; event_index++;
} }
DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE); /*
* If the generation number changes due to event addition
* or removal by a callback we restart the loop.
*/
curgen = io_tree.generation;
WSAEVENT event; for(DWORD event_offset = 0; event_offset < event_count;) {
if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count) DWORD result = WSAWaitForMultipleEvents(event_count - event_offset, &events[event_offset], FALSE, timeout_ms, FALSE);
event = events[result - WSA_WAIT_EVENT_0];
free(events);
if (result == WSA_WAIT_TIMEOUT)
continue;
if (result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count)
return false;
io_t *io = splay_search(&io_tree, &((io_t){.event = event})); if(result == WSA_WAIT_TIMEOUT) {
if (!io) break;
abort(); }
if (io->fd == -1) { if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) {
io->cb(io->data, 0); return(false);
} else { }
WSANETWORKEVENTS network_events;
if (WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) /* Look up io in the map by index. */
return false; event_index = result - WSA_WAIT_EVENT_0 + event_offset;
if (network_events.lNetworkEvents & READ_EVENTS) io_t *io = io_map[event_index];
io->cb(io->data, IO_READ);
/* if(io->fd == -1) {
The fd might be available for write too. However, if we already fired the read callback, that io->cb(io->data, 0);
callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the
write callback here. Instead, we loop back and let the writable io loop above handle it. if(curgen != io_tree.generation) {
*/ break;
}
} else {
WSANETWORKEVENTS network_events;
if(WSAEnumNetworkEvents(io->fd, io->event, &network_events) != 0) {
return(false);
}
if(network_events.lNetworkEvents & READ_EVENTS) {
io->cb(io->data, IO_READ);
if(curgen != io_tree.generation) {
break;
}
}
/*
The fd might be available for write too. However, if we already fired the read callback, that
callback might have deleted the io (e.g. through terminate_connection()), so we can't fire the
write callback here. Instead, we loop back and let the writable io loop above handle it.
*/
}
/* Continue checking the rest of the events. */
event_offset = event_index + 1;
/* Just poll the next time through. */
timeout_ms = 0;
} }
} }
#endif #endif
return true; return true;

View file

@ -1,3 +1,6 @@
#ifndef TINC_EVENT_H
#define TINC_EVENT_H
/* /*
event.h -- I/O, timeout and signal event handling event.h -- I/O, timeout and signal event handling
Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2012-2013 Guus Sliepen <guus@tinc-vpn.org>
@ -17,9 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_EVENT_H__
#define __TINC_EVENT_H__
#include "splay_tree.h" #include "splay_tree.h"
#define IO_READ 1 #define IO_READ 1
@ -58,7 +58,7 @@ extern struct timeval now;
extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags); extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags);
#ifdef HAVE_MINGW #ifdef HAVE_MINGW
extern void io_add_event(io_t *io, io_cb_t cb, void* data, WSAEVENT event); extern void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event);
#endif #endif
extern void io_del(io_t *io); extern void io_del(io_t *io);
extern void io_set(io_t *io, int flags); extern void io_set(io_t *io, int flags);

View file

@ -64,7 +64,7 @@ static void close_device(void) {
} }
static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) { static inline uint16_t get_ip_ethertype(vpn_packet_t *packet) {
switch (DATA(packet)[ETH_HLEN] >> 4) { switch(DATA(packet)[ETH_HLEN] >> 4) {
case 4: case 4:
return ETH_P_IP; return ETH_P_IP;
@ -85,12 +85,14 @@ static inline void set_etherheader(vpn_packet_t *packet, uint16_t ethertype) {
static bool read_packet(vpn_packet_t *packet) { static bool read_packet(vpn_packet_t *packet) {
int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN); int lenin = read(device_fd, DATA(packet) + ETH_HLEN, MTU - ETH_HLEN);
if(lenin <= 0) { if(lenin <= 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno)); logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading from fd/%d: %s!", device_fd, strerror(errno));
return false; return false;
} }
uint16_t ethertype = get_ip_ethertype(packet); uint16_t ethertype = get_ip_ethertype(packet);
if(ethertype == ETH_P_MAX) { if(ethertype == ETH_P_MAX) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd); logger(DEBUG_TRAFFIC, LOG_ERR, "Unknown IP version while reading packet from fd/%d!", device_fd);
return false; return false;

View file

@ -32,31 +32,43 @@
#include "utils.h" #include "utils.h"
static bool ask_fix(void) { static bool ask_fix(void) {
if(force) if(force) {
return true; return true;
if(!tty) }
if(!tty) {
return false; return false;
}
again: again:
fprintf(stderr, "Fix y/n? "); fprintf(stderr, "Fix y/n? ");
char buf[1024]; char buf[1024];
if(!fgets(buf, sizeof buf, stdin)) {
if(!fgets(buf, sizeof(buf), stdin)) {
tty = false; tty = false;
return false; return false;
} }
if(buf[0] == 'y' || buf[0] == 'Y')
if(buf[0] == 'y' || buf[0] == 'Y') {
return true; return true;
if(buf[0] == 'n' || buf[0] == 'N') }
if(buf[0] == 'n' || buf[0] == 'N') {
return false; return false;
}
goto again; goto again;
} }
static void print_tinc_cmd(const char *argv0, const char *format, ...) { static void print_tinc_cmd(const char *argv0, const char *format, ...) {
if(confbasegiven) if(confbasegiven) {
fprintf(stderr, "%s -c %s ", argv0, confbase); fprintf(stderr, "%s -c %s ", argv0, confbase);
else if(netname) } else if(netname) {
fprintf(stderr, "%s -n %s ", argv0, netname); fprintf(stderr, "%s -n %s ", argv0, netname);
else } else {
fprintf(stderr, "%s ", argv0); fprintf(stderr, "%s ", argv0);
}
va_list va; va_list va;
va_start(va, format); va_start(va, format);
vfprintf(stderr, format, va); vfprintf(stderr, format, va);
@ -67,13 +79,19 @@ static void print_tinc_cmd(const char *argv0, const char *format, ...) {
static int strtailcmp(const char *str, const char *tail) { static int strtailcmp(const char *str, const char *tail) {
size_t slen = strlen(str); size_t slen = strlen(str);
size_t tlen = strlen(tail); size_t tlen = strlen(tail);
if(tlen > slen)
if(tlen > slen) {
return -1; return -1;
}
return memcmp(str + slen - tlen, tail, tlen); return memcmp(str + slen - tlen, tail, tlen);
} }
static void check_conffile(const char *fname, bool server) { static void check_conffile(const char *fname, bool server) {
(void)server;
FILE *f = fopen(fname, "r"); FILE *f = fopen(fname, "r");
if(!f) { if(!f) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: cannot read %s: %s\n", fname, strerror(errno));
return; return;
@ -84,12 +102,14 @@ static void check_conffile(const char *fname, bool server) {
bool skip = false; bool skip = false;
const int maxvariables = 50; const int maxvariables = 50;
int count[maxvariables]; int count[maxvariables];
memset(count, 0, sizeof count); memset(count, 0, sizeof(count));
while(fgets(line, sizeof line, f)) { while(fgets(line, sizeof(line), f)) {
if(skip) { if(skip) {
if(!strncmp(line, "-----END", 8)) if(!strncmp(line, "-----END", 8)) {
skip = false; skip = false;
}
continue; continue;
} else { } else {
if(!strncmp(line, "-----BEGIN", 10)) { if(!strncmp(line, "-----BEGIN", 10)) {
@ -105,26 +125,32 @@ static void check_conffile(const char *fname, bool server) {
lineno++; lineno++;
eol = line + strlen(line); eol = line + strlen(line);
while(strchr("\t \r\n", *--eol))
*eol = '\0';
if(!line[0] || line[0] == '#') while(strchr("\t \r\n", *--eol)) {
*eol = '\0';
}
if(!line[0] || line[0] == '#') {
continue; continue;
}
len = strcspn(value, "\t ="); len = strcspn(value, "\t =");
value += len; value += len;
value += strspn(value, "\t "); value += strspn(value, "\t ");
if(*value == '=') { if(*value == '=') {
value++; value++;
value += strspn(value, "\t "); value += strspn(value, "\t ");
} }
variable[len] = '\0'; variable[len] = '\0';
bool found = false; bool found = false;
for(int i = 0; variables[i].name; i++) { for(int i = 0; variables[i].name; i++) {
if(strcasecmp(variables[i].name, variable)) if(strcasecmp(variables[i].name, variable)) {
continue; continue;
}
found = true; found = true;
@ -132,24 +158,29 @@ static void check_conffile(const char *fname, bool server) {
fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno); fprintf(stderr, "WARNING: obsolete variable %s in %s line %d\n", variable, fname, lineno);
} }
if(i < maxvariables) if(i < maxvariables) {
count[i]++; count[i]++;
}
} }
if(!found) if(!found) {
fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno); fprintf(stderr, "WARNING: unknown variable %s in %s line %d\n", variable, fname, lineno);
}
if(!*value) if(!*value) {
fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno); fprintf(stderr, "ERROR: no value for variable %s in %s line %d\n", variable, fname, lineno);
}
} }
for(int i = 0; variables[i].name && i < maxvariables; i++) { for(int i = 0; variables[i].name && i < maxvariables; i++) {
if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) if(count[i] > 1 && !(variables[i].type & VAR_MULTIPLE)) {
fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname); fprintf(stderr, "WARNING: multiple instances of variable %s in %s\n", variables[i].name, fname);
}
} }
if(ferror(f)) if(ferror(f)) {
fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: while reading %s: %s\n", fname, strerror(errno));
}
fclose(f); fclose(f);
} }
@ -165,19 +196,23 @@ int fsck(const char *argv0) {
if(access(tinc_conf, R_OK)) { if(access(tinc_conf, R_OK)) {
fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno)); fprintf(stderr, "ERROR: cannot read %s: %s\n", tinc_conf, strerror(errno));
if(errno == ENOENT) { if(errno == ENOENT) {
fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n"); fprintf(stderr, "No tinc configuration found. Create a new one with:\n\n");
print_tinc_cmd(argv0, "init"); print_tinc_cmd(argv0, "init");
} else if(errno == EACCES) { } else if(errno == EACCES) {
if(uid != 0) if(uid != 0) {
fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n"); fprintf(stderr, "You are currently not running tinc as root. Use sudo?\n");
else } else {
fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf); fprintf(stderr, "Check the permissions of each component of the path %s.\n", tinc_conf);
}
} }
return 1; return 1;
} }
char *name = get_my_name(true); char *name = get_my_name(true);
if(!name) { if(!name) {
fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n"); fprintf(stderr, "ERROR: tinc cannot run without a valid Name.\n");
return 1; return 1;
@ -192,7 +227,7 @@ int fsck(const char *argv0) {
#ifndef DISABLE_LEGACY #ifndef DISABLE_LEGACY
rsa_t *rsa_priv = NULL; rsa_t *rsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/rsa_key.priv", confbase); snprintf(fname, sizeof(fname), "%s/rsa_key.priv", confbase);
if(stat(fname, &st)) { if(stat(fname, &st)) {
if(errno != ENOENT) { if(errno != ENOENT) {
@ -203,12 +238,15 @@ int fsck(const char *argv0) {
} }
} else { } else {
FILE *f = fopen(fname, "r"); FILE *f = fopen(fname, "r");
if(!f) { if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1; return 1;
} }
rsa_priv = rsa_read_pem_private_key(f); rsa_priv = rsa_read_pem_private_key(f);
fclose(f); fclose(f);
if(!rsa_priv) { if(!rsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new RSA key with:\n\n"); fprintf(stderr, "You can generate a new RSA key with:\n\n");
@ -217,23 +255,28 @@ int fsck(const char *argv0) {
} }
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) { if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) { if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) { } else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077)) if(chmod(fname, st.st_mode & ~077)) {
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else } else {
fprintf(stderr, "Fixed permissions of %s.\n", fname); fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
} }
} }
#endif #endif
} }
#endif #endif
ecdsa_t *ecdsa_priv = NULL; ecdsa_t *ecdsa_priv = NULL;
snprintf(fname, sizeof fname, "%s/ed25519_key.priv", confbase); snprintf(fname, sizeof(fname), "%s/ed25519_key.priv", confbase);
if(stat(fname, &st)) { if(stat(fname, &st)) {
if(errno != ENOENT) { if(errno != ENOENT) {
@ -244,12 +287,15 @@ int fsck(const char *argv0) {
} }
} else { } else {
FILE *f = fopen(fname, "r"); FILE *f = fopen(fname, "r");
if(!f) { if(!f) {
fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not open %s: %s\n", fname, strerror(errno));
return 1; return 1;
} }
ecdsa_priv = ecdsa_read_pem_private_key(f); ecdsa_priv = ecdsa_read_pem_private_key(f);
fclose(f); fclose(f);
if(!ecdsa_priv) { if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname); fprintf(stderr, "ERROR: No key or unusable key found in %s.\n", fname);
fprintf(stderr, "You can generate a new Ed25519 key with:\n\n"); fprintf(stderr, "You can generate a new Ed25519 key with:\n\n");
@ -258,24 +304,30 @@ int fsck(const char *argv0) {
} }
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
if(st.st_mode & 077) { if(st.st_mode & 077) {
fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname); fprintf(stderr, "WARNING: unsafe file permissions on %s.\n", fname);
if(st.st_uid != uid) { if(st.st_uid != uid) {
fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname); fprintf(stderr, "You are not running %s as the same uid as %s.\n", argv0, fname);
} else if(ask_fix()) { } else if(ask_fix()) {
if(chmod(fname, st.st_mode & ~077)) if(chmod(fname, st.st_mode & ~077)) {
fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not change permissions of %s: %s\n", fname, strerror(errno));
else } else {
fprintf(stderr, "Fixed permissions of %s.\n", fname); fprintf(stderr, "Fixed permissions of %s.\n", fname);
}
} }
} }
#endif #endif
} }
#ifdef DISABLE_LEGACY #ifdef DISABLE_LEGACY
if(!ecdsa_priv) { if(!ecdsa_priv) {
fprintf(stderr, "ERROR: No Ed25519 private key found.\n"); fprintf(stderr, "ERROR: No Ed25519 private key found.\n");
#else #else
if(!rsa_priv && !ecdsa_priv) { if(!rsa_priv && !ecdsa_priv) {
fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n"); fprintf(stderr, "ERROR: Neither RSA or Ed25519 private key found.\n");
#endif #endif
@ -287,9 +339,11 @@ int fsck(const char *argv0) {
// Check for public keys. // Check for public keys.
// TODO: use RSAPublicKeyFile variable if present. // TODO: use RSAPublicKeyFile variable if present.
snprintf(fname, sizeof fname, "%s/hosts/%s", confbase, name); snprintf(fname, sizeof(fname), "%s/hosts/%s", confbase, name);
if(access(fname, R_OK))
if(access(fname, R_OK)) {
fprintf(stderr, "WARNING: cannot read %s\n", fname); fprintf(stderr, "WARNING: cannot read %s\n", fname);
}
FILE *f; FILE *f;
@ -297,6 +351,7 @@ int fsck(const char *argv0) {
rsa_t *rsa_pub = NULL; rsa_t *rsa_pub = NULL;
f = fopen(fname, "r"); f = fopen(fname, "r");
if(f) { if(f) {
rsa_pub = rsa_read_pem_public_key(f); rsa_pub = rsa_read_pem_public_key(f);
fclose(f); fclose(f);
@ -305,13 +360,17 @@ int fsck(const char *argv0) {
if(rsa_priv) { if(rsa_priv) {
if(!rsa_pub) { if(!rsa_pub) {
fprintf(stderr, "WARNING: No (usable) public RSA key found.\n"); fprintf(stderr, "WARNING: No (usable) public RSA key found.\n");
if(ask_fix()) { if(ask_fix()) {
FILE *f = fopen(fname, "a"); FILE *f = fopen(fname, "a");
if(f) { if(f) {
if(rsa_write_pem_public_key(rsa_priv, f)) if(rsa_write_pem_public_key(rsa_priv, f)) {
fprintf(stderr, "Wrote RSA public key to %s.\n", fname); fprintf(stderr, "Wrote RSA public key to %s.\n", fname);
else } else {
fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname); fprintf(stderr, "ERROR: could not write RSA public key to %s.\n", fname);
}
fclose(f); fclose(f);
} else { } else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
@ -320,56 +379,70 @@ int fsck(const char *argv0) {
} else { } else {
// TODO: suggest remedies // TODO: suggest remedies
size_t len = rsa_size(rsa_priv); size_t len = rsa_size(rsa_priv);
if(len != rsa_size(rsa_pub)) { if(len != rsa_size(rsa_pub)) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1; return 1;
} }
char buf1[len], buf2[len], buf3[len]; char buf1[len], buf2[len], buf3[len];
randomize(buf1, sizeof buf1); randomize(buf1, sizeof(buf1));
buf1[0] &= 0x7f; buf1[0] &= 0x7f;
memset(buf2, 0, sizeof buf2); memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof buf2); memset(buf3, 0, sizeof(buf2));
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof buf1, buf2)) {
if(!rsa_public_encrypt(rsa_pub, buf1, sizeof(buf1), buf2)) {
fprintf(stderr, "ERROR: public RSA key does not work.\n"); fprintf(stderr, "ERROR: public RSA key does not work.\n");
return 1; return 1;
} }
if(!rsa_private_decrypt(rsa_priv, buf2, sizeof buf2, buf3)) {
if(!rsa_private_decrypt(rsa_priv, buf2, sizeof(buf2), buf3)) {
fprintf(stderr, "ERROR: private RSA key does not work.\n"); fprintf(stderr, "ERROR: private RSA key does not work.\n");
return 1; return 1;
} }
if(memcmp(buf1, buf3, sizeof buf1)) {
if(memcmp(buf1, buf3, sizeof(buf1))) {
fprintf(stderr, "ERROR: public and private RSA keys do not match.\n"); fprintf(stderr, "ERROR: public and private RSA keys do not match.\n");
return 1; return 1;
} }
} }
} else { } else {
if(rsa_pub) if(rsa_pub) {
fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n"); fprintf(stderr, "WARNING: A public RSA key was found but no private key is known.\n");
}
} }
#endif #endif
ecdsa_t *ecdsa_pub = NULL; ecdsa_t *ecdsa_pub = NULL;
f = fopen(fname, "r"); f = fopen(fname, "r");
if(f) { if(f) {
ecdsa_pub = get_pubkey(f); ecdsa_pub = get_pubkey(f);
if(!ecdsa_pub) { if(!ecdsa_pub) {
rewind(f); rewind(f);
ecdsa_pub = ecdsa_read_pem_public_key(f); ecdsa_pub = ecdsa_read_pem_public_key(f);
} }
fclose(f); fclose(f);
} }
if(ecdsa_priv) { if(ecdsa_priv) {
if(!ecdsa_pub) { if(!ecdsa_pub) {
fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n"); fprintf(stderr, "WARNING: No (usable) public Ed25519 key found.\n");
if(ask_fix()) { if(ask_fix()) {
FILE *f = fopen(fname, "a"); FILE *f = fopen(fname, "a");
if(f) { if(f) {
if(ecdsa_write_pem_public_key(ecdsa_priv, f)) if(ecdsa_write_pem_public_key(ecdsa_priv, f)) {
fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname); fprintf(stderr, "Wrote Ed25519 public key to %s.\n", fname);
else } else {
fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname); fprintf(stderr, "ERROR: could not write Ed25519 public key to %s.\n", fname);
}
fclose(f); fclose(f);
} else { } else {
fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: could not append to %s: %s\n", fname, strerror(errno));
@ -378,119 +451,150 @@ int fsck(const char *argv0) {
} else { } else {
// TODO: suggest remedies // TODO: suggest remedies
char *key1 = ecdsa_get_base64_public_key(ecdsa_pub); char *key1 = ecdsa_get_base64_public_key(ecdsa_pub);
if(!key1) { if(!key1) {
fprintf(stderr, "ERROR: public Ed25519 key does not work.\n"); fprintf(stderr, "ERROR: public Ed25519 key does not work.\n");
return 1; return 1;
} }
char *key2 = ecdsa_get_base64_public_key(ecdsa_priv); char *key2 = ecdsa_get_base64_public_key(ecdsa_priv);
if(!key2) { if(!key2) {
free(key1); free(key1);
fprintf(stderr, "ERROR: private Ed25519 key does not work.\n"); fprintf(stderr, "ERROR: private Ed25519 key does not work.\n");
return 1; return 1;
} }
int result = strcmp(key1, key2); int result = strcmp(key1, key2);
free(key1); free(key1);
free(key2); free(key2);
if(result) { if(result) {
fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n"); fprintf(stderr, "ERROR: public and private Ed25519 keys do not match.\n");
return 1; return 1;
} }
} }
} else { } else {
if(ecdsa_pub) if(ecdsa_pub) {
fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n"); fprintf(stderr, "WARNING: A public Ed25519 key was found but no private key is known.\n");
}
} }
// Check whether scripts are executable // Check whether scripts are executable
struct dirent *ent; struct dirent *ent;
DIR *dir = opendir(confbase); DIR *dir = opendir(confbase);
if(!dir) { if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno)); fprintf(stderr, "ERROR: cannot read directory %s: %s\n", confbase, strerror(errno));
return 1; return 1;
} }
while((ent = readdir(dir))) { while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) {
continue; continue;
}
strncpy(fname, ent->d_name, sizeof fname); strncpy(fname, ent->d_name, sizeof(fname));
char *dash = strrchr(fname, '-'); char *dash = strrchr(fname, '-');
if(!dash)
if(!dash) {
continue; continue;
}
*dash = 0; *dash = 0;
if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) { if(strcmp(fname, "tinc") && strcmp(fname, "host") && strcmp(fname, "subnet")) {
static bool explained = false; static bool explained = false;
fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name); fprintf(stderr, "WARNING: Unknown script %s" SLASH "%s found.\n", confbase, ent->d_name);
if(!explained) { if(!explained) {
fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase); fprintf(stderr, "The only scripts in %s executed by tinc are:\n", confbase);
fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n"); fprintf(stderr, "tinc-up, tinc-down, host-up, host-down, subnet-up and subnet-down.\n");
explained = true; explained = true;
} }
continue; continue;
} }
snprintf(fname, sizeof fname, "%s" SLASH "%s", confbase, ent->d_name); snprintf(fname, sizeof(fname), "%s" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) { if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) { if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue; continue;
} }
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) { if(ask_fix()) {
if(chmod(fname, 0755)) if(chmod(fname, 0755)) {
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
} }
} }
} }
closedir(dir); closedir(dir);
snprintf(dname, sizeof dname, "%s" SLASH "hosts", confbase); snprintf(dname, sizeof(dname), "%s" SLASH "hosts", confbase);
dir = opendir(dname); dir = opendir(dname);
if(!dir) { if(!dir) {
fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno)); fprintf(stderr, "ERROR: cannot read directory %s: %s\n", dname, strerror(errno));
return 1; return 1;
} }
while((ent = readdir(dir))) { while((ent = readdir(dir))) {
if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) if(strtailcmp(ent->d_name, "-up") && strtailcmp(ent->d_name, "-down")) {
continue; continue;
}
strncpy(fname, ent->d_name, sizeof fname); strncpy(fname, ent->d_name, sizeof(fname));
char *dash = strrchr(fname, '-'); char *dash = strrchr(fname, '-');
if(!dash)
if(!dash) {
continue; continue;
}
*dash = 0; *dash = 0;
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
if(access(fname, R_OK | X_OK)) { if(access(fname, R_OK | X_OK)) {
if(errno != EACCES) { if(errno != EACCES) {
fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: cannot access %s: %s\n", fname, strerror(errno));
continue; continue;
} }
fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno)); fprintf(stderr, "WARNING: cannot read and execute %s: %s\n", fname, strerror(errno));
if(ask_fix()) { if(ask_fix()) {
if(chmod(fname, 0755)) if(chmod(fname, 0755)) {
fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno)); fprintf(stderr, "ERROR: cannot change permissions on %s: %s\n", fname, strerror(errno));
}
} }
} }
} }
closedir(dir); closedir(dir);
// Check for obsolete / unsafe / unknown configuration variables. // Check for obsolete / unsafe / unknown configuration variables.
check_conffile(tinc_conf, true); check_conffile(tinc_conf, true);
dir = opendir(dname); dir = opendir(dname);
if(dir) { if(dir) {
while((ent = readdir(dir))) { while((ent = readdir(dir))) {
if(!check_id(ent->d_name)) if(!check_id(ent->d_name)) {
continue; continue;
}
snprintf(fname, sizeof fname, "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name); snprintf(fname, sizeof(fname), "%s" SLASH "hosts" SLASH "%s", confbase, ent->d_name);
check_conffile(fname, false); check_conffile(fname, false);
} }
closedir(dir); closedir(dir);
} }

View file

@ -1,3 +1,6 @@
#ifndef TINC_FSCK_H
#define TINC_FSCK_H
/* /*
fsck.h -- header for fsck.c. fsck.h -- header for fsck.c.
Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org> Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
@ -17,10 +20,6 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef __TINC_FSCK_H__
#define __TINC_FSCK_H__
extern int fsck(const char *argv0); extern int fsck(const char *argv0);
#endif #endif

View file

@ -55,7 +55,7 @@ static struct {
static bool nametocipher(const char *name, int *algo, int *mode) { static bool nametocipher(const char *name, int *algo, int *mode) {
size_t i; size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) { if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) {
*algo = ciphertable[i].algo; *algo = ciphertable[i].algo;
*mode = ciphertable[i].mode; *mode = ciphertable[i].mode;
@ -69,7 +69,7 @@ static bool nametocipher(const char *name, int *algo, int *mode) {
static bool nidtocipher(int nid, int *algo, int *mode) { static bool nidtocipher(int nid, int *algo, int *mode) {
size_t i; size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(nid == ciphertable[i].nid) { if(nid == ciphertable[i].nid) {
*algo = ciphertable[i].algo; *algo = ciphertable[i].algo;
*mode = ciphertable[i].mode; *mode = ciphertable[i].mode;
@ -83,7 +83,7 @@ static bool nidtocipher(int nid, int *algo, int *mode) {
static bool ciphertonid(int algo, int mode, int *nid) { static bool ciphertonid(int algo, int mode, int *nid) {
size_t i; size_t i;
for(i = 0; i < sizeof ciphertable / sizeof *ciphertable; i++) { for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) { if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) {
*nid = ciphertable[i].nid; *nid = ciphertable[i].nid;
return true; return true;
@ -102,7 +102,7 @@ static bool cipher_open(cipher_t *cipher, int algo, int mode) {
} }
if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) { if((err = gcry_cipher_open(&cipher->handle, algo, mode, 0))) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to intialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err)); logger(DEBUG_ALWAYS, LOG_DEBUG, "Unable to initialise cipher %d mode %d: %s", algo, mode, gcry_strerror(err));
return false; return false;
} }
@ -146,10 +146,8 @@ void cipher_close(cipher_t *cipher) {
cipher->handle = NULL; cipher->handle = NULL;
} }
if(cipher->key) { free(cipher->key);
free(cipher->key); cipher->key = NULL;
cipher->key = NULL;
}
} }
size_t cipher_keylength(const cipher_t *cipher) { size_t cipher_keylength(const cipher_t *cipher) {
@ -193,8 +191,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
uint8_t pad[cipher->blklen]; uint8_t pad[cipher->blklen];
if(cipher->padding) { if(cipher->padding) {
if(!oneshot) if(!oneshot) {
return false; return false;
}
size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen; size_t reqlen = ((inlen + cipher->blklen) / cipher->blklen) * cipher->blklen;
@ -207,14 +206,16 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
inlen = reqlen - cipher->blklen; inlen = reqlen - cipher->blklen;
for(int i = 0; i < cipher->blklen; i++) for(int i = 0; i < cipher->blklen; i++)
if(i < cipher->blklen - padbyte) if(i < cipher->blklen - padbyte) {
pad[i] = ((uint8_t *)indata)[inlen + i]; pad[i] = ((uint8_t *)indata)[inlen + i];
else } else {
pad[i] = padbyte; pad[i] = padbyte;
}
} }
if(oneshot) if(oneshot) {
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
}
if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) { if((err = gcry_cipher_encrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err)); logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err));
@ -237,8 +238,9 @@ bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) {
gcry_error_t err; gcry_error_t err;
if(oneshot) if(oneshot) {
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen); gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
}
if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) { if((err = gcry_cipher_decrypt(cipher->handle, outdata, *outlen, indata, inlen))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err)); logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", gcry_strerror(err));
@ -246,8 +248,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
} }
if(cipher->padding) { if(cipher->padding) {
if(!oneshot) if(!oneshot) {
return false; return false;
}
uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1]; uint8_t padbyte = ((uint8_t *)outdata)[inlen - 1];
@ -265,8 +268,9 @@ bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *ou
} }
*outlen = origlen; *outlen = origlen;
} else } else {
*outlen = inlen; *outlen = inlen;
}
return true; return true;
} }

View file

@ -37,7 +37,7 @@ static struct {
static bool nametodigest(const char *name, int *algo) { static bool nametodigest(const char *name, int *algo) {
int i; int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) { if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) {
*algo = digesttable[i].algo; *algo = digesttable[i].algo;
return true; return true;
@ -50,7 +50,7 @@ static bool nametodigest(const char *name, int *algo) {
static bool nidtodigest(int nid, int *algo) { static bool nidtodigest(int nid, int *algo) {
int i; int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(nid == digesttable[i].nid) { if(nid == digesttable[i].nid) {
*algo = digesttable[i].algo; *algo = digesttable[i].algo;
return true; return true;
@ -63,7 +63,7 @@ static bool nidtodigest(int nid, int *algo) {
static bool digesttonid(int algo, int *nid) { static bool digesttonid(int algo, int *nid) {
int i; int i;
for(i = 0; i < sizeof digesttable / sizeof *digesttable; i++) { for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(algo == digesttable[i].algo) { if(algo == digesttable[i].algo) {
*nid = digesttable[i].nid; *nid = digesttable[i].nid;
return true; return true;
@ -81,10 +81,11 @@ static bool digest_open(digest_t *digest, int algo, int maclength) {
unsigned int len = gcry_md_get_algo_dlen(algo); unsigned int len = gcry_md_get_algo_dlen(algo);
if(maclength > len || maclength < 0) if(maclength > len || maclength < 0) {
digest->maclength = len; digest->maclength = len;
else } else {
digest->maclength = maclength; digest->maclength = maclength;
}
digest->algo = algo; digest->algo = algo;
digest->hmac = NULL; digest->hmac = NULL;
@ -119,16 +120,21 @@ bool digest_open_sha1(digest_t *digest, int maclength) {
} }
void digest_close(digest_t *digest) { void digest_close(digest_t *digest) {
if(digest->hmac) if(digest->hmac) {
gcry_md_close(digest->hmac); gcry_md_close(digest->hmac);
}
digest->hmac = NULL; digest->hmac = NULL;
} }
bool digest_set_key(digest_t *digest, const void *key, size_t len) { bool digest_set_key(digest_t *digest, const void *key, size_t len) {
if(!digest->hmac) if(!digest->hmac) {
gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC); gcry_md_open(&digest->hmac, digest->algo, GCRY_MD_FLAG_HMAC);
if(!digest->hmac) }
if(!digest->hmac) {
return false; return false;
}
return !gcry_md_setkey(digest->hmac, key, len); return !gcry_md_setkey(digest->hmac, key, len);
} }
@ -141,8 +147,11 @@ bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *out
gcry_md_reset(digest->hmac); gcry_md_reset(digest->hmac);
gcry_md_write(digest->hmac, indata, inlen); gcry_md_write(digest->hmac, indata, inlen);
tmpdata = gcry_md_read(digest->hmac, digest->algo); tmpdata = gcry_md_read(digest->hmac, digest->algo);
if(!tmpdata)
if(!tmpdata) {
return false; return false;
}
memcpy(outdata, tmpdata, digest->maclength); memcpy(outdata, tmpdata, digest->maclength);
} else { } else {
char tmpdata[len]; char tmpdata[len];

Some files were not shown because too many files have changed in this diff Show more