From 058ae090a970436caec3b3059e9e18b310dd6b0d Mon Sep 17 00:00:00 2001 From: Michael Prokop Date: Fri, 29 May 2009 21:19:02 +0200 Subject: [PATCH] Imported Upstream version 0.3 --- AUTHORS | 3 + ChangeLog | 43 ++ LICENSE | 704 ++++++++++++++++++++ README | 97 +++ etc/anytun/autostart | 4 + etc/anytun/client1/config | 94 +++ etc/anytun/client1/post-up.sh | 12 + etc/anytun/client2/config | 94 +++ etc/anytun/client2/post-up.sh | 12 + etc/anytun/client3/config | 94 +++ etc/anytun/client3/post-up.sh | 12 + etc/anytun/p2p-a/config | 87 +++ etc/anytun/p2p-b/config | 87 +++ etc/anytun/server/conf.d/client1 | 48 ++ etc/anytun/server/conf.d/client2 | 48 ++ etc/anytun/server/conf.d/client3 | 48 ++ etc/anytun/server/config | 95 +++ etc/anytun/server/post-up.sh | 30 + etc/init.d/anytun | 204 ++++++ src/Doxyfile | 1252 +++++++++++++++++++++++++++++++++++ src/Makefile | 198 ++++++ src/anyrtpproxy/Makefile | 79 +++ src/anyrtpproxy/anyrtpproxy.cpp | 387 +++++++++++ src/anyrtpproxy/callIdQueue.cpp | 77 +++ src/anyrtpproxy/callIdQueue.h | 73 ++ src/anyrtpproxy/commandHandler.cpp | 286 ++++++++ src/anyrtpproxy/commandHandler.h | 92 +++ src/anyrtpproxy/connectionList.cpp | 90 +++ src/anyrtpproxy/connectionList.h | 65 ++ src/anyrtpproxy/options.cpp | 408 ++++++++++++ src/anyrtpproxy/options.h | 138 ++++ src/anyrtpproxy/portWindow.cpp | 86 +++ src/anyrtpproxy/portWindow.h | 64 ++ src/anyrtpproxy/rtpSession.cpp | 154 +++++ src/anyrtpproxy/rtpSession.h | 133 ++++ src/anyrtpproxy/rtpSessionTable.cpp | 123 ++++ src/anyrtpproxy/rtpSessionTable.h | 75 +++ src/anyrtpproxy/syncRtpCommand.cpp | 46 ++ src/anyrtpproxy/syncRtpCommand.h | 61 ++ src/anytun-config.cpp | 141 ++++ src/anytun-controld.cpp | 156 +++++ src/anytun-showtables.cpp | 136 ++++ src/anytun.cpp | 527 +++++++++++++++ src/anytun.sln | 26 + src/anytun.suo | Bin 0 -> 68608 bytes src/anytun.vcproj | 682 +++++++++++++++++++ src/anytunError.cpp | 53 ++ src/anytunError.h | 83 +++ src/authAlgo.cpp | 167 +++++ src/authAlgo.h | 108 +++ src/authAlgoFactory.cpp | 62 ++ src/authAlgoFactory.h | 53 ++ src/bsd/tunDevice.cpp | 283 ++++++++ src/buffer.cpp | 257 +++++++ src/buffer.h | 77 +++ src/cipher.cpp | 190 ++++++ src/cipher.h | 132 ++++ src/cipherFactory.cpp | 56 ++ src/cipherFactory.h | 52 ++ src/configure | 136 ++++ src/connectionList.cpp | 154 +++++ src/connectionList.h | 78 +++ src/connectionParam.cpp | 40 ++ src/connectionParam.h | 79 +++ src/cryptinit.hpp | 113 ++++ src/daemon.hpp | 165 +++++ src/datatypes.h | 67 ++ src/deviceConfig.hpp | 97 +++ src/encryptedPacket.cpp | 222 +++++++ src/encryptedPacket.h | 158 +++++ src/endian.h | 59 ++ src/keyDerivation.cpp | 340 ++++++++++ src/keyDerivation.h | 203 ++++++ src/keyDerivationFactory.cpp | 56 ++ src/keyDerivationFactory.h | 52 ++ src/linux/tunDevice.cpp | 173 +++++ src/log.cpp | 101 +++ src/log.h | 102 +++ src/logTargets.cpp | 436 ++++++++++++ src/logTargets.h | 203 ++++++ src/man/Makefile | 57 ++ src/man/anyrtpproxy.8.txt | 184 +++++ src/man/anytun-config.8.txt | 217 ++++++ src/man/anytun-controld.8.txt | 136 ++++ src/man/anytun-showtables.8.txt | 77 +++ src/man/anytun.8.txt | 468 +++++++++++++ src/networkAddress.cpp | 203 ++++++ src/networkAddress.h | 117 ++++ src/networkPrefix.cpp | 69 ++ src/networkPrefix.h | 66 ++ src/options.cpp | 1098 ++++++++++++++++++++++++++++++ src/options.h | 230 +++++++ src/packetSource.cpp | 74 +++ src/packetSource.h | 76 +++ src/plainPacket.cpp | 180 +++++ src/plainPacket.h | 115 ++++ src/resolver.cpp | 180 +++++ src/resolver.h | 99 +++ src/routingTable.cpp | 196 ++++++ src/routingTable.h | 82 +++ src/routingTree.hpp | 104 +++ src/routingTreeNode.cpp | 64 ++ src/routingTreeNode.h | 59 ++ src/seqWindow.cpp | 160 +++++ src/seqWindow.h | 91 +++ src/signalController.cpp | 255 +++++++ src/signalController.h | 199 ++++++ src/syncBuffer.cpp | 33 + src/syncBuffer.h | 64 ++ src/syncClient.cpp | 127 ++++ src/syncClient.h | 50 ++ src/syncCommand.cpp | 57 ++ src/syncCommand.h | 79 +++ src/syncConnectionCommand.cpp | 46 ++ src/syncConnectionCommand.h | 64 ++ src/syncOnConnect.hpp | 68 ++ src/syncQueue.cpp | 89 +++ src/syncQueue.h | 73 ++ src/syncRouteCommand.cpp | 46 ++ src/syncRouteCommand.h | 65 ++ src/syncServer.cpp | 90 +++ src/syncServer.h | 71 ++ src/syncTcpConnection.cpp | 63 ++ src/syncTcpConnection.h | 65 ++ src/sysexec.hpp | 74 +++ src/threadUtils.hpp | 69 ++ src/tunDevice.h | 98 +++ src/win32/#winService.cpp# | 212 ++++++ src/win32/common.h | 82 +++ src/win32/registryKey.cpp | 121 ++++ src/win32/registryKey.h | 57 ++ src/win32/tunDevice.cpp | 271 ++++++++ src/win32/winService.cpp | 212 ++++++ src/win32/winService.h | 81 +++ wireshark-lua/satp.lua | 82 +++ 135 files changed, 19343 insertions(+) create mode 100644 AUTHORS create mode 100644 ChangeLog create mode 100644 LICENSE create mode 100644 README create mode 100644 etc/anytun/autostart create mode 100644 etc/anytun/client1/config create mode 100755 etc/anytun/client1/post-up.sh create mode 100644 etc/anytun/client2/config create mode 100755 etc/anytun/client2/post-up.sh create mode 100644 etc/anytun/client3/config create mode 100755 etc/anytun/client3/post-up.sh create mode 100644 etc/anytun/p2p-a/config create mode 100644 etc/anytun/p2p-b/config create mode 100644 etc/anytun/server/conf.d/client1 create mode 100644 etc/anytun/server/conf.d/client2 create mode 100644 etc/anytun/server/conf.d/client3 create mode 100644 etc/anytun/server/config create mode 100755 etc/anytun/server/post-up.sh create mode 100755 etc/init.d/anytun create mode 100644 src/Doxyfile create mode 100644 src/Makefile create mode 100644 src/anyrtpproxy/Makefile create mode 100644 src/anyrtpproxy/anyrtpproxy.cpp create mode 100644 src/anyrtpproxy/callIdQueue.cpp create mode 100644 src/anyrtpproxy/callIdQueue.h create mode 100644 src/anyrtpproxy/commandHandler.cpp create mode 100644 src/anyrtpproxy/commandHandler.h create mode 100644 src/anyrtpproxy/connectionList.cpp create mode 100644 src/anyrtpproxy/connectionList.h create mode 100644 src/anyrtpproxy/options.cpp create mode 100644 src/anyrtpproxy/options.h create mode 100644 src/anyrtpproxy/portWindow.cpp create mode 100644 src/anyrtpproxy/portWindow.h create mode 100644 src/anyrtpproxy/rtpSession.cpp create mode 100644 src/anyrtpproxy/rtpSession.h create mode 100644 src/anyrtpproxy/rtpSessionTable.cpp create mode 100644 src/anyrtpproxy/rtpSessionTable.h create mode 100644 src/anyrtpproxy/syncRtpCommand.cpp create mode 100644 src/anyrtpproxy/syncRtpCommand.h create mode 100644 src/anytun-config.cpp create mode 100644 src/anytun-controld.cpp create mode 100644 src/anytun-showtables.cpp create mode 100644 src/anytun.cpp create mode 100644 src/anytun.sln create mode 100644 src/anytun.suo create mode 100644 src/anytun.vcproj create mode 100644 src/anytunError.cpp create mode 100644 src/anytunError.h create mode 100644 src/authAlgo.cpp create mode 100644 src/authAlgo.h create mode 100644 src/authAlgoFactory.cpp create mode 100644 src/authAlgoFactory.h create mode 100644 src/bsd/tunDevice.cpp create mode 100644 src/buffer.cpp create mode 100644 src/buffer.h create mode 100644 src/cipher.cpp create mode 100644 src/cipher.h create mode 100644 src/cipherFactory.cpp create mode 100644 src/cipherFactory.h create mode 100755 src/configure create mode 100644 src/connectionList.cpp create mode 100644 src/connectionList.h create mode 100644 src/connectionParam.cpp create mode 100644 src/connectionParam.h create mode 100644 src/cryptinit.hpp create mode 100644 src/daemon.hpp create mode 100644 src/datatypes.h create mode 100644 src/deviceConfig.hpp create mode 100644 src/encryptedPacket.cpp create mode 100644 src/encryptedPacket.h create mode 100644 src/endian.h create mode 100644 src/keyDerivation.cpp create mode 100644 src/keyDerivation.h create mode 100644 src/keyDerivationFactory.cpp create mode 100644 src/keyDerivationFactory.h create mode 100644 src/linux/tunDevice.cpp create mode 100644 src/log.cpp create mode 100644 src/log.h create mode 100644 src/logTargets.cpp create mode 100644 src/logTargets.h create mode 100644 src/man/Makefile create mode 100644 src/man/anyrtpproxy.8.txt create mode 100644 src/man/anytun-config.8.txt create mode 100644 src/man/anytun-controld.8.txt create mode 100644 src/man/anytun-showtables.8.txt create mode 100644 src/man/anytun.8.txt create mode 100644 src/networkAddress.cpp create mode 100644 src/networkAddress.h create mode 100644 src/networkPrefix.cpp create mode 100644 src/networkPrefix.h create mode 100644 src/options.cpp create mode 100644 src/options.h create mode 100644 src/packetSource.cpp create mode 100644 src/packetSource.h create mode 100644 src/plainPacket.cpp create mode 100644 src/plainPacket.h create mode 100644 src/resolver.cpp create mode 100644 src/resolver.h create mode 100644 src/routingTable.cpp create mode 100644 src/routingTable.h create mode 100644 src/routingTree.hpp create mode 100644 src/routingTreeNode.cpp create mode 100644 src/routingTreeNode.h create mode 100644 src/seqWindow.cpp create mode 100644 src/seqWindow.h create mode 100644 src/signalController.cpp create mode 100644 src/signalController.h create mode 100644 src/syncBuffer.cpp create mode 100644 src/syncBuffer.h create mode 100644 src/syncClient.cpp create mode 100644 src/syncClient.h create mode 100644 src/syncCommand.cpp create mode 100644 src/syncCommand.h create mode 100644 src/syncConnectionCommand.cpp create mode 100644 src/syncConnectionCommand.h create mode 100644 src/syncOnConnect.hpp create mode 100644 src/syncQueue.cpp create mode 100644 src/syncQueue.h create mode 100644 src/syncRouteCommand.cpp create mode 100644 src/syncRouteCommand.h create mode 100644 src/syncServer.cpp create mode 100644 src/syncServer.h create mode 100644 src/syncTcpConnection.cpp create mode 100644 src/syncTcpConnection.h create mode 100644 src/sysexec.hpp create mode 100644 src/threadUtils.hpp create mode 100644 src/tunDevice.h create mode 100644 src/win32/#winService.cpp# create mode 100644 src/win32/common.h create mode 100644 src/win32/registryKey.cpp create mode 100644 src/win32/registryKey.h create mode 100644 src/win32/tunDevice.cpp create mode 100644 src/win32/winService.cpp create mode 100644 src/win32/winService.h create mode 100644 wireshark-lua/satp.lua diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..6d7339f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Othmar Gsenger +Erwin Nindl +Christian Pointner diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..a2736ca --- /dev/null +++ b/ChangeLog @@ -0,0 +1,43 @@ +2009.5.1 -- Version 0.3 svn834 + +* updated to new protocol specification (extended label and crypto role) + Due to this changes this version is incompatible to version 0.2 and prior +* the auth tag length can now be configured +* added extended logging support (syslog, file stdout and stderr) +* changed -n|--ifconfig parameter to new behavior + tun and tap devices now use the same syntax +* added seperate resolver thread +* fixed packet length errors +* dropping privileges is now possible wihtout chroot +* full ipv6 support + - ipv6 multiple connection routing + - syncronisation over ipv6 + - 4in6,6in6 tunnels +* replaced several dependencies with boost libs +* ported basic functionality to Windows +* dropped OpenBSD Port due to multi threading issues +* code cleanup + +2008.6.20 -- Version 0.2.1svn556 + +* finished own tun/tap devices and removed openvpn source code + currently there are tun/tap devices for Linux, FreeBSD, OpenBSD + and NetBSD +* several fixes for building on OpenBSD +* added manpages for all binaries +* switched to GPLv3 + + +2008.4.12 -- Version 0.2svn490 + +* updated to Internet Draft Revision 02 + Mind that the this version is incompatible to version 0.1 + However this is only the case if you use encryption. There + shouldn't be any Problem with NULL cipher +* several fixes for tunneling IPv6 + +2008.3.18 -- Version 0.1svn441 + +* Initial release. +* IPv4 tunnel over UDP, with AES-CTR cipher and SHA1 HMAC signature. + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..51e0b22 --- /dev/null +++ b/LICENSE @@ -0,0 +1,704 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README b/README new file mode 100644 index 0000000..b7168e2 --- /dev/null +++ b/README @@ -0,0 +1,97 @@ +Dependencies +============ + +Anytun can be built by using either libgcrypt or the openssl-crypto library. +The latter is more performant in most cases but there are some license +issues when using this library. + +Linux +----- + +using libgcrypt: + libgcrypt11-dev + +using ssl crypto lib: + libssl-dev + +common: + build-essential + libboost-serialization1.35-dev + libboost-thread1.35-dev + libboost-system1.35-dev + libboost-regex1.35-dev + asciidoc (only for manpage) + + +Windows +------- +OpenSSL + Developer: + http://www.slproweb.com/download/Win32OpenSSL-0_9_8j.exe + + Runtime Only: + http://www.slproweb.com/download/Win32OpenSSL_Light-0_9_8j.exe + +Boost 1.35: + http://www.boostpro.com/download/boost_1_35_0_setup.exe + + As it can take some time to install everything from boost here is a + complete list of libraries which have to be installed in order to build anytun: + + * Serialization + * Thread + * date_time + * System + * regex + +Microsoft Visual C++ 2008 Redistributable Package (x86): + http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF + + + +Installation +============ + +Getting the source via subversion: +---------------------------------- +svn co http://anytun.org/svn/anytun/ + +Building from source +-------------------- + +using libgcrypt: + + # cd src + # ./configure + # make + +using ssl crypto library: + + # cd src + # ./configure --use-ssl-crypto + # make + + +Notes: + - try './configure --help' for further information + - if using openssl pre 0.9.8 you have to disable passphrase + because openssl had no SHA256 implementation prior to this + version + + +Errors: +======= + +Note: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2) +Cannot open TUN/TAP dev /dev/anytun0: No such file or directory (errno=2) + +Solution: Enabling tun/tap device +------------------------------------ + +modprobe tun +cd /dev +./MAKEDEV tun + +edit /etc/modules and add the line +tun +to load the module automatically diff --git a/etc/anytun/autostart b/etc/anytun/autostart new file mode 100644 index 0000000..328826b --- /dev/null +++ b/etc/anytun/autostart @@ -0,0 +1,4 @@ +server +#client1 +#client2 +#client3 diff --git a/etc/anytun/client1/config b/etc/anytun/client1/config new file mode 100644 index 0000000..da11356 --- /dev/null +++ b/etc/anytun/client1/config @@ -0,0 +1,94 @@ +############################# +## Main options # +############################# + +role client + +## Client ID +## (has to be unique for each client) +mux 1 + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## The remote host and port +remote-host example.com +remote-port 4444 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-client1,daemon + +## change user and group after init +username anytun +groupname anytun + +## chroot to users home directory +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4444 + +## Device name +#dev anytun0 + +## Automaticaly configure the interface an set a route +## +## We highly recommend the use of the post up script to do this +## +## the address hast to be supplied in CIDR notation +#ifconfig / + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/client1/post-up.sh b/etc/anytun/client1/post-up.sh new file mode 100755 index 0000000..574a3e8 --- /dev/null +++ b/etc/anytun/client1/post-up.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +ip link set dev $1 up +ip link set dev $1 mtu 1400 +ip addr add dev $1 192.168.123.1/24 +ip addr add dev $1 fec0::1/64 + +# disable ICMP redirects as they don't work within the tunnel +echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects +echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects + +exit 0 diff --git a/etc/anytun/client2/config b/etc/anytun/client2/config new file mode 100644 index 0000000..ff9bab7 --- /dev/null +++ b/etc/anytun/client2/config @@ -0,0 +1,94 @@ +############################# +## Main options # +############################# + +role client + +## Client ID +## (has to be unique for each client) +mux 2 + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## The remote host and port +remote-host example.com +remote-port 4444 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-client2,daemon + +## change user and group after init +username anytun +groupname anytun + +## chroot to users home directory +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4444 + +## Device name +#dev anytun0 + +## Automaticaly configure the interface an set a route +## +## We highly recommend the use of the post up script to do this +## +## the address hast to be supplied in CIDR notation +#ifconfig / + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 2123456789ABCDEF0123456789ABCDEF +#salt 2123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/client2/post-up.sh b/etc/anytun/client2/post-up.sh new file mode 100755 index 0000000..b65cb0b --- /dev/null +++ b/etc/anytun/client2/post-up.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +ip link set dev $1 up +ip link set dev $1 mtu 1400 +ip addr add dev $1 192.168.123.2/24 +ip addr add dev $1 fec0::2/64 + +# disable ICMP redirects as they don't work within the tunnel +echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects +echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects + +exit 0 diff --git a/etc/anytun/client3/config b/etc/anytun/client3/config new file mode 100644 index 0000000..c5f529c --- /dev/null +++ b/etc/anytun/client3/config @@ -0,0 +1,94 @@ +############################# +## Main options # +############################# + +role client + +## Client ID +## (has to be unique for each client) +mux 3 + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## The remote host and port +remote-host example.com +remote-port 4444 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-client3,daemon + +## change user and group after init +username anytun +groupname anytun + +## chroot to users home directory +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4444 + +## Device name +#dev anytun0 + +## Automaticaly configure the interface an set a route +## +## We highly recommend the use of the post up script to do this +## +## the address hast to be supplied in CIDR notation +#ifconfig / + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 3123456789ABCDEF0123456789ABCDEF +#salt 3123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/client3/post-up.sh b/etc/anytun/client3/post-up.sh new file mode 100755 index 0000000..4245ff4 --- /dev/null +++ b/etc/anytun/client3/post-up.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +ip link set dev $1 up +ip link set dev $1 mtu 1400 +ip addr add dev $1 192.168.123.3/24 +ip addr add dev $1 fec0::3/64 + +# disable ICMP redirects as they don't work within the tunnel +echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects +echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects + +exit 0 diff --git a/etc/anytun/p2p-a/config b/etc/anytun/p2p-a/config new file mode 100644 index 0000000..126f918 --- /dev/null +++ b/etc/anytun/p2p-a/config @@ -0,0 +1,87 @@ +############################# +## Main options # +############################# + +role alice + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## Automaticaly configure the interface +## the address hast to be supplied in CIDR notation +ifconfig 192.168.223.1/30 + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_P2P_VPN_Tunnels_With_Anytun_Is_Easy + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4445 + +## The remote host and port +remote-host p2p-b.example.com +remote-port 4445 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-p2p-a,daemon + +## change user and group after init +username anytun +groupname anytun + +## chroot to users home directory +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## Device name +#dev uanytun0 + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/p2p-b/config b/etc/anytun/p2p-b/config new file mode 100644 index 0000000..859b26d --- /dev/null +++ b/etc/anytun/p2p-b/config @@ -0,0 +1,87 @@ +############################# +## Main options # +############################# + +role bob + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## Automaticaly configure the interface +## the address hast to be supplied in CIDR notation +ifconfig 192.168.223.2/30 + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_P2P_VPN_Tunnels_With_Anytun_Is_Easy + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4445 + +## The remote host and port +remote-host p2p-a.example.com +remote-port 4445 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-p2p-b,daemon + +## change user and group after init +username anytun +groupname anytun + +## chroot to users home directory +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## Device name +#dev uanytun0 + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/server/conf.d/client1 b/etc/anytun/server/conf.d/client1 new file mode 100644 index 0000000..5099cef --- /dev/null +++ b/etc/anytun/server/conf.d/client1 @@ -0,0 +1,48 @@ +############################# +## main options # +############################# + +role server + +## Client ID +## (has to be unique for each client) +mux 1 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## staticially configure client address +## (autodetect if skiped) +#remote-host +#remote-port 4444 + +############################# +## routing options # +############################# + +## Internal Routing entries +## multiple routes allowed +## make sure to also set a system route in the post-up script +route 192.168.123.1/32 +route fec0::1/128 + +## Add a subnet route +## make sure to also set a system route in the post-up script +#route 192.168.11.0/24 +#route fec0:1::/48 + + +############################# +## Expert options # +############################# + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 0123456789ABCDEF0123456789ABCDEF +#salt 0123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/server/conf.d/client2 b/etc/anytun/server/conf.d/client2 new file mode 100644 index 0000000..e0b05d2 --- /dev/null +++ b/etc/anytun/server/conf.d/client2 @@ -0,0 +1,48 @@ +############################# +## main options # +############################# + +role server + +## Client ID +## (has to be unique for each client) +mux 2 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## staticially configure client address +## (autodetect if skiped) +#remote-host +#remote-port 4444 + +############################# +## routing options # +############################# + +## Internal Routing entries +## multiple routes allowed +## make sure to also set a system route in the post-up script +route 192.168.123.2/32 +route fec0::2/128 + +## Add a subnet route +## make sure to also set a system route in the post-up script +#route 192.168.12.0/24 +#route fec0:2::/48 + + +############################# +## Expert options # +############################# + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 2123456789ABCDEF0123456789ABCDEF +#salt 2123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/server/conf.d/client3 b/etc/anytun/server/conf.d/client3 new file mode 100644 index 0000000..8f22de0 --- /dev/null +++ b/etc/anytun/server/conf.d/client3 @@ -0,0 +1,48 @@ +############################# +## main options # +############################# + +role server + +## Client ID +## (has to be unique for each client) +mux 3 + +## Passphrase +## this is used to generate the crypto-key and salt +## this should be al least 30 characters +passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy + +## staticially configure client address +## (autodetect if skiped) +#remote-host +#remote-port 4444 + +############################# +## routing options # +############################# + +## Internal Routing entries +## multiple routes allowed +## make sure to also set a system route in the post-up script +route 192.168.123.3/32 +route fec0::3/128 + +## Add a subnet route +## make sure to also set a system route in the post-up script +#route 192.168.13.0/24 +#route fec0:3::/48 + + +############################# +## Expert options # +############################# + +## Manually set encryption key and salt +## (this replaces the passphrase) +#key 3123456789ABCDEF0123456789ABCDEF +#salt 3123456789ABCD0123456789ABCD + +## Setting a window size > 0 will enable replay protection +## This most likely will only work with external rekeying +#window-size 0 diff --git a/etc/anytun/server/config b/etc/anytun/server/config new file mode 100644 index 0000000..8488923 --- /dev/null +++ b/etc/anytun/server/config @@ -0,0 +1,95 @@ +############################# +## multi connection support # +############################# + +## control host for multi-client support +## This enables multi-connection support and splits configuration files per client +## Make sure to use a unique port for each server, when runnig multiple servers +control-host 127.0.0.1:4444 + +############################# +## Main options # +############################# + +## device type tun = ip/ipv6, tap = ethernet +type tun + +## payload encryption algorithm +#cipher null +#cipher aes-ctr-128 +#cipher aes-ctr-192 +#cipher aes-ctr-256 +cipher aes-ctr + +## message authentication algorithm +#auth-algo null +auth-algo sha1 + +##message auth tag length +#auth-tag-length 10 + +## local ip address to bind to (for tunnel data) +## (if you run an anycast cluster this has to be the anycast ip address) +#interface + +## local port to bind to (for tunnel data) +## make sure to use a different port for every server and client! +port 4444 + +############################# +## Debug options # +############################# + +## don't run in background +#nodaemonize + +## additional log to standard output with a level of 5 +#log stdout:5 + + +############################# +## Expert options # +############################# + +## log to syslog with a level of 3 +log syslog:3,anytun-server,daemon + +## change user and group after init +username nobody +groupname nogroup + +## chroot to /var/run/anytun +#chroot /var/run/anytun + +## key derivation pseudo random function +#kd-prf null +#kd-prf aes-ctr +#kd-prf aes-ctr-128 +#kd-prf aes-ctr-192 +#kd-prf aes-ctr-256 + +## Device name +#dev anytun0 + +## Automaticaly configure the interface an set a route +## +## We highly recommend the use of the post up script to do this +## +## the address hast to be supplied in CIDR notation +#ifconfig / + +############################# +## Cluster options # +############################# + +## the sender id to use (has to be unique for multiple anycast servers) +#sender-id 1 + +## local unicast(sync) ip address to bind to +#sync-interface + +## local unicast(sync) port to bind to +#sync-port 1234 + +## remote hosts to sync with +#sync-hosts :[,:[...]] diff --git a/etc/anytun/server/post-up.sh b/etc/anytun/server/post-up.sh new file mode 100755 index 0000000..9d585a1 --- /dev/null +++ b/etc/anytun/server/post-up.sh @@ -0,0 +1,30 @@ +#!/bin/sh +ip link set dev $1 up +ip link set mtu 1400 dev $1 + +# add tunnel addresses +ip addr add 192.168.123.254/24 dev $1 +ip addr add fec0::fd/64 dev $1 + +# add routes to client subnets +# you also have to add these routes to the client configuration file of each client +# ip route add 192.168.11.0/24 dev $1 +# ip route add fec0:1::/48 dev $1 +# ip route add 192.168.12.0/24 dev $1 +# ip route add fec0:2::/48 dev $1 +# ip route add 192.168.13.0/24 dev $1 +# ip route add fec0:3::/48 dev $1 + +# disable ICMP redirects as they don't work within the tunnel +echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects +echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects + +# enable packet forwarding +echo 1 > /proc/sys/net/ipv6/conf/$1/forwarding +echo 1 > /proc/sys/net/ipv4/conf/$1/forwarding + +# enable routing to local ethernet interface +# echo 1 > /proc/sys/net/ipv6/conf/eth0/forwarding +# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding + +exit 0 diff --git a/etc/init.d/anytun b/etc/init.d/anytun new file mode 100755 index 0000000..d0299d4 --- /dev/null +++ b/etc/init.d/anytun @@ -0,0 +1,204 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: anytun +# Required-Start: $network $named $syslog +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start anycast tunneling daemon at boot time +# Description: Enables networking over vpn tunnel interfaces +### END INIT INFO +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/usr/sbin/anytun +ANYTUNCONFIG=/usr/bin/anytun-config +CONTROLDAEMON=/usr/bin/anytun-controld +NAME=anytun +DESC=anytun +CONFIG_DIR=/etc/anytun +VARCONFIG_DIR=/var/run/anytun-controld + +test -x $DAEMON || exit 0 + +# Include anytun defaults if available +if [ -f /etc/default/anytun ] ; then + . /etc/default/anytun +fi + +start_vpn () { + STATUS="OK" + if [ -f $CONFIG_DIR/$NAME/config ] ; then + POSTUP='' + test -f $CONFIG_DIR/$NAME/post-up.sh && POSTUP="-x $CONFIG_DIR/$NAME/post-up.sh" + CHROOTDIR=`grep '^chroot' < $CONFIG_DIR/$NAME/config | sed 's/chroot\s*//'` + if [ -n "$CHROOTDIR" ] ; then + test -d $CHROOTDIR || mkdir -p $CHROOTDIR + fi + DAEMONARG=`sed 's/#.*//' < $CONFIG_DIR/$NAME/config | grep -e '\w' | sed 's/^/--/' | tr '\n' ' '` + $DAEMON --write-pid /var/run/anytun.$NAME.pid $POSTUP \ + $DAEMONOPTS $DAEMONARG || STATUS="FAILED" + else + STATUS="no config found" + fi + start_configd + echo -n "($STATUS)" +} +stop_vpn () { + kill `cat $PIDFILE` || true + rm $PIDFILE + stop_configd +} + +start_configd () { + if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then + test -d $VARCONFIG_DIR || mkdir -p $VARCONFIG_DIR + chmod 700 $VARCONFIG_DIR + rm -f $VARCONFIG_DIR/$NAME 2>/dev/null + for CLIENTNAME in `ls $CONFIG_DIR/$NAME/conf.d`; do + echo -n " ($CLIENTNAME)" + DAEMONARG=`sed 's/#.*//' < $CONFIG_DIR/$NAME/conf.d/$CLIENTNAME | grep -e '\w' | sed 's/^/ --/' | xargs echo` + $ANYTUNCONFIG $DAEMONARG >> $VARCONFIG_DIR/$NAME + done + CONTROLHOST=`sed 's/#.*//' < $CONFIG_DIR/$NAME/config | grep -e 'control-host' | sed 's/^/ --/'` + $CONTROLDAEMON -f $VARCONFIG_DIR/$NAME $DAEMONOPTS $CONTROLHOST \ + --write-pid $VARCONFIG_DIR/$NAME.pid + # rm -f $VARCONFIG_DIR/$NAME + fi +} +stop_configd () { + if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then + echo -n " ($NAME)" + kill `cat $VARCONFIG_DIR/$NAME.pid` || true + rm $VARCONFIG_DIR/$NAME.pid + fi +} + +set -e +case "$1" in + start) + echo -n "Starting $DESC:" + if test -z "$2" ; then + if [ -f $CONFIG_DIR/autostart ] ; then + for NAME in `sed 's/#.*//' < $CONFIG_DIR/autostart | grep -e '\w'`; do + echo -n " $NAME" + start_vpn + done + else + echo "no config found" + exit 1; + fi + else + while shift ; do + [ -z "$1" ] && break + NAME=$1 + echo -n " $NAME" + start_vpn + done + fi + echo "." + ;; + stop) + echo -n "Stoping $DESC:" + if test -z "$2" ; then + for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + stop_vpn + done + else + while shift ; do + [ -z "$1" ] && break + if test -e /var/run/anytun.$1.pid ; then + PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null` + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + stop_vpn + else + echo -n " (failure: No such tunnel is running: $1)" + fi + done + fi + echo "." + ;; + reload) + echo -n "Reloading $DESC:" + if test -z "$2" ; then + for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then + stop_vpn + start_vpn + else + stop_configd + start_configd + fi + done + else + while shift ; do + [ -z "$1" ] && break + if test -e /var/run/anytun.$1.pid ; then + PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null` + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then + stop_vpn + start_vpn + else + stop_configd + start_configd + fi + else + echo -n " (failure: No such tunnel is running: $1)" + fi + done + fi + echo "." + ;; + force-reload) + echo -n "Restarting $DESC:" + if test -z "$2" ; then + for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + stop_vpn + sleep 1 + start_vpn + done + else + while shift ; do + [ -z "$1" ] && break + if test -e /var/run/anytun.$1.pid ; then + PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null` + NAME=`echo $PIDFILE | cut -c17-` + NAME=${NAME%%.pid} + echo -n " $NAME" + stop_vpn + sleep 1 + start_vpn + else + echo -n " (failure: No such tunnel is running: $1)" + fi + done + fi + echo "." + ;; + restart) + SCRIPT=$0 + shift + $SCRIPT stop $* + sleep 1 + $SCRIPT start $* + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/src/Doxyfile b/src/Doxyfile new file mode 100644 index 0000000..9b5e4ef --- /dev/null +++ b/src/Doxyfile @@ -0,0 +1,1252 @@ +# Doxyfile 1.5.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "anytun" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..4f75c70 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,198 @@ +## +## anytun +## +## The secure anycast tunneling protocol (satp) defines a protocol used +## for communication between any combination of unicast and anycast +## tunnel endpoints. It has less protocol overhead than IPSec in Tunnel +## mode and allows tunneling of every ETHER TYPE protocol (e.g. +## ethernet, ip, arp ...). satp directly includes cryptography and +## message authentication based on the methodes used by SRTP. It is +## intended to deliver a generic, scaleable and secure solution for +## tunneling and relaying of packets of any protocol. +## +## +## Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, +## Christian Pointner +## +## This file is part of Anytun. +## +## Anytun is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 3 as +## published by the Free Software Foundation. +## +## Anytun 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 anytun. If not, see . +## + +ifneq ($(MAKECMDGOALS),distclean) +include include.mk +endif + +OBJS := tunDevice.o \ + packetSource.o \ + buffer.o \ + syncBuffer.o \ + plainPacket.o \ + encryptedPacket.o \ + cipher.o \ + authAlgo.o \ + keyDerivation.o \ + cipherFactory.o \ + authAlgoFactory.o \ + keyDerivationFactory.o \ + connectionList.o \ + connectionParam.o \ + networkAddress.o \ + networkPrefix.o \ + routingTable.o \ + signalController.o \ + log.o \ + logTargets.o \ + anytunError.o \ + options.o \ + seqWindow.o \ + routingTreeNode.o \ + resolver.o + +SYNCOBJS := syncServer.o \ + syncClient.o \ + syncQueue.o \ + syncCommand.o \ + syncRouteCommand.o \ + syncConnectionCommand.o \ + syncTcpConnection.o + +ANYCTROBJS := signalController.o \ + anyCtrOptions.o \ + buffer.o \ + log.o \ + logTargets.o \ + anytunError.o \ + syncTcpConnection.o \ + syncServer.o \ + resolver.o + +ANYCONFOBJS := log.o \ + logTargets.o \ + anytunError.o \ + buffer.o \ + keyDerivation.o \ + keyDerivationFactory.o \ + networkAddress.o \ + networkPrefix.o \ + connectionList.o \ + connectionParam.o \ + routingTreeNode.o \ + anyConfOptions.o \ + routingTable.o \ + seqWindow.o \ + syncQueue.o \ + syncBuffer.o \ + syncCommand.o \ + syncServer.o \ + syncTcpConnection.o \ + syncRouteCommand.o \ + syncConnectionCommand.o \ + resolver.o + +EXECUTABLE := anytun anytun-config anytun-controld anytun-showtables anytun-nosync +EXEOBJS := anytun.o anytun-config.o anytun-controld.o anytun-showtables.o + +SRCS := $(OBJS:%.o=%.cpp) +SYNCSRCS := $(SYNCOBJS:%.o=%.cpp) +ANYCTRSRCS := $(ANYCTROBJS:%.o=%.cpp) +ANYCONFSRCS := $(ANYCONFOBJS:%.o=%.cpp) +EXESRCS := $(EXEOBJS:%.o=%.cpp) + +.PHONY: distclean cleanall clean ctags + +all: $(EXECUTABLE) #libAnysync.a + +%.d: %.cpp + @set -e; rm -f $@; \ + $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$; echo '(re)building $@' + +ifneq ($(MAKECMDGOALS),distclean) +-include $(SRCS:%.cpp=%.d) $(SYNCSRCS:%.cpp=%.d) $(ANYCTRSRCS:%.cpp=%.d) $(ANYCONFSRCS:%.cpp=%.d) $(EXESRCS:%.cpp=%.d) +endif + +strip: $(EXECUTABLE) + strip -s $(EXECUTABLE) + +anytun: $(OBJS) $(SYNCOBJS) anytun.o + $(LD) $(OBJS) $(SYNCOBJS) anytun.o -o $@ $(LDFLAGS) + +anytun-static: $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o + $(LD) $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o -o $@ -Bstatic -lstdc++ -static $(LDFLAGS) -lpthread + strip -s anytun-static + +anytun-nosync: $(OBJS) anytun-nosync.o + $(LD) $(OBJS) anytun-nosync.o -o $@ $(LDFLAGS) + +anytun-nosync.o: anytun.cpp + $(CXX) $(CXXFLAGS) -DANYTUN_NOSYNC $< -c -o anytun-nosync.o + +anytun-noprivdrop.o: anytun.cpp + $(CXX) $(CXXFLAGS) -DNO_PRIVDROP $< -c -o anytun-noprivdrop.o + +anytun-showtables: $(OBJS) $(SYNCOBJS) anytun-showtables.o + $(LD) $(OBJS) $(SYNCOBJS) anytun-showtables.o -o $@ $(LDFLAGS) + +anytun-config: $(ANYCONFOBJS) anytun-config.o + $(LD) $(ANYCONFOBJS) anytun-config.o -o $@ $(LDFLAGS) + +anytun-controld: $(ANYCTROBJS) anytun-controld.o + $(LD) $(ANYCTROBJS) anytun-controld.o -o $@ $(LDFLAGS) + + +options.o: options.cpp + $(CXX) $(CXXFLAGS) -DANYTUN_OPTIONS $< -c -o $@ + +anyCtrOptions.o: options.cpp + $(CXX) $(CXXFLAGS) -DANYCTR_OPTIONS $< -c -o $@ + +anyConfOptions.o: options.cpp + $(CXX) $(CXXFLAGS) -DANYCONF_OPTIONS $< -c -o $@ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) $< -c + + +libAnysync.a: $(OBJS) + ar cru $@ $(OBJS) + ranlib $@ + +anyrtpproxy: anytun + $(MAKE) --directory=$(CURDIR)/anyrtpproxy + + +distclean: cleanall + find . -name *.o -exec rm -f {} \; + rm -f config.sub config.guess + rm -f tunDevice.cpp + rm -f include.mk + +cleanall: clean + $(MAKE) --directory=$(CURDIR)/man clean + +clean: + rm -f *.o + rm -f *.d + rm -f *.d.* + rm -f $(EXECUTABLE) + rm -f anytun-nosync + rm -f -r doc/html/* + rm -f -r doc/latex/* + rm -f libAnysync.a + $(MAKE) --directory=$(CURDIR)/anyrtpproxy clean + +manpage: + @cd man ; $(MAKE) + diff --git a/src/anyrtpproxy/Makefile b/src/anyrtpproxy/Makefile new file mode 100644 index 0000000..40ca273 --- /dev/null +++ b/src/anyrtpproxy/Makefile @@ -0,0 +1,79 @@ +## +## anytun +## +## The secure anycast tunneling protocol (satp) defines a protocol used +## for communication between any combination of unicast and anycast +## tunnel endpoints. It has less protocol overhead than IPSec in Tunnel +## mode and allows tunneling of every ETHER TYPE protocol (e.g. +## ethernet, ip, arp ...). satp directly includes cryptography and +## message authentication based on the methodes used by SRTP. It is +## intended to deliver a generic, scaleable and secure solution for +## tunneling and relaying of packets of any protocol. +## +## +## Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, +## Christian Pointner +## +## This file is part of Anytun. +## +## Anytun is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 3 as +## published by the Free Software Foundation. +## +## Anytun 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 anytun. If not, see . +## +CC = gcc +CFLAGS = -g -Wall +CXX = g++ +CXXFLAGS = -g -Wall +LD = g++ +LDFLAGS = -g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system + +OBJS = anyrtpproxy.o \ + ../signalController.o \ + ../log.o \ + ../buffer.o \ + rtpSessionTable.o \ + rtpSession.o \ + connectionList.o \ + ../syncServer.o \ + ../syncClient.o \ + ../syncTcpConnection.o \ + ../syncQueue.o \ + syncRtpCommand.o \ + commandHandler.o \ + portWindow.o \ + callIdQueue.o \ + options.o + +SRCS = $(OBJS:%.o=%.cpp) + +EXECUTABLE = anyrtpproxy +DEPENDFILE = .depend + +.PHONY: dep clean + +all: dep $(EXECUTABLE) + +dep: $(SRCS) + $(CC) -MM $(SRCS) > $(DEPENDFILE) + +-include $(DEPENDFILE) + +anyrtpproxy: $(OBJS) + $(LD) $(OBJS) -o $@ $(LDFLAGS) + +%.o: %.cpp + $(CXX) $(CXXFLAGS) $< -c + +clean: + rm -f *.o + rm -f $(DEPENDFILE) + rm -f $(EXECUTABLE) + diff --git a/src/anyrtpproxy/anyrtpproxy.cpp b/src/anyrtpproxy/anyrtpproxy.cpp new file mode 100644 index 0000000..fdb809e --- /dev/null +++ b/src/anyrtpproxy/anyrtpproxy.cpp @@ -0,0 +1,387 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include + +#include + +#include +#include +#include + +#include "../datatypes.h" + +#include "../log.h" +#include "../signalController.h" +#include "../buffer.h" +#include "connectionList.h" +#include "rtpSessionTable.h" +#include "syncRtpCommand.h" +#include "../syncQueue.h" +#include "../syncClient.h" +#include "syncOnConnect.hpp" + +#include "../threadUtils.hpp" + +#include "commandHandler.h" +#include "callIdQueue.h" + +#include "options.h" +#include "portWindow.h" +#include +#include + +#define MAX_PACKET_SIZE 1500 + +void listener(RtpSession::proto::socket* sock1, RtpSession::proto::socket* sock2, std::string call_id, int dir, SyncQueue* queue, bool* running) +{ + cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") started"; + + try + { + Buffer buf(u_int32_t(MAX_PACKET_SIZE)); + RtpSession::proto::endpoint remote_end; + + while(1) { + buf.setLength(MAX_PACKET_SIZE); + u_int32_t len=0; + if(dir == 1) + len = 0;//sock1->recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_end, 1000); + else if(dir == 2) + len = 0; //sock2->recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_end, 1000); + else break; + + RtpSession& session = gRtpSessionTable.getSession(call_id); + if(session.isDead()) { + cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") session is dead, exiting"; + break; + } + + if(!len) + continue; + buf.setLength(len); + + if((dir == 1 && remote_end != session.getRemoteEnd1()) || + (dir == 2 && remote_end != session.getRemoteEnd2())) + { + if(gOpt.getNat() || + (!gOpt.getNoNatOnce() && ((dir == 1 && !session.getSeen1()) || + (dir == 2 && !session.getSeen2())))) + { + cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") setting remote host to " + << remote_end; + if(dir == 1) + session.setRemoteEnd1(remote_end); + if(dir == 2) + session.setRemoteEnd2(remote_end); + + if(!gOpt.getNat()) { // with nat enabled sync is not needed + SyncRtpCommand sc(call_id); + queue->push(sc); + } + } + else + continue; + } + session.setSeen1(); + session.setSeen2(); + + if(dir == 1) + sock2->send_to(boost::asio::buffer(buf.getBuf(), buf.getLength()), session.getRemoteEnd2()); + else if(dir == 2) + sock1->send_to(boost::asio::buffer(buf.getBuf(), buf.getLength()), session.getRemoteEnd1()); + else break; + } + } + catch(std::exception &e) + { + cLog.msg(Log::PRIO_ERR) << "listener(" << call_id << "/" << dir << ") exiting because: " << e.what(); + } + *running = false; + gCallIdQueue.push(call_id); +} + +class ListenerData +{ +public: + ListenerData() : sock1_(ios1_), sock2_(ios2_) {} + + boost::asio::io_service ios1_; + boost::asio::io_service ios2_; + RtpSession::proto::socket sock1_; + RtpSession::proto::socket sock2_; + boost::thread* thread1_; + boost::thread* thread2_; + bool running1_; + bool running2_; +}; + +void listenerManager(void* p) +{ + SyncQueue* queue_ = reinterpret_cast(p); + + std::map listenerMap; + while(1) + { + try + { + std::string call_id = gCallIdQueue.front(); // waits for semaphor and returns next call_id + gCallIdQueue.pop(); + + RtpSession& session = gRtpSessionTable.getSession(call_id); + if(!session.isComplete()) + continue; + + std::map::iterator it; + it = listenerMap.find(call_id); + if(it == listenerMap.end()) // listener Threads not existing yet + { + ListenerData* ld = new ListenerData(); + + ld->sock1_.open(session.getLocalEnd1().protocol()); + ld->sock1_.bind(session.getLocalEnd1()); + + ld->sock2_.open(session.getLocalEnd2().protocol()); + ld->sock2_.bind(session.getLocalEnd2()); + + ld->thread1_ = new boost::thread(boost::bind(listener, &(ld->sock1_), &(ld->sock2_), call_id, 1, queue_, &(ld->running1_))); + ld->thread2_ = new boost::thread(boost::bind(listener, &(ld->sock1_), &(ld->sock2_), call_id, 2, queue_, &(ld->running2_))); + + std::pair::iterator, bool> ret; + ret = listenerMap.insert(std::map::value_type(call_id, ld)); + continue; + } + + if(!it->second->running1_ && !it->second->running2_) + { + cLog.msg(Log::PRIO_NOTICE) << "listenerManager both threads for '" << call_id << "' exited, cleaning up"; + if(it->second->thread1_) { + it->second->thread1_->join(); + delete it->second->thread1_; + } + if(it->second->thread2_) { + it->second->thread2_->join(); + delete it->second->thread2_; + } + delete it->second; + listenerMap.erase(it); + gRtpSessionTable.delSession(call_id); + continue; + } + // TODO: reinit if session changed + } + catch(std::exception &e) + { + cLog.msg(Log::PRIO_ERR) << "listenerManager restarting after exception: " << e.what(); + usleep(500); // in case of an hard error don't block cpu (this is ugly) + } + } + cLog.msg(Log::PRIO_ERR) << "listenerManager exiting because of unknown reason"; +} + +void chrootAndDrop(string const& chrootdir, string const& username) +{ + if (getuid() != 0) + { + std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl; + exit(-1); + } + + struct passwd *pw = getpwnam(username.c_str()); + if(pw) { + if(chroot(chrootdir.c_str())) + { + std::cerr << "can't chroot to " << chrootdir << std::endl; + exit(-1); + } + std::cout << "we are in chroot jail (" << chrootdir << ") now" << std::endl; + chdir("/"); + if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid)) + { + std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl; + exit(-1); + } + std::cout << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl; + } + else + { + std::cerr << "unknown user " << username << std::endl; + exit(-1); + } +} + +void daemonize() +{ + pid_t pid; + + pid = fork(); + if(pid) exit(0); + setsid(); + pid = fork(); + if(pid) exit(0); + +// std::cout << "running in background now..." << std::endl; + + int fd; +// for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors + for (fd=0;fd<=2;fd++) // close all file descriptors + close(fd); + fd=open("/dev/null",O_RDWR); // stdin + dup(fd); // stdout + dup(fd); // stderr + umask(027); +} + +class ThreadParam +{ +public: + ThreadParam(SyncQueue & queue_,OptionConnectTo & connto_) + : queue(queue_),connto(connto_) + {}; + SyncQueue & queue; + OptionConnectTo & connto; +}; + +void syncConnector(void* p) +{ + ThreadParam* param = reinterpret_cast(p); + + SyncClient sc ( param->connto.host, param->connto.port); + sc.run(); +} + +void syncListener(SyncQueue * queue) +{ + try + { + boost::asio::io_service io_service; + SyncTcpConnection::proto::resolver resolver(io_service); + SyncTcpConnection::proto::endpoint e; + if(gOpt.getLocalSyncAddr()!="") + { + SyncTcpConnection::proto::resolver::query query(gOpt.getLocalSyncAddr(), gOpt.getLocalSyncPort()); + e = *resolver.resolve(query); + } else { + SyncTcpConnection::proto::resolver::query query(gOpt.getLocalSyncPort()); + e = *resolver.resolve(query); + } + + + SyncServer server(io_service,e); + server.onConnect=boost::bind(syncOnConnect,_1); + queue->setSyncServerPtr(&server); + io_service.run(); + } + catch (std::exception& e) + { + std::string addr = gOpt.getLocalSyncAddr() == "" ? "*" : gOpt.getLocalSyncAddr(); + cLog.msg(Log::PRIO_ERR) << "sync: cannot bind to " << addr << ":" << gOpt.getLocalSyncPort() + << " (" << e.what() << ")" << std::endl; + } + +} + +int main(int argc, char* argv[]) +{ +// std::cout << "anyrtpproxy" << std::endl; + if(!gOpt.parse(argc, argv)) + { + gOpt.printUsage(); + exit(-1); + } + + cLog.setLogName("anyrtpproxy"); + cLog.msg(Log::PRIO_NOTICE) << "anyrtpproxy started..."; + + std::ofstream pidFile; + if(gOpt.getPidFile() != "") { + pidFile.open(gOpt.getPidFile().c_str()); + if(!pidFile.is_open()) { + std::cout << "can't open pid file" << std::endl; + } + } + + if(gOpt.getChroot()) + chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername()); + if(gOpt.getDaemonize()) + daemonize(); + + if(pidFile.is_open()) { + pid_t pid = getpid(); + pidFile << pid; + pidFile.close(); + } + + SignalController sig; + sig.init(); + + SyncQueue queue; + + + boost::thread listenerManagerThread(boost::bind(listenerManager,&queue)); + + +// #ifndef ANYTUN_NOSYNC +// boost::thread * syncListenerThread; +// if(gOpt.getLocalSyncPort() != "") +// syncListenerThread = new boost::thread(boost::bind(syncListener,&queue)); + +// std::list connectThreads; +// for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it) { +// ThreadParam * point = new ThreadParam(dev, *src, cl, queue,*it); +// connectThreads.push_back(new boost::thread(boost::bind(syncConnector,point))); +// } +// #endif + + + +// pthread_t syncListenerThread; + +// ConnectToList connect_to = gOpt.getConnectTo(); +// ThreadParam p( queue,*(new OptionConnectTo())); +// if ( gOpt.getLocalSyncPort()) +// pthread_create(&syncListenerThread, NULL, syncListener, &p); + +// std::list connectThreads; +// for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it) +// { +// connectThreads.push_back(pthread_t()); +// ThreadParam * point = new ThreadParam(queue,*it); +// pthread_create(& connectThreads.back(), NULL, syncConnector, point); +// } + + PortWindow port_window(gOpt.getRtpStartPort(),gOpt.getRtpEndPort()); + CommandHandler cmd(queue, gOpt.getControlInterface().addr_, gOpt.getControlInterface().port_,port_window); + + int ret = sig.run(); + return ret; +} + diff --git a/src/anyrtpproxy/callIdQueue.cpp b/src/anyrtpproxy/callIdQueue.cpp new file mode 100644 index 0000000..e2ce700 --- /dev/null +++ b/src/anyrtpproxy/callIdQueue.cpp @@ -0,0 +1,77 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "callIdQueue.h" + +CallIdQueue* CallIdQueue::inst = NULL; +Mutex CallIdQueue::instMutex; +CallIdQueue& gCallIdQueue = CallIdQueue::instance(); + +CallIdQueue& CallIdQueue::instance() +{ + Lock lock(instMutex); + static instanceCleaner c; + if(!inst) + inst = new CallIdQueue(); + + return *inst; +} + +CallIdQueue::CallIdQueue() +{ +} + +CallIdQueue::~CallIdQueue() +{ + while(!callids_.empty()) + pop(); +} + +std::string& CallIdQueue::front() +{ + sem_.down(); + Lock lock(mutex_); + return callids_.front(); +} + +void CallIdQueue::push(std::string c) +{ + Lock lock(mutex_); + callids_.push(c); + sem_.up(); +} + +void CallIdQueue::pop() +{ + Lock lock(mutex_); + callids_.pop(); +} + diff --git a/src/anyrtpproxy/callIdQueue.h b/src/anyrtpproxy/callIdQueue.h new file mode 100644 index 0000000..1ffe2df --- /dev/null +++ b/src/anyrtpproxy/callIdQueue.h @@ -0,0 +1,73 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef __CALLID_QUEUE_H__ +#define __CALLID_QUEUE_H__ + +#include +#include + +#include "../threadUtils.hpp" + +class CallIdQueue +{ +public: + static CallIdQueue& instance(); + + std::string& front(); + void push(std::string c); + void pop(); + +private: + CallIdQueue(); + ~CallIdQueue(); + + void operator=(const CallIdQueue &src); + CallIdQueue(const CallIdQueue &src); + + static CallIdQueue* inst; + static ::Mutex instMutex; + class instanceCleaner { + public: ~instanceCleaner() { + if(CallIdQueue::inst != 0) + delete CallIdQueue::inst; + } + }; + friend class instanceCleaner; + + ::Mutex mutex_; + Semaphore sem_; + std::queue callids_; +}; + +extern CallIdQueue& gCallIdQueue; + +#endif diff --git a/src/anyrtpproxy/commandHandler.cpp b/src/anyrtpproxy/commandHandler.cpp new file mode 100644 index 0000000..01613ec --- /dev/null +++ b/src/anyrtpproxy/commandHandler.cpp @@ -0,0 +1,286 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include + +#include "commandHandler.h" +#include "../buffer.h" +#include "../log.h" +#include "../syncQueue.h" +#include "syncRtpCommand.h" +#include "rtpSessionTable.h" +#include "callIdQueue.h" +#include "options.h" + +#define MAX_COMMAND_LENGTH 1000 + +CommandHandler::CommandHandler(SyncQueue& q, std::string lp,PortWindow & pw) : thread_(boost::bind(run,this)), + queue_(q), running_(true), control_sock_(io_service_), + local_address_(""), local_port_(lp),port_window_(pw) +{ + proto::resolver resolver(io_service_); + proto::resolver::query query(local_port_); + proto::endpoint e = *resolver.resolve(query); + control_sock_.open(e.protocol()); + control_sock_.bind(e); +} + +CommandHandler::CommandHandler(SyncQueue& q, string la, std::string lp, PortWindow & pw) : thread_(boost::bind(run,this)), + queue_(q), running_(true), control_sock_(io_service_), + local_address_(la), local_port_(lp),port_window_(pw) +{ + proto::resolver resolver(io_service_); + proto::resolver::query query(local_address_, local_port_); + proto::endpoint e = *resolver.resolve(query); + control_sock_.open(e.protocol()); + control_sock_.bind(e); +} + +void CommandHandler::run(void* s) +{ + CommandHandler* self = reinterpret_cast(s); + + Buffer buf(u_int32_t(MAX_COMMAND_LENGTH)); + try + { + proto::endpoint remote_end; + + int len; + while(1) + { + buf.setLength(MAX_COMMAND_LENGTH); + + len = self->control_sock_.receive_from(boost::asio::buffer(buf.getBuf(), buf.getLength()), remote_end); + buf.setLength(len); + + std::string ret = self->handle(std::string(reinterpret_cast(buf.getBuf()), buf.getLength())); // TODO: reinterpret is ugly + + cLog.msg(Log::PRIO_DEBUG) << "CommandHandler received Command from " << remote_end << ", ret='" << ret << "'"; + + self->control_sock_.send_to(boost::asio::buffer(ret.c_str(), ret.length()), remote_end); + } + } + catch(std::exception& e) + { + self->running_ = false; + } + self->running_ = false; +} + +bool CommandHandler::isRunning() +{ + return running_; +} + + + +std::string CommandHandler::handle(std::string command) +{ + istringstream iss(command); + ostringstream oss; + std::string cookie; + std::string cmd; + + iss >> cookie; + oss << cookie << " "; + + if(iss.bad() || iss.eof()) { + oss << RET_ERR_SYNTAX; + return oss.str(); + } + iss >> cmd; + + std::vector params; + while(!iss.bad() && !iss.eof()) { + std::string tmp; + iss >> tmp; + params.push_back(tmp); + } + + switch(std::toupper(cmd[0])) + { + case CMD_REQUEST: + if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; } + oss << handleRequest(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]); + break; + case CMD_RESPONSE: + if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; } + oss << handleResponse(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]); + break; + case CMD_DELETE: + if(params.size() < 2) { oss << RET_ERR_SYNTAX; break; } + oss << handleDelete(params[0], params[1], (params.size() < 3) ? "" : params[2]); + break; + case CMD_VERSION: + if(cmd.length() > 1 && cmd[1] == 'F') { + if(params.size() < 1) { oss << RET_ERR_SYNTAX; break; } + oss << handleVersionF(params[0]); + break; + } + oss << handleVersion(); + break; + case CMD_INFO: + oss << handleInfo(); + break; + default: + oss << RET_ERR_SYNTAX; + break; + } + + return oss.str(); +} + +string CommandHandler::handleRequest(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag) +{ + std::cout << "received request[" << modifiers << "] command ('" << call_id << "','" << addr << "','" << port + << "','" << from_tag << "','" << to_tag << "')" << std::endl; + + try + { + RtpSession::proto::resolver resolver(io_service_); + bool is_new; + RtpSession& session = gRtpSessionTable.getOrNewSession(call_id, is_new); + if(is_new) + { + u_int16_t port1 = port_window_.newPort(); // TODO: get next available port + u_int16_t port2 = port_window_.newPort(); // TODO: get next available port + if( !port1 || !port2) + { + if( port1) port_window_.freePort(port1); + if( port2) port_window_.freePort(port2); + throw std::runtime_error("no free port found"); + } + std::stringstream ps1, ps2; + ps1 << port1; + ps2 << port2; + + RtpSession::proto::endpoint e1, e2; + if(gOpt.getLocalAddr() == "") { + RtpSession::proto::resolver::query query1(ps1.str()); + e1 = *resolver.resolve(query1); + RtpSession::proto::resolver::query query2(ps2.str()); + e2 = *resolver.resolve(query2); + } + else { + RtpSession::proto::resolver::query query1(gOpt.getLocalAddr(),ps1.str()); + e1 = *resolver.resolve(query1); + RtpSession::proto::resolver::query query2(gOpt.getLocalAddr(),ps2.str()); + e2 = *resolver.resolve(query2); + } + + session.setLocalEnd1(e1); + session.setLocalEnd2(e2); + } + RtpSession::proto::resolver::query query(addr,port); + session.setRemoteEnd1(*resolver.resolve(query)); + + ostringstream oss; + oss << session.getLocalEnd2().port(); + return oss.str(); + } + catch(std::exception& e) + { + return RET_ERR_UNKNOWN; // TODO: change to corret error value + } +} + +string CommandHandler::handleResponse(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag) +{ + std::cout << "received response[" << modifiers << "] command ('" << call_id << "','" << addr << "','" << port + << "','" << from_tag << "','" << to_tag << "')" << std::endl; + + try + { + RtpSession& session = gRtpSessionTable.getSession(call_id); + RtpSession::proto::resolver resolver(io_service_); + RtpSession::proto::resolver::query query(addr,port); + session.setRemoteEnd2(*resolver.resolve(query)); + session.isComplete(true); + SyncRtpCommand sc(call_id); + queue_.push(sc); + + ostringstream oss; + oss << session.getLocalEnd1().port(); + return oss.str(); + } + catch(std::exception& e) + { + return RET_ERR_UNKNOWN; // TODO: change to corret error value + } +} + +string CommandHandler::handleDelete(string call_id, string from_tag, string to_tag) +{ + std::cout << "received delete command ('" << call_id << "','" << from_tag << "','" << to_tag << "')" << std::endl; + + try + { + RtpSession& session = gRtpSessionTable.getSession(call_id); + session.isDead(true); + SyncRtpCommand sc(call_id); + queue_.push(sc); + + return RET_OK; + } + catch(std::exception& e) + { + return RET_ERR_UNKNOWN; // TODO: change to corret error value + } +} + +string CommandHandler::handleVersion() +{ + std::cout << "received version command" << std::endl; + return BASE_VERSION; +} + +string CommandHandler::handleVersionF(string date_code) +{ + std::cout << "received version[F] command ('" << date_code << "')" << std::endl; + if(!date_code.compare(SUP_VERSION)) + return "1"; + + return "0"; +} + +string CommandHandler::handleInfo() +{ + std::cout << "received info command, ignoring" << std::endl; + return RET_OK; +} + diff --git a/src/anyrtpproxy/commandHandler.h b/src/anyrtpproxy/commandHandler.h new file mode 100644 index 0000000..6bd802a --- /dev/null +++ b/src/anyrtpproxy/commandHandler.h @@ -0,0 +1,92 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _COMMAND_HANDLER_H_ +#define _COMMAND_HANDLER_H_ + +#include + +#include +#include "../datatypes.h" +#include "../PracticalSocket.h" +#include "../syncQueue.h" +#include "portWindow.h" + +class CommandHandler +{ +public: + typedef boost::asio::ip::udp proto; + + CommandHandler(SyncQueue& q, std::string lp, PortWindow &); + CommandHandler(SyncQueue& q, std::string la, std::string lp, PortWindow &); + + bool isRunning(); + + #define CMD_REQUEST 'U' + #define CMD_RESPONSE 'L' + #define CMD_DELETE 'D' + #define CMD_VERSION 'V' + #define CMD_INFO 'I' + + #define RET_OK "0" + #define RET_ERR_SYNTAX "E1" + #define RET_ERR_UNKNOWN "E2" + + #define BASE_VERSION "20040107" + #define SUP_VERSION "20050322" + +private: + CommandHandler(const CommandHandler &c); + void operator=(const CommandHandler &c); + + static void run(void* s); + std::string handle(std::string command); + + std::string handleRequest(std::string modifiers, std::string call_id, std::string addr, std::string port, std::string from_tag, std::string to_tag); + std::string handleResponse(std::string modifiers, std::string call_id, std::string addr, std::string port, std::string from_tag, std::string to_tag); + std::string handleDelete(std::string call_id, std::string from_tag, std::string to_tag); + std::string handleVersion(); + std::string handleVersionF(std::string date_code); + std::string handleInfo(); + + boost::thread thread_; + SyncQueue& queue_; + + bool running_; + boost::asio::io_service io_service_; + proto::socket control_sock_; + std::string local_address_; + std::string local_port_; + PortWindow& port_window_; +}; + + +#endif diff --git a/src/anyrtpproxy/connectionList.cpp b/src/anyrtpproxy/connectionList.cpp new file mode 100644 index 0000000..eea1e38 --- /dev/null +++ b/src/anyrtpproxy/connectionList.cpp @@ -0,0 +1,90 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "connectionList.h" + +ConnectionList::ConnectionList() +{ +} + +ConnectionList::~ConnectionList() +{ +} + +void ConnectionList::addConnection(ConnectionParam &conn, u_int16_t mux ) +{ +} + +const ConnectionMap::iterator ConnectionList::getEnd() +{ + return connections_.end(); +} + +ConnectionMap::iterator ConnectionList::getBeginUnlocked() +{ + return connections_.begin(); +} + +ConnectionMap::iterator ConnectionList::getEndUnlocked() +{ + return connections_.end(); +} + +const ConnectionMap::iterator ConnectionList::getConnection(u_int16_t mux) +{ + Lock lock(mutex_); + ConnectionMap::iterator it = connections_.find(mux); + return it; +} + + +ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux) +{ + ConnectionMap::iterator it = connections_.find(mux); + return it->second; +} + +void ConnectionList::clear() +{ + Lock lock(mutex_); + connections_.clear(); +} + +bool ConnectionList::empty() +{ + Lock lock(mutex_); + return connections_.empty(); +} + +Mutex& ConnectionList::getMutex() +{ + return mutex_; +} diff --git a/src/anyrtpproxy/connectionList.h b/src/anyrtpproxy/connectionList.h new file mode 100644 index 0000000..de45f8a --- /dev/null +++ b/src/anyrtpproxy/connectionList.h @@ -0,0 +1,65 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CONNECTION_LIST_H +#define _CONNECTION_LIST_H + +#include + +#include "../threadUtils.hpp" +#include "../datatypes.h" +#include "../connectionParam.h" +#include "../networkAddress.h" +typedef std::map ConnectionMap; + +class ConnectionList +{ +public: + ConnectionList(); + ~ConnectionList(); + void addConnection(ConnectionParam &conn, u_int16_t mux); + const ConnectionMap::iterator getConnection(u_int16_t mux); + const ConnectionMap::iterator getEnd(); + ConnectionMap::iterator getEndUnlocked(); + ConnectionMap::iterator getBeginUnlocked(); + ConnectionParam & getOrNewConnectionUnlocked(u_int16_t mux); + bool empty(); + void clear(); + Mutex& getMutex(); + +private: + ConnectionList(const ConnectionList &s); + void operator=(const ConnectionList &s); + ConnectionMap connections_; + Mutex mutex_; +}; + +#endif diff --git a/src/anyrtpproxy/options.cpp b/src/anyrtpproxy/options.cpp new file mode 100644 index 0000000..6a48483 --- /dev/null +++ b/src/anyrtpproxy/options.cpp @@ -0,0 +1,408 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include +#include + +#include "options.h" + +Options* Options::inst = NULL; +Mutex Options::instMutex; +Options& gOpt = Options::instance(); + +Options& Options::instance() +{ + Lock lock(instMutex); + static instanceCleaner c; + if(!inst) + inst = new Options(); + + return *inst; +} + +void Host::splitAndSetAddrPort(std::string addr_port) +{ + if(addr_port.length() >= 2 && addr_port[0] == ':' && addr_port[1] != ':') { + addr_ = ""; + addr_port.erase(0,1); + std::stringstream tmp_stream(addr_port); + tmp_stream >> port_; + return; + } + + size_t pos = addr_port.find_first_of("["); + + if(pos != std::string::npos && pos != 0) + return; // an [ was found but not at the beginning + + bool hasPort = false; + if(pos != std::string::npos) { + addr_port.erase(pos, 1); + pos = addr_port.find_first_of("]"); + + if(pos == std::string::npos) + return; // no trailing ] although an leading [ was found + + if(pos < addr_port.length()-2) { + + if(addr_port[pos+1] != ':') + return; // wrong port delimieter + + addr_port[pos+1] = '/'; + hasPort = true; + } + else if(pos != addr_port.length()-1) + return; // to few characters left + + addr_port.erase(pos, 1); + } + + if(hasPort) { + std::stringstream tmp_stream(addr_port); + + getline(tmp_stream, addr_, '/'); + if(!tmp_stream.good()) + return; + + tmp_stream >> port_; + } + else { + addr_ = addr_port; + port_ = "2323"; // default sync port + } +} + + +Options::Options() : control_interface_("0.0.0.0", "22222") + +{ + progname_ = "anyrtpproxy"; + chroot_ = false; + username_ = "nobody"; + chroot_dir_ = "/var/run"; + daemonize_ = true; + pid_file_ = ""; + local_addr_ = ""; + local_sync_port_ = ""; + rtp_start_port_ = 34000; + rtp_end_port_ = 35000; + no_nat_once_ = false; + nat_ = false; +} + +Options::~Options() +{ +} + +#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \ + else if(str == SHORT || str == LONG) \ + VALUE = true; + +#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \ + else if(str == SHORT || str == LONG) \ + VALUE = false; + +#define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 1 || argv[i+1][0] == '-') \ + return false; \ + std::stringstream tmp; \ + tmp << argv[i+1]; \ + tmp >> VALUE; \ + argc--; \ + i++; \ + } + +#define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 2 || \ + argv[i+1][0] == '-' || argv[i+2][0] == '-') \ + return false; \ + std::stringstream tmp; \ + tmp << argv[i+1] << " " << argv[i+2]; \ + tmp >> VALUE1; \ + tmp >> VALUE2; \ + argc-=2; \ + i+=2; \ + } + +#define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 1 || argv[i+1][0] == '-') \ + return false; \ + VALUE = std::string(argv[i+1]); \ + argc--; \ + i++; \ + } + +#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 1 || argv[i+1][0] == '-') \ + return false; \ + VALUE = Buffer(std::string(argv[i+1])); \ + for(size_t j=0; j < strlen(argv[i+1]); ++j) \ + argv[i+1][j] = '#'; \ + argc--; \ + i++; \ + } + +#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST) \ + else if(str == SHORT || str == LONG) \ + { \ + if(argc < 1 || argv[i+1][0] == '-') \ + return false; \ + std::stringstream tmp(argv[i+1]); \ + /* LIST.clear(); */ \ + while (tmp.good()) \ + { \ + std::string tmp_line; \ + getline(tmp,tmp_line,','); \ + LIST.push(tmp_line); \ + } \ + argc--; \ + i++; \ + } + +bool Options::parse(int argc, char* argv[]) +{ + Lock lock(mutex); + + progname_ = argv[0]; + std::queue host_port_queue; + argc--; + for(int i=1; argc > 0; ++i) + { + std::string str(argv[i]); + argc--; + + if(str == "-h" || str == "--help") + return false; + PARSE_BOOL_PARAM("-t","--chroot", chroot_) + PARSE_BOOL_PARAM("-n","--nat", nat_) + PARSE_BOOL_PARAM("-o","--no-nat-once", no_nat_once_) + PARSE_SCALAR_PARAM("-u","--user", username_) + PARSE_SCALAR_PARAM("-c","--chroot-dir", chroot_dir_) + PARSE_INVERSE_BOOL_PARAM("-d","--nodaemonize", daemonize_) + PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_) + PARSE_SCALAR_PARAM("-i","--interface", local_addr_) + PARSE_STRING_PARAM("-s","--control", control_interface_) + PARSE_SCALAR_PARAM2("-p","--port-range", rtp_start_port_, rtp_end_port_) + PARSE_CSLIST_PARAM("-M","--sync-hosts", host_port_queue) + PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_port_) + PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_addr_) + else + return false; + } + while(!host_port_queue.empty()) + { + std::stringstream tmp_stream(host_port_queue.front()); + OptionConnectTo oct; + getline(tmp_stream,oct.host,':'); + if(!tmp_stream.good()) + return false; + tmp_stream >> oct.port; + host_port_queue.pop(); + connect_to_.push_back(oct); + } + + return sanityCheck(); +} + +bool Options::sanityCheck() +{ + if(control_interface_.port_ == "") control_interface_.port_ = "22222"; + return true; +} + +void Options::printUsage() +{ + std::cout << "USAGE: anyrtpproxy" << std::endl; + std::cout << " [-h|--help] prints this..." << std::endl; + std::cout << " [-t|--chroot] chroot and drop priviledges" << std::endl; + std::cout << " [-u|--username] in case of chroot run as this user" << std::endl; + std::cout << " [-c|--chroot-dir] directory to make a chroot to" << std::endl; + std::cout << " [-d|--nodaemonize] don't run in background" << std::endl; + std::cout << " [-P|--write-pid] write pid to this file" << std::endl; + std::cout << " [-i|--interface] local ip address to listen to for RTP packets" << std::endl; + std::cout << " [-s|--control] [:] the address/port to listen on for control commands" << std::endl; + std::cout << " [-p|--port-range] port range used to relay rtp connections" << std::endl; + std::cout << " [-n|--nat] enable permantent automatic nat detection(use only with anytun)" << std::endl; + std::cout << " [-o|--no-nat-once] disable automatic nat detection for new connections" << std::endl; + std::cout << " [-I|--sync-interface] local unicast(sync) ip address to bind to" << std::endl; + std::cout << " [-S|--sync-port] local unicast(sync) port to bind to" << std::endl; + std::cout << " [-M|--sync-hosts] :[,:[...]]"<< std::endl; + std::cout << " List of Remote Sync Hosts/Ports"<< std::endl; +} + +void Options::printOptions() +{ + Lock lock(mutex); + std::cout << "Options:" << std::endl; + std::cout << "chroot='" << chroot_ << "'" << std::endl; + std::cout << "username='" << username_ << "'" << std::endl; + std::cout << "chroot-dir='" << chroot_dir_ << "'" << std::endl; + std::cout << "daemonize='" << daemonize_ << "'" << std::endl; + std::cout << "pid_file='" << pid_file_ << "'" << std::endl; + std::cout << "control-interface='" << control_interface_.toString() << "'" << std::endl; + std::cout << "local_addr='" << local_addr_ << "'" << std::endl; + std::cout << "rtp_start_port=" << rtp_start_port_ << std::endl; + std::cout << "rtp_end_port=" << rtp_end_port_ << std::endl; + std::cout << "local_sync_addr='" << local_sync_addr_ << "'" << std::endl; + std::cout << "local_sync_port='" << local_sync_port_ << "'" << std::endl; +} + +std::string Options::getProgname() +{ + Lock lock(mutex); + return progname_; +} + +bool Options::getChroot() +{ + Lock lock(mutex); + return chroot_; +} + +bool Options::getNat() +{ + Lock lock(mutex); + return nat_; +} + +bool Options::getNoNatOnce() +{ + Lock lock(mutex); + return no_nat_once_; +} + +std::string Options::getUsername() +{ + Lock lock(mutex); + return username_; +} + +std::string Options::getChrootDir() +{ + Lock lock(mutex); + return chroot_dir_; +} + +bool Options::getDaemonize() +{ + Lock lock(mutex); + return daemonize_; +} + +std::string Options::getPidFile() +{ + Lock lock(mutex); + return pid_file_; +} + +Host Options::getControlInterface() +{ + Lock lock(mutex); + return control_interface_; +} + +std::string Options::getLocalAddr() +{ + Lock lock(mutex); + return local_addr_; +} + +Options& Options::setLocalAddr(std::string l) +{ + Lock lock(mutex); + local_addr_ = l; + return *this; +} + +std::string Options::getLocalSyncAddr() +{ + Lock lock(mutex); + return local_sync_addr_; +} + +Options& Options::setLocalSyncAddr(std::string l) +{ + Lock lock(mutex); + local_sync_addr_ = l; + return *this; +} + +std::string Options::getLocalSyncPort() +{ + Lock lock(mutex); + return local_sync_port_; +} + +Options& Options::setLocalSyncPort(std::string l) +{ + Lock lock(mutex); + local_sync_port_ = l; + return *this; +} + +u_int16_t Options::getRtpStartPort() +{ + return rtp_start_port_; +} + +Options& Options::setRtpStartPort(u_int16_t l) +{ + rtp_start_port_ = l; + return *this; +} + +u_int16_t Options::getRtpEndPort() +{ + return rtp_end_port_; +} + +Options& Options::setRtpEndPort(u_int16_t l) +{ + rtp_end_port_ = l; + return *this; +} + +ConnectToList Options::getConnectTo() +{ + Lock lock(mutex); + return connect_to_; +} + diff --git a/src/anyrtpproxy/options.h b/src/anyrtpproxy/options.h new file mode 100644 index 0000000..af09d4f --- /dev/null +++ b/src/anyrtpproxy/options.h @@ -0,0 +1,138 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _OPTIONS_H_ +#define _OPTIONS_H_ + +#include "../threadUtils.hpp" +#include +#include + +typedef struct OptionConnectTo +{ + std::string host; + std::string port; +}; + +typedef std::list ConnectToList; + +class Host +{ +public: + Host(std::string addr, std::string port) : addr_(addr), port_(port) {} + Host(std::string addr_port) { + splitAndSetAddrPort(addr_port); + } + std::string toString() const + { + std::ostringstream oss; + oss << addr_ << ":" << port_; + return oss.str(); + } + + std::string addr_; + std::string port_; + +protected: + void splitAndSetAddrPort(std::string addr_port); +}; + +typedef std::list HostList; + +class Options +{ +public: + static Options& instance(); + + bool parse(int argc, char* argv[]); + void printUsage(); + void printOptions(); + + std::string getProgname(); + bool getChroot(); + bool getNat(); + bool getNoNatOnce(); + std::string getUsername(); + std::string getChrootDir(); + std::string getPidFile(); + bool getDaemonize(); + Host getControlInterface(); + std::string getLocalAddr(); + Options& setLocalAddr(std::string l); + std::string getLocalSyncAddr(); + Options& setLocalSyncAddr(std::string l); + std::string getLocalSyncPort(); + Options& setLocalSyncPort(std::string l); + u_int16_t getRtpStartPort(); + Options& setRtpStartPort(u_int16_t l); + u_int16_t getRtpEndPort(); + Options& setRtpEndPort(u_int16_t l); + ConnectToList getConnectTo(); + +private: + Options(); + ~Options(); + Options(const Options &l); + void operator=(const Options &l); + bool sanityCheck(); + + static Options* inst; + static ::Mutex instMutex; + class instanceCleaner { + public: ~instanceCleaner() { + if(Options::inst != 0) + delete Options::inst; + } + }; + friend class instanceCleaner; + + ::Mutex mutex; + + std::string progname_; + bool chroot_; + bool nat_; + bool no_nat_once_; + std::string username_; + std::string chroot_dir_; + std::string pid_file_; + bool daemonize_; + std::string local_sync_addr_; + std::string local_sync_port_; + std::string local_addr_; + u_int16_t rtp_start_port_; + u_int16_t rtp_end_port_; + ConnectToList connect_to_; + Host control_interface_; +}; + +extern Options& gOpt; + +#endif diff --git a/src/anyrtpproxy/portWindow.cpp b/src/anyrtpproxy/portWindow.cpp new file mode 100644 index 0000000..99dafd7 --- /dev/null +++ b/src/anyrtpproxy/portWindow.cpp @@ -0,0 +1,86 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "portWindow.h" + +PortWindow::PortWindow(u_int16_t start, u_int16_t end) : start_port_(start), end_port_(end) +{ +} + +PortWindow::~PortWindow() +{ +} + +PortWindow::PortSet::size_type PortWindow::getLength() +{ + Lock lock(mutex_); + return ports_.size(); +} + +bool PortWindow::hasPort(u_int16_t port) +{ + Lock lock(mutex_); + + PortSet::const_iterator it=ports_.find(port); + if(it == ports_.end()) + return false; + return true; +} + +bool PortWindow::freePort(u_int16_t port) +{ + Lock lock(mutex_); + + PortSet::iterator it=ports_.find(port); + if(it == ports_.end()) + return false; + ports_.erase(it); + return true; +} + +u_int16_t PortWindow::newPort() +{ + Lock lock(mutex_); + u_int16_t port= start_port_; + while (port=end_port_) + return 0; + ports_.insert(port); + return port; +} + +void PortWindow::clear() +{ + Lock lock(mutex_); + ports_.clear(); +} + diff --git a/src/anyrtpproxy/portWindow.h b/src/anyrtpproxy/portWindow.h new file mode 100644 index 0000000..f3bdffb --- /dev/null +++ b/src/anyrtpproxy/portWindow.h @@ -0,0 +1,64 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _PORT_WINDOW_H_ +#define _PORT_WINDOW_H_ + +#include +#include "../threadUtils.hpp" +#include "../datatypes.h" + +class PortWindow +{ +public: + typedef std::set PortSet; + + PortWindow(u_int16_t,u_int16_t); + ~PortWindow(); + + PortSet::size_type getLength(); + bool hasPort(u_int16_t); + bool freePort(u_int16_t); + u_int16_t newPort(); + void clear(); + + +private: + u_int16_t start_port_; + u_int16_t end_port_; + ::Mutex mutex_; + PortSet ports_; + + PortWindow(const PortWindow &s); + void operator=(const PortWindow &s); +}; + +#endif diff --git a/src/anyrtpproxy/rtpSession.cpp b/src/anyrtpproxy/rtpSession.cpp new file mode 100644 index 0000000..a3551e3 --- /dev/null +++ b/src/anyrtpproxy/rtpSession.cpp @@ -0,0 +1,154 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "rtpSession.h" + +#include "callIdQueue.h" + +RtpSession::RtpSession(const std::string& call_id) : in_sync_(false), call_id_(call_id) , dead_(false), complete_(false), + seen1_(false), seen2_(false) +{ +} + +void RtpSession::reinit() +{ + gCallIdQueue.push(call_id_); +} + +bool RtpSession::isDead() +{ + Lock lock(mutex_); + return (dead_ && in_sync_); +} + +bool RtpSession::isDead(bool d) +{ + Lock Lock(mutex_); + return dead_ = d; +} + +bool RtpSession::isComplete() +{ + Lock lock(mutex_); + return complete_; +} + +bool RtpSession::isComplete(bool c) +{ + Lock lock(mutex_); + return complete_ = c; +} + +bool RtpSession::getSeen1() +{ + Lock lock(mutex_); + return seen1_; +} + +RtpSession& RtpSession::setSeen1() +{ + Lock lock(mutex_); + //in_sync_ = false; + seen1_ = true; + return *this; +} + +bool RtpSession::getSeen2() +{ + Lock lock(mutex_); + return seen2_; +} + +RtpSession& RtpSession::setSeen2() +{ + Lock lock(mutex_); + //in_sync_ = false; + seen2_ = true; + return *this; +} + +RtpSession::proto::endpoint RtpSession::getLocalEnd1() +{ + Lock lock(mutex_); + return local_end1_; +} + +RtpSession& RtpSession::setLocalEnd1(RtpSession::proto::endpoint e) +{ + Lock lock(mutex_); + in_sync_ = false; + local_end1_ = e; + return *this; +} + +RtpSession::proto::endpoint RtpSession::getLocalEnd2() +{ + Lock lock(mutex_); + return local_end2_; +} + +RtpSession& RtpSession::setLocalEnd2(RtpSession::proto::endpoint e) +{ + Lock lock(mutex_); + in_sync_ = false; + local_end2_ = e; + return *this; +} + +RtpSession::proto::endpoint RtpSession::getRemoteEnd1() +{ + Lock lock(mutex_); + return remote_end1_; +} + +RtpSession& RtpSession::setRemoteEnd1(RtpSession::proto::endpoint e) +{ + Lock lock(mutex_); + in_sync_ = false; + remote_end1_ = e; + return *this; +} + +RtpSession::proto::endpoint RtpSession::getRemoteEnd2() +{ + Lock lock(mutex_); + return remote_end2_; +} + +RtpSession& RtpSession::setRemoteEnd2(RtpSession::proto::endpoint e) +{ + Lock lock(mutex_); + in_sync_ = false; + remote_end2_ = e; + return *this; +} + + diff --git a/src/anyrtpproxy/rtpSession.h b/src/anyrtpproxy/rtpSession.h new file mode 100644 index 0000000..3716c9b --- /dev/null +++ b/src/anyrtpproxy/rtpSession.h @@ -0,0 +1,133 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _RTPSESSION_H_ +#define _RTPSESSION_H_ + +#include + +#include "../threadUtils.hpp" + +#include +#include + +class RtpSession +{ +public: + typedef boost::asio::ip::udp proto; + + RtpSession(const std::string& call_id); + + bool isDead(); + bool isDead(bool d); + + bool isComplete(); + bool isComplete(bool c); + + proto::endpoint getLocalEnd1(); + RtpSession& setLocalEnd1(proto::endpoint e); + proto::endpoint getLocalEnd2(); + RtpSession& setLocalEnd2(proto::endpoint e); + + proto::endpoint getRemoteEnd1(); + RtpSession& setRemoteEnd1(proto::endpoint e); + proto::endpoint getRemoteEnd2(); + RtpSession& setRemoteEnd2(proto::endpoint e); + + RtpSession& setSeen1(); + bool getSeen1(); + + RtpSession& setSeen2(); + bool getSeen2(); + +private: + RtpSession(const RtpSession & src); + + void reinit(); + + //TODO: check if this is ok + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + Lock lock(mutex_); + + // address of local_end1 and local_end2 are always equal + std::string local_addr(local_end1_.address().to_string()); + u_int16_t local_port1 = local_end1_.port(); + u_int16_t local_port2 = local_end2_.port(); + + std::string remote_addr1(remote_end1_.address().to_string()); + u_int16_t remote_port1 = remote_end1_.port(); + std::string remote_addr2(remote_end2_.address().to_string()); + u_int16_t remote_port2 = remote_end2_.port(); + + ar & dead_; + ar & complete_; + ar & local_addr; + ar & local_port1; + ar & local_port2; + ar & remote_addr1; + ar & remote_port1; + ar & remote_addr2; + ar & remote_port2; + ar & seen1_; + ar & seen2_; + + proto::endpoint local_end1(boost::asio::ip::address::from_string(local_addr), local_port1); + local_end1_ = local_end1; + proto::endpoint local_end2(boost::asio::ip::address::from_string(local_addr), local_port2); + local_end2_ = local_end2; + + proto::endpoint remote_end1(boost::asio::ip::address::from_string(remote_addr1), remote_port1); + remote_end1_ = remote_end1; + proto::endpoint remote_end2(boost::asio::ip::address::from_string(remote_addr2), remote_port2); + remote_end2_ = remote_end2; + + if(complete_ && !dead_) + reinit(); + + in_sync_ = true; + } + + bool in_sync_; + ::Mutex mutex_; + + const std::string& call_id_; + bool dead_; + bool complete_; + proto::endpoint local_end1_, local_end2_; + proto::endpoint remote_end1_, remote_end2_; + bool seen1_,seen2_; //has at least 1 packet been recieved? +}; + + +#endif diff --git a/src/anyrtpproxy/rtpSessionTable.cpp b/src/anyrtpproxy/rtpSessionTable.cpp new file mode 100644 index 0000000..9237866 --- /dev/null +++ b/src/anyrtpproxy/rtpSessionTable.cpp @@ -0,0 +1,123 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ +#include "../threadUtils.hpp" +#include "../datatypes.h" + +#include "rtpSessionTable.h" + +RtpSessionTable* RtpSessionTable::inst = NULL; +Mutex RtpSessionTable::instMutex; +RtpSessionTable& gRtpSessionTable = RtpSessionTable::instance(); + + +RtpSessionTable& RtpSessionTable::instance() +{ + Lock lock(instMutex); + static instanceCleaner c; + if(!inst) + inst = new RtpSessionTable(); + + return *inst; +} + +RtpSessionTable::RtpSessionTable() +{ +} + +RtpSessionTable::~RtpSessionTable() +{ +} + +void RtpSessionTable::delSession(const std::string & call_id) +{ + Lock lock(mutex_); + + RtpSessionMap::iterator it = map_.find(call_id); + if(it!=map_.end()) + delete it->second; + + map_.erase(it); +} + +RtpSession& RtpSessionTable::getOrNewSession(const std::string & call_id, bool& is_new) +{ + Lock lock(mutex_); + return getOrNewSessionUnlocked(call_id, is_new); +} + +RtpSession& RtpSessionTable::getOrNewSessionUnlocked(const std::string & call_id, bool& is_new) +{ + is_new = false; + RtpSessionMap::iterator it = map_.find(call_id); + if(it!=map_.end()) + return *(it->second); + + is_new = true; + std::pair ret = map_.insert(RtpSessionMap::value_type(call_id, NULL)); + ret.first->second = new RtpSession(ret.first->first); + return *(ret.first->second); +} + +RtpSession& RtpSessionTable::getSession(const std::string & call_id) +{ + RtpSessionMap::iterator it = map_.find(call_id); + if(it!=map_.end()) + return *(it->second); + + throw std::runtime_error("session not found"); +} + +RtpSessionMap::iterator RtpSessionTable::getBeginUnlocked() +{ + return map_.begin(); +} + +RtpSessionMap::iterator RtpSessionTable::getEndUnlocked() +{ + return map_.end(); +} + +void RtpSessionTable::clear() +{ + Lock lock(mutex_); + map_.clear(); +} + +bool RtpSessionTable::empty() +{ + Lock lock(mutex_); + return map_.empty(); +} + +Mutex& RtpSessionTable::getMutex() +{ + return mutex_; +} diff --git a/src/anyrtpproxy/rtpSessionTable.h b/src/anyrtpproxy/rtpSessionTable.h new file mode 100644 index 0000000..a37318d --- /dev/null +++ b/src/anyrtpproxy/rtpSessionTable.h @@ -0,0 +1,75 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _RTPSESSIONTABLE_H +#define _RTPSESSIONTABLE_H + +#include + +#include "../threadUtils.hpp" +#include "../datatypes.h" +#include "rtpSession.h" +typedef std::map RtpSessionMap; + +class RtpSessionTable +{ +public: + static RtpSessionTable& instance(); + RtpSessionTable(); + ~RtpSessionTable(); + void delSession(const std::string & call_id); + bool empty(); + void clear(); + ::Mutex& getMutex(); + RtpSessionMap::iterator getBeginUnlocked(); + RtpSessionMap::iterator getEndUnlocked(); + RtpSession& getOrNewSession(const std::string & call_id, bool& isnew); + RtpSession& getOrNewSessionUnlocked(const std::string & call_id, bool& isnew); + RtpSession& getSession(const std::string & call_id); + +private: + static ::Mutex instMutex; + static RtpSessionTable* inst; + class instanceCleaner { + public: ~instanceCleaner() { + if(RtpSessionTable::inst != 0) + delete RtpSessionTable::inst; + } + }; + RtpSessionTable(const RtpSessionTable &s); + void operator=(const RtpSessionTable &s); + RtpSessionMap map_; + ::Mutex mutex_; +}; + +extern RtpSessionTable& gRtpSessionTable; + +#endif diff --git a/src/anyrtpproxy/syncRtpCommand.cpp b/src/anyrtpproxy/syncRtpCommand.cpp new file mode 100644 index 0000000..f612c8a --- /dev/null +++ b/src/anyrtpproxy/syncRtpCommand.cpp @@ -0,0 +1,46 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ +#include "syncRtpCommand.h" + +SyncRtpCommand::SyncRtpCommand() +{ +} + +SyncRtpCommand::SyncRtpCommand( const std::string & addr ) +:callid_(addr) +{ +} + + +std::string SyncRtpCommand::getCallId() const +{ + return callid_; +} diff --git a/src/anyrtpproxy/syncRtpCommand.h b/src/anyrtpproxy/syncRtpCommand.h new file mode 100644 index 0000000..282243b --- /dev/null +++ b/src/anyrtpproxy/syncRtpCommand.h @@ -0,0 +1,61 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ +#ifndef _SYNCRTPCOMMAND_H +#define _SYNCRTPCOMMAND_H +#include +#include + +#include "../threadUtils.hpp" +#include "rtpSessionTable.h" + +class SyncRtpCommand +{ +public: + SyncRtpCommand(const std::string & ); + SyncRtpCommand(); + std::string getCallId() const; + +private: + SyncRtpCommand(const SyncRtpCommand &); + std::string callid_; + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + Lock lock(gRtpSessionTable.getMutex()); + ar & callid_; + bool is_new; + ar & gRtpSessionTable.getOrNewSessionUnlocked(callid_, is_new); + }; +}; + + +#endif // _SYNCCOMMAND_H diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp new file mode 100644 index 0000000..72e4902 --- /dev/null +++ b/src/anytun-config.cpp @@ -0,0 +1,141 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include "datatypes.h" + +#include "log.h" +#include "buffer.h" +#include "keyDerivation.h" +#include "keyDerivationFactory.h" +#include "options.h" +#include "connectionList.h" +#include "routingTable.h" +#include "networkAddress.h" +#include "packetSource.h" +#include "resolver.h" + +#include "syncQueue.h" +#include "syncCommand.h" + + + +void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & cl, u_int16_t seqSize, SyncQueue & queue, mux_t mux, Semaphore& sem) +{ + SeqWindow * seq = new SeqWindow(seqSize); + seq_nr_t seq_nr_ = 0; + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf()); + kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); + kd->setRole(gOpt.getRole()); + cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; + ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end); + cl.addConnection(connparam, mux); + + std::ostringstream sout; + boost::archive::text_oarchive oa(sout); + const SyncCommand scom(cl, mux); + + oa << scom; + std::cout << std::setw(5) << std::setfill('0') << sout.str().size()<< ' ' << sout.str() << std::endl; + + NetworkList routes = gOpt.getRoutes(); + NetworkList::const_iterator rit; + for(rit = routes.begin(); rit != routes.end(); ++rit) + { + NetworkAddress addr(rit->net_addr.c_str()); + NetworkPrefix prefix(addr, rit->prefix_length); + + gRoutingTable.addRoute(prefix, mux); + + std::ostringstream sout2; + boost::archive::text_oarchive oa2(sout2); + const SyncCommand scom2(prefix); + + oa2 << scom2; + std::cout << std::setw(5) << std::setfill('0') << sout2.str().size()<< ' ' << sout2.str() << std::endl; + } + sem.up(); +} + +void createConnectionError(const std::exception& e, Semaphore& sem, int& ret) +{ + cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error: " << e.what(); + ret = -1; + sem.up(); +} + +int main(int argc, char* argv[]) +{ + try + { + bool result = gOpt.parse(argc, argv); + if(!result) { + gOpt.printUsage(); + exit(0); + } + StringList targets = gOpt.getLogTargets(); + if(targets.empty()) { + cLog.addTarget("stderr:2"); + } + else { + StringList::const_iterator it; + for(it = targets.begin();it != targets.end(); ++it) + cLog.addTarget(*it); + } + } + catch(syntax_error& e) + { + std::cerr << e << std::endl; + gOpt.printUsage(); + exit(-1); + } + + gOpt.parse_post(); // print warnings + + gResolver.init(); + + ConnectionList cl; + SyncQueue queue; + + Semaphore sem; + int ret = 0; + UDPPacketSource::proto::endpoint endpoint; + // allow emtpy endpoint!!! + gResolver.resolveUdp(gOpt.getRemoteAddr(), gOpt.getRemotePort(), + boost::bind(createConnection, _1, boost::ref(cl), gOpt.getSeqWindowSize(), boost::ref(queue), gOpt.getMux(), boost::ref(sem)), + boost::bind(createConnectionError, _1, boost::ref(sem), boost::ref(ret)), + gOpt.getResolvAddrType()); + sem.down(); + return ret; +} + diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp new file mode 100644 index 0000000..f32ec83 --- /dev/null +++ b/src/anytun-controld.cpp @@ -0,0 +1,156 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "datatypes.h" + +#include "log.h" +#include "signalController.h" +#include "options.h" +#include "resolver.h" + +#include "syncServer.h" +#include "daemon.hpp" + +void syncOnConnect(SyncTcpConnection * connptr) +{ + std::ifstream file(gOpt.getFileName().c_str()); + if(file.is_open()) { + std::string line; + while (!file.eof()) { + getline (file,line); + connptr->Send(line); + } + file.close(); + } +} + +void syncListener() +{ + boost::asio::io_service io_service; + try + { + SyncServer server(gOpt.getBindToAddr(), gOpt.getBindToPort(), boost::bind(syncOnConnect, _1)); + server.run(); + } + catch(std::runtime_error& e) { + cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what(); + } + catch(std::exception& e) { + cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what(); + } +} + +int main(int argc, char* argv[]) +{ + bool daemonized=false; + try + { + try + { + bool result = gOpt.parse(argc, argv); + if(!result) { + gOpt.printUsage(); + exit(0); + } + StringList targets = gOpt.getLogTargets(); + if(targets.empty()) { + cLog.addTarget("syslog:3,anytun-controld,daemon"); + } + else { + StringList::const_iterator it; + for(it = targets.begin();it != targets.end(); ++it) + cLog.addTarget(*it); + } + } + catch(syntax_error& e) + { + std::cerr << e << std::endl; + gOpt.printUsage(); + exit(-1); + } + + cLog.msg(Log::PRIO_NOTICE) << "anytun-controld started..."; + gOpt.parse_post(); // print warnings + + + std::ifstream file( gOpt.getFileName().c_str() ); + if( file.is_open() ) + file.close(); + else { + std::cout << "ERROR: unable to open file!" << std::endl; + exit(-1); + } + + PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname()); + if(gOpt.getDaemonize()) { + daemonize(); + daemonized = true; + } + + gSignalController.init(); + gResolver.init(); + + if(gOpt.getChrootDir() != "") + do_chroot(gOpt.getChrootDir()); + + privs.drop(); + + boost::thread * syncListenerThread; + syncListenerThread = new boost::thread(boost::bind(syncListener)); + + int ret = gSignalController.run(); + + return ret; + } + catch(std::runtime_error& e) + { + if(daemonized) + cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what(); + else + std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl; + } + catch(std::exception& e) + { + if(daemonized) + cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what(); + else + std::cout << "uncaught exception, exiting: " << e.what() << std::endl; + } +} + diff --git a/src/anytun-showtables.cpp b/src/anytun-showtables.cpp new file mode 100644 index 0000000..5d061d6 --- /dev/null +++ b/src/anytun-showtables.cpp @@ -0,0 +1,136 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "datatypes.h" + +#include "log.h" +#include "buffer.h" +#include "keyDerivation.h" +#include "seqWindow.h" +#include "connectionList.h" +#include "routingTable.h" +#include "networkAddress.h" +#include "syncCommand.h" + +#include +#include +#include + +#include +#include + + +void output() +{ + ConnectionList &cl(gConnectionList); + if( !cl.empty() ) + { + ConnectionMap::iterator it = cl.getBeginUnlocked(); + mux_t mux = it->first; + ConnectionParam &conn( it->second ); + std::cout << "Client " << mux << ": " ; + if( conn.remote_end_==PacketSourceEndpoint()) + { + std::cout<< "not registered"; + } else { + std::cout<< conn.remote_end_; + } + std::cout << std::endl; + //std::cout << "Connection: Keyderivation-Type: " << conn.kd_.printType() << std::endl; + cl.clear(); + } else { + network_address_type_t types[] = {ipv4,ipv6,ethernet}; + for (int types_idx=0; types_idx<3; types_idx++) + { + network_address_type_t type = types[types_idx]; + if( !gRoutingTable.empty(type) ) + { + RoutingMap::iterator it = gRoutingTable.getBeginUnlocked(type); + NetworkPrefix pref( it->first ); + std::cout << "Route: " << pref.toString() << "/" << (int)pref.getNetworkPrefixLength() << " -> "; + mux_t mux = it->second; + std::cout << mux << std::endl; + gRoutingTable.clear(type); + } + } + } +} + +void readExactly(size_t toread, std::iostream & result) +{ + size_t hasread = 0; + while (toread > hasread && std::cin.good()) + { + char a[1]; + std::cin.read(a,1); + result.write(a,1); + hasread++; + } +} + +void readAndProcessOne() +{ + size_t message_lenght ; + std::stringstream message_lenght_stream; + readExactly(5,message_lenght_stream); + message_lenght_stream >> message_lenght; + std::stringstream void_stream; + readExactly(1,void_stream); //skip space + if (!message_lenght) + return; + std::stringstream sync_command_stream; + readExactly(message_lenght, sync_command_stream); + //std::cout << message_lenght << std::endl; + //std::cout << sync_command_stream.str()<< std::endl; + boost::archive::text_iarchive ia(sync_command_stream); + SyncCommand scom(gConnectionList); + ia >> scom; +} + +int main(int argc, char* argv[]) +{ + int ret = 0; + + while( std::cin.good() ) + { + try + { + readAndProcessOne(); + } + catch(std::exception& e) + { + std::cout << "uncaught exception, exiting: " << e.what() << std::endl; + } + output(); + } + return ret; +} + diff --git a/src/anytun.cpp b/src/anytun.cpp new file mode 100644 index 0000000..34fd5f5 --- /dev/null +++ b/src/anytun.cpp @@ -0,0 +1,527 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + + +#include +#include // for ENOMEM + +#include "datatypes.h" + +#include "log.h" +#include "resolver.h" +#include "buffer.h" +#include "plainPacket.h" +#include "encryptedPacket.h" +#include "cipher.h" +#include "keyDerivation.h" +#include "authAlgo.h" +#include "cipherFactory.h" +#include "authAlgoFactory.h" +#include "keyDerivationFactory.h" +#include "signalController.h" +#ifdef WIN_SERVICE +#include "win32/winService.h" +#endif +#include "packetSource.h" +#include "tunDevice.h" +#include "options.h" +#include "seqWindow.h" +#include "connectionList.h" +#ifndef NO_ROUTING +#include "routingTable.h" +#include "networkAddress.h" +#endif + + +#ifndef ANYTUN_NOSYNC +#include "syncQueue.h" +#include "syncCommand.h" +#include "syncServer.h" +#include "syncClient.h" +#include "syncOnConnect.hpp" +#endif + +#define MAX_PACKET_LENGTH 1600 + +#include "cryptinit.hpp" +#include "daemon.hpp" +#include "sysexec.hpp" + +bool disableRouting = false; + +void createConnection(const PacketSourceEndpoint& remote_end, window_size_t seqSize, mux_t mux) +{ + SeqWindow* seq = new SeqWindow(seqSize); + seq_nr_t seq_nr_=0; + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf()); + kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); + kd->setRole(gOpt.getRole()); + cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; + + ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end); + gConnectionList.addConnection(connparam,mux); +#ifndef ANYTUN_NOSYNC + SyncCommand sc (gConnectionList,mux); + gSyncQueue.push(sc); +#endif +} + +void createConnectionError(const std::exception& e) +{ + gSignalController.inject(SIGERROR, e.what()); +} + +#ifndef ANYTUN_NOSYNC +void syncConnector(const OptionHost& connto) +{ + SyncClient sc(connto.addr, connto.port); + sc.run(); +} + +void syncListener() +{ + try + { + SyncServer server(gOpt.getLocalSyncAddr(), gOpt.getLocalSyncPort(), boost::bind(syncOnConnect, _1)); + gSyncQueue.setSyncServerPtr(&server); + server.run(); + } + catch(std::runtime_error& e) { + cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what(); + } + catch(std::exception& e) { + cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what(); + } +} +#endif + +void sender(TunDevice* dev, PacketSource* src) +{ + if(!dev || !src) { + cLog.msg(Log::PRIO_ERROR) << "sender thread died because either dev or src pointer is null"; + return; + } + + try + { + std::auto_ptr c(CipherFactory::create(gOpt.getCipher(), KD_OUTBOUND)); + std::auto_ptr a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_OUTBOUND) ); + + PlainPacket plain_packet(MAX_PACKET_LENGTH); + EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength()); + + u_int16_t mux = gOpt.getMux(); + PacketSourceEndpoint emptyEndpoint; + while(1) { + plain_packet.setLength(MAX_PACKET_LENGTH); + encrypted_packet.withAuthTag(false); + encrypted_packet.setLength(MAX_PACKET_LENGTH); + + // read packet from device + int len = dev->read(plain_packet.getPayload(), plain_packet.getPayloadLength()); + if(len < 0) + continue; // silently ignore device read errors, this is probably no good idea... + + if(static_cast(len) < PlainPacket::getHeaderLength()) + continue; // ignore short packets + plain_packet.setPayloadLength(len); + // set payload type + if(dev->getType() == TYPE_TUN) + plain_packet.setPayloadType(PAYLOAD_TYPE_TUN); + else if(dev->getType() == TYPE_TAP) + plain_packet.setPayloadType(PAYLOAD_TYPE_TAP); + else + plain_packet.setPayloadType(0); + + if(gConnectionList.empty()) + continue; + //std::cout << "got Packet for plain "< "<second; + + if(conn.remote_end_ == emptyEndpoint) { + //cLog.msg(Log::PRIO_INFO) << "no remote address set"; + continue; + } + + // encrypt packet + c->encrypt(conn.kd_, plain_packet, encrypted_packet, conn.seq_nr_, gOpt.getSenderId(), mux); + + encrypted_packet.setHeader(conn.seq_nr_, gOpt.getSenderId(), mux); + conn.seq_nr_++; + + // add authentication tag + a->generate(conn.kd_, encrypted_packet); + + try { + src->send(encrypted_packet.getBuf(), encrypted_packet.getLength(), conn.remote_end_); + } catch (std::exception& /*e*/) { + //TODO: do something here + //cLog.msg(Log::PRIO_ERROR) << "could not send data: " << e.what(); + } + } + } + catch(std::runtime_error& e) { + cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught runtime_error: " << e.what(); + } + catch(std::exception& e) { + cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught exception: " << e.what(); + } +} + +void receiver(TunDevice* dev, PacketSource* src) +{ + if(!dev || !src) { + cLog.msg(Log::PRIO_ERROR) << "receiver thread died because either dev or src pointer is null"; + return; + } + + try + { + std::auto_ptr c(CipherFactory::create(gOpt.getCipher(), KD_INBOUND)); + std::auto_ptr a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND)); + + EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength()); + PlainPacket plain_packet(MAX_PACKET_LENGTH); + + while(1) { + PacketSourceEndpoint remote_end; + + plain_packet.setLength(MAX_PACKET_LENGTH); + encrypted_packet.withAuthTag(false); + encrypted_packet.setLength(MAX_PACKET_LENGTH); + + // read packet from socket + int len; + try { + len = src->recv(encrypted_packet.getBuf(), encrypted_packet.getLength(), remote_end); + } catch (std::exception& /*e*/) { + //TODO: do something here + //cLog.msg(Log::PRIO_ERROR) << "could not recive packet "<< e.what(); + continue; + } + if(len < 0) + continue; // silently ignore socket recv errors, this is probably no good idea... + + if(static_cast(len) < EncryptedPacket::getHeaderLength()) + continue; // ignore short packets + encrypted_packet.setLength(len); + + mux_t mux = encrypted_packet.getMux(); + // autodetect peer + if( gConnectionList.empty() && gOpt.getRemoteAddr() == "") { + cLog.msg(Log::PRIO_NOTICE) << "autodetected remote host " << remote_end; + createConnection(remote_end, gOpt.getSeqWindowSize(),mux); + } + + ConnectionMap::iterator cit = gConnectionList.getConnection(mux); + if (cit == gConnectionList.getEnd()) + continue; + ConnectionParam & conn = cit->second; + + // check whether auth tag is ok or not + if(!a->checkTag(conn.kd_, encrypted_packet)) { + cLog.msg(Log::PRIO_NOTICE) << "wrong Authentication Tag!" << std::endl; + continue; + } + + // Replay Protection + if(conn.seq_window_.checkAndAdd(encrypted_packet.getSenderId(), encrypted_packet.getSeqNr())) { + cLog.msg(Log::PRIO_NOTICE) << "Replay attack from " << conn.remote_end_ + << " seq:"<< encrypted_packet.getSeqNr() << " sid: "<< encrypted_packet.getSenderId(); + continue; + } + + //Allow dynamic IP changes + //TODO: add command line option to turn this off + if (remote_end != conn.remote_end_) { + cLog.msg(Log::PRIO_NOTICE) << "connection "<< mux << " autodetected remote host ip changed " << remote_end; + conn.remote_end_=remote_end; +#ifndef ANYTUN_NOSYNC + SyncCommand sc (gConnectionList,mux); + gSyncQueue.push(sc); +#endif + } + // ignore zero length packets + if(encrypted_packet.getPayloadLength() <= PlainPacket::getHeaderLength()) + continue; + + // decrypt packet + c->decrypt(conn.kd_, encrypted_packet, plain_packet); + + // check payload_type + if((dev->getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 && + plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) || + (dev->getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP)) + continue; + + // write it on the device + dev->write(plain_packet.getPayload(), plain_packet.getLength()); + } + } + catch(std::runtime_error& e) { + cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught runtime_error: " << e.what(); + } + catch(std::exception& e) { + cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught exception: " << e.what(); + } +} + +#ifndef NO_DAEMON +void startSendRecvThreads(PrivInfo& privs, TunDevice* dev, PacketSource* src) +#else +void startSendRecvThreads(TunDevice* dev, PacketSource* src) +#endif +{ + src->waitUntilReady(); + +#ifndef NO_DAEMON + if(gOpt.getChrootDir() != "") { + try { + do_chroot(gOpt.getChrootDir()); + } + catch(const std::runtime_error& e) { + cLog.msg(Log::PRIO_WARNING) << "ignroing chroot error: " << e.what(); + } + } +#ifndef NO_PRIVDROP + privs.drop(); +#endif +#endif + + boost::thread(boost::bind(sender, dev, src)); + boost::thread(boost::bind(receiver, dev, src)); +} + + + +#ifdef WIN_SERVICE +int main(int argc, char* argv[]) +{ + try { + if(argc > 1) { + if(std::string(argv[1]) == "install") { + WinService::install(); + return 0; + } + else if(std::string(argv[1]) == "uninstall") { + WinService::uninstall(); + return 0; + } + } + WinService::start(); + return 0; + } + catch(std::runtime_error& e) + { + std::cout << "caught runtime error, exiting: " << e.what() << std::endl; + } + catch(std::exception& e) + { + std::cout << "caught exception, exiting: " << e.what() << std::endl; + } +} + +int real_main(int argc, char* argv[]) +#else +int main(int argc, char* argv[]) +#endif +{ +#ifdef WIN_SERVICE + bool daemonized=true; +#else + bool daemonized=false; +#endif + try + { + try + { + bool result = gOpt.parse(argc, argv); + if(!result) { + gOpt.printUsage(); + exit(0); + } + StringList targets = gOpt.getLogTargets(); + if(targets.empty()) { +#ifndef _MSC_VER + cLog.addTarget("syslog:3,anytun,daemon"); +#else + #ifdef WIN_SERVICE + cLog.addTarget("eventlog:3,anytun"); + #else + cLog.addTarget("stdout:3"); + #endif +#endif + } + else { + StringList::const_iterator it; + for(it = targets.begin();it != targets.end(); ++it) + cLog.addTarget(*it); + } + } + catch(syntax_error& e) + { + std::cerr << e << std::endl; + gOpt.printUsage(); + exit(-1); + } + + cLog.msg(Log::PRIO_NOTICE) << "anytun started..."; + gOpt.parse_post(); // print warnings + + // daemonizing has to done before any thread gets started +#ifndef NO_DAEMON +#ifndef NO_PRIVDROP + PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname()); +#endif + if(gOpt.getDaemonize()) { + daemonize(); + daemonized = true; + } +#endif + + // this has to be called before the first thread is started + gSignalController.init(); + gResolver.init(); + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +// this must be called before any other libgcrypt call + if(!initLibGCrypt()) + return -1; +#endif +#endif + + OptionNetwork net = gOpt.getIfconfigParam(); + TunDevice dev(gOpt.getDevName(), gOpt.getDevType(), net.net_addr, net.prefix_length); + cLog.msg(Log::PRIO_NOTICE) << "dev opened - name '" << dev.getActualName() << "', node '" << dev.getActualNode() << "'"; + cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << dev.getTypeString() << "'"; +#ifndef NO_EXEC + if(gOpt.getPostUpScript() != "") { + cLog.msg(Log::PRIO_NOTICE) << "executing post-up script '" << gOpt.getPostUpScript() << "'"; + execScript(gOpt.getPostUpScript(), dev.getActualName(), dev.getActualNode()); + } +#endif + + PacketSource* src = new UDPPacketSource(gOpt.getLocalAddr(), gOpt.getLocalPort()); + + if(gOpt.getRemoteAddr() != "") + gResolver.resolveUdp(gOpt.getRemoteAddr(), gOpt.getRemotePort(), boost::bind(createConnection, _1, gOpt.getSeqWindowSize(), gOpt.getMux()), boost::bind(createConnectionError, _1), gOpt.getResolvAddrType()); + + HostList connect_to = gOpt.getRemoteSyncHosts(); +#ifndef NO_ROUTING + NetworkList routes = gOpt.getRoutes(); + NetworkList::const_iterator rit; + for(rit = routes.begin(); rit != routes.end(); ++rit) { + NetworkAddress addr( rit->net_addr ); + NetworkPrefix prefix( addr, static_cast(rit->prefix_length)); + gRoutingTable.addRoute( prefix, gOpt.getMux() ); + } + if (connect_to.begin() == connect_to.end() || gOpt.getDevType()!="tun") { + cLog.msg(Log::PRIO_NOTICE) << "No sync/control host defined or not a tun device. Disabling multi connection support (routing)"; + disableRouting=true; + } +#endif + +#ifndef ANYTUN_NOSYNC + boost::thread* syncListenerThread = NULL; + if(gOpt.getLocalSyncPort() != "") + syncListenerThread = new boost::thread(boost::bind(syncListener)); + + boost::thread_group connectThreads; + for(HostList::const_iterator it = connect_to.begin() ;it != connect_to.end(); ++it) + connectThreads.create_thread(boost::bind(syncConnector, *it)); +#endif + + // wait for packet source to finish in a seperate thread in order + // to be still able to process signals while waiting +#ifndef NO_DAEMON + boost::thread(boost::bind(startSendRecvThreads, privs, &dev, src)); +#else + boost::thread(boost::bind(startSendRecvThreads, &dev, src)); +#endif + +#if defined(WIN_SERVICE) + int ret = 0; + gWinService.waitForStop(); +#else + int ret = gSignalController.run(); +#endif + +// TODO: stop all threads and cleanup +// +// if(src) +// delete src; +// if(connTo) +// delete connTo; + +#if defined(WIN_SERVICE) + gWinService.stop(); +#endif + return ret; + } + catch(std::runtime_error& e) + { + cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what(); + if(!daemonized) + std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl; + } + catch(std::exception& e) + { + cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what(); + if(!daemonized) + std::cout << "uncaught exception, exiting: " << e.what() << std::endl; + } +#if defined(WIN_SERVICE) + gWinService.stop(); +#endif + return -1; +} + + diff --git a/src/anytun.sln b/src/anytun.sln new file mode 100644 index 0000000..b562246 --- /dev/null +++ b/src/anytun.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "anytun", "anytun.vcproj", "{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Service Debug|Win32 = Service Debug|Win32 + Service Release|Win32 = Service Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.ActiveCfg = Debug|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.Build.0 = Debug|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.ActiveCfg = Release|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.Build.0 = Release|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.ActiveCfg = Service Debug|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.Build.0 = Service Debug|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.ActiveCfg = Service Release|Win32 + {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.Build.0 = Service Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/anytun.suo b/src/anytun.suo new file mode 100644 index 0000000000000000000000000000000000000000..a2b304d8a2b922c65596727e86f2dd3ce45ab451 GIT binary patch literal 68608 zcmeI52b>+nm9HfsLA6)J)IlPS4d~cHjHGJ@8l6{daYp3a3tm?tACkuWkJH zEe~$x zXWIh%a!s%nSR1Sh)&c8-^}q&TL$DE```c{_HU^u3%|LgsIoJYh3AO^;f!?47>;$$4 zJAfTQ7tk5>1YJQl&;#@XeZUB?GuRaj0K0)+U@+Jp3RH`oV^1hrsaFbW(D#)7TE7_b-E4;%`{fkVInV0SPc90g{9gTN#(8O#BTKs`7N zOaO<2BfybhDwqgnfN5YMmtoH~~1u&LCV2rh{XF+-ZbM!EB(( z*`Ia9j|VHkiQr^#5;z4c0jGk~!I@wZrLAwbyj=~gw3u*dri}|#$`)9RdKGP`Om3ci z@W?Uue7*e|Bs%??Jmo|**3$y}p?waq(OId>a%p;P3%pRSJ^#1q)s{bLze=uuNxM4A zv7EZsU?nps%M5xzt~Ke>u0wnK+_7K@T1)Ts_Q3I_OhMB!dj9}=dKo1+n19uq_+@#r z7XR&re(fZ+L5m3s7djA6`n91VKHysMv*TYs;P}@McugOW(rBl@2bUMP;`nzwIUcnQ zeL->jn@4B3{-7&(1vu7|59mqUG`mFT_`ee98ytt<0*?Pw7RR^a|7B1M9RFV1gV3?* znD+Bag!+JV--w9o2js3I)Gv$$`hamjf8+Q+3poBA+m2<^r}1xGKccTNt`Bhh8&Bh3 zzhQql{-=W(!0WRJX9LIXyx<(`UOR?R|DeC{^U-vmKIS5zAJ9s*6X#z2$8jKye|?8O z!11pi&<8mF^&6*yoyI+VRmVrZHR_4yKQ-jvpS$`YsMQi}`Qym@Bek&qIkEg=%&a}8 zPFz|)cj=5pHDl&4tXo#obLEghJ5N1u{;Z|-%j)MWuQ_D?vK2EH)=XZ$V)p#{nxVb> zOg&`e)cGH`{@%X>7}ahM<_A5`3H0L%!m0G>Qs$VcTvaMx>zH3`^S_6nWeV0*k9E!D z-<8Z{`k&+QN3$|(EYDj1r$5;kV479=KmC6y_hHPK3mHi>(6)eo^|}+7rIw?=o>r*F z|Cyh<6{4+*x~E5~QRtgVd(RDje<)>GPFd!`x2D@HYT7XWtjT?@mz3uEN6_|llwkpF zP){2;Czq9@C;Ii}`sZrv--)#PRHeCo=U@B1+8*dZ|63nNakcu_BCTasn(H5v)p<5n zSWmBL|9ZrhMg8hsmn7BdS9gyXxGn2H0n2nm=yh8b^f%aEwfgnpDaYpe52U_}(CRwu z&}fT#ym?DDuv^rBBQmU3{|2OWtyvVu@VQ`Q=7;iC(OgO~gVNNnBA!n>I3lL9KGHL| zYFh^8V4pS2c&=Vnka{7XCc~{@Hgg2mumbPRj6Ic{>&eTyEoKEjm6>%EtG%gsnpxRr z$K67%&*5{vHvOL~i}iChtxjya=JIj4=6RKU?!@fXzJ0#8O6k6N&wx#S_u+3plJ5rT z8fj-x$cuMhwpmP^J5?U(cQ0Ydi$Xp9nfyWuWz&P zAM13TaLGrX`O9lBe15cg4rur8X5C-EziZchAN$46PT6VZq5-n(pKDyFm#uz^>z>}3 zw^%|6-7~s!>&7X8tCs~>kR@M$#psXv@L%7|^Jx7ot)6DKJM1-Q4%g7Vv4bW2m!D%y z90`1HWNZb*`z2>SiakGhU3EU&4{M@7H!{!Ayop1tB z+>4mbyd6u5-cn9~;~vELWf7{+S+vMm<|lw_u@~Z+>xdV@PT-~BHY2#B9>{_;M|A)7ARv2+ydf`fyKc&9*-gJx~M)leadmfEz^m?dCx7ueK9!u z<3Zx)@o<6r67jv@z8sw8dz!fUyimnN^oBP261(LGdSDmHR6`<-QaA$-w>Zj z_`3r4N8;{N{~TNm@o^FV8)5Dv)Hpq}+zG64j==*s*XO>c(Z?T>?Vw3oBCP*c+y7Yh zGb7KDScWGc%d#~@9V?yYr6^I(CC)!qTYqu>Nj}bba0z8`<>hRcdqUfyTs(iVO&veg z`rl1R`}xTBV7!D{XRuzX1F1autlQG6udz&RY5!vV$Kt1EXSx?t=Y^DJ45e9^F-z%{ z*2Mkat|Zc4tF3=g{{*~+>ps1um|JN1Q7}teDS-X&*@kUet$xo({<349ar4=u+J4XP z*57n+nU#&rYV~hQ`ks+NI_FF0f0OaJ+Ms(-Tc))hXp8;pQ{4k8W7|A`X|;0;v*s1I zzcJbzZH=P1@|4pG%A$HBtXoBy!DAt$yv`lE}DBzb)OG zwB`KAvd)f-%k=kcO*z-Czw4aNpxXNPChc+;cgWoANyAJ$a9v?6zjfO-*Lbygj@qCd z*8@1NU2Ckq{msa%e;&{17NWntp!dBW-hGj|CcUn16j!6_9S^1fWj<)nTGSb{F55A! zEaY_41K0k*RNhq-eSw_*K|4@Vt;Q11Yn4B1G@Uk}uTc5`IoEZmZz}oEO8bPO|4QS} z@!yvFEAJdep7+?f6s$>&J4Z<^wQD{{bkm(fnf+xhi95AhxqJ{5_| z^gBzmChAwO>;7u>yY)QPCPB*d56qL4{@a%EuT51m{w-%~lIpKLS6lx*Nqbmi+_>xA z;Py?1N=C!P_58`4oL<|}qv*lpoP!)aimO1meZX!&Nh8L4(}>ZkQc068TO@I761Q|- z+Y(Fx9f42M|CQDsY0uvK`k%U_ z%5pVKqAyWX<&{rf@~Lgmzl^it#oRXu-*6#Y+e{o*qh*Z=xZcVYQ@ zWRv~wbg9MT&!o)FCt{w~Ey%cO@F%p%f6gYq{FHrhR^R;8=fw8=J!Tz~9XdhU zd)l+1D@esvV=a(#Mp}LQai3|87BhEE`k43U&&_P3#*uvDxAvT8*-}l6EBakaJqEZ2 zQ1W$XI-7T9nO(@~%_FvP%8i`7*OBLlG=2m)tPSNa+HYn37Jt;YZp|j+ycU-CN}xOr za(1@{{i|dD+SXiZ>UsApEGmER#a*u!o7UuK@3-+BwKZ?WGzOgUc5Udt)zM!Ze{I=+ zxZ<(jJ&T-`)xuNcG%oTHJbmr)f4B6xl^V+>?Yy+^;h=2(>znP<;>H#N_y2kVZL4`p zwQx&jf8USu=Q92MviYN>Tyoy?kFAOB2ddS-gtV_Xr66Vc`&M`Um90OV@v7B-Eon2; zYDIs)Y`sRJ60!ZAm7U?L)o;IN4ua6xR)3(KXcM-h-2NbOx&XO@g7Yj>uc#afOs6<& z+pYSAbnj8by?0uHn;D#KkkZW$Zc%}=pS*WPfm<2eX$9^x!ChY9t_tq@;M_qU36#4) zD)ZgME%Uv>*#`Fm^*&nQo(%5U0`~&(d=!lf)-}Ze;1F&o>2=K|$okXu_?e-xjSRQLSDXRIf1=BgL-?9Ul&UOa&rd|+RTp6Rt7T|g(W zFt{xUcLd5}VEKx2EFbdnReGPM=zlBCU)7brm`n3rsQvQupZ_8&QuDH<`C|{R4$V^J zZ?c-sHO9`t)e_3--BMlU@_MCRZ+?p3^f^^^7+rZZ5q5jpKgn^df$TvuS7m0FP3qtg1Ry7K$h&K&;BXY8~V|L28kWzDX} zqV(j0oTW`IY$@di0Ov1d2#^~EQtzbE?KS=mgOR#Tm$56xod%P1CX=qHv;7=KyDlGGEiOta@Ok`KzSX=c?$3bP<{mD z+&}*qDE|iJ?9I1<@;*rUeULHj+WjNA?u7pg&cpD$XRF(bwB3KW-#NC)J2H(nd&TS_ zoh^_hE{ZKF*Dc_+U4Wdm*cB-DjGR5*7btszlrHTr_X%!G!djq=1g5J6T9I-Ekkbm% zD)zdJ^UdRY*Ol)=R=nKRDK*+Kf8(aOGir?I`=?QqwGX{Kij%4#tmt}SK_huGKZMu_ z*wOTMFD!X9Yq=4`#}FS0--lTLY!0yO*Q*k_8RWgEhfTh*Y;9ZVIeB&Cw^IMF+Z)Vd7B{3fUgP+9 z=H*i#-@C})e@t&(eDu+tSs5$8n~^^!H0|2icrCu0QH^bst$+Jx-YAu{a_IWg*0W{v zR;rw?$ZBoB45D1W{aY^TcVyOrYV|)t+6UI;AEaD=|2$F2zwSTOo1`RZ!==rMJr*`l zu76;|JuOArqTkW*L_>zI1#6--JqR^Z{o_u-?HZivb_=d=aQnjb3vOs|o#FNfZl3~I z8{FvN9K&ORJD|WF7~JIGoav?ncX)8x#Sy_x4{iY5jNs-3Hw50gR!Rf0{igc$1r#+k=+}Xj^z?~D^1;II|To~MC!MTRJJh*FuQ^&Qz-4vX&_|3uH z9-RGgM{xHB*9Gpr;2sLjwt6_YCxg?!e<`?UgR_sG%eXU$oe4e-d@g@B;W@xn|GD5i za6Y&IxJEIJtN+h}OTeYzGO#&jvj#c3J~55>Bk?it&UAkM9N{hCE8wQ!?jXE1;-%o76@Kx~5`1~5-x50OS>#8@vcft37_y2(Khu}@{qu_o*_!jsn_&4x2_!;PK*HRLy&C#q;CV&Y#j+{IA!%_)w@ZXpq6gP@R3BXb9ncKp!r*CUA8n=jth? zJAil%aQ2p42TTUaR3N8EISMG#fLvcN9VoMaTt~1FY!4Ozxt+iqpezS+%8ESTy~CW_ zkZ>iioM#5NH{tO>ajbancEB;CI9}wu*D>QY$Bo=t!11#MxE#oB3>;s|)j-ZRy9Ow? z06E*qv7_7r;UU-TQ}($!$1s+Oe_*MB?(5Rqlflx1|xJ zCerOsymN571m|_%6;yT$&NBB7u5W?sAKakex{_{ia6^MLpFM)xGdT0xJGhYrPQR!e z5S;dZU~mTqr~Mxi+>ya~&(z?K3eG+{I=H&v#=xa_EEWZ~Eu8N+Dl3BPK>T>(2NJFf zZU^GN`>31}+(yLDCT_jY39di!^c?l#;H>YZ#FguVvwv?0?(X15!rdF(^TADmdm*^5 z1vehfcO;eX1~-BD_kw$y5SNy@Gw7PBOV=O}P2@vf5^H>Exv((S*1rzS&bH9j<@Du= z`$2F&E^ykq>Ha;qtqJb~%CA5auibmZEzPfkQ-{9Wdy}op{V_Q0+k0*A-vFf}M9NQF zH@~%l^WJrdo8Kk{Zj0b{C~#eZ>k-`M+_N@uCE366UU2%z-6Nek`Vm*hzydcUxV;LT z^N;C96*%9$l}om6eiMQ_tdLH-HeIq|)A#0Qy0h@xMtQ}Te|5SH=;rCT$Ra`$+ zcmEQ~o}StH{4Ralt??9V_PM`sDbO(XjVoP&HR%VmUu8ES=eo)HKp6<+js&)XvImem z80-m@T98`H&uRYdLHunA#I>gPnfC`k`3G1$YvGF7byMfpFI&E}ZpI?%PJ1n0v2fuq zqljN%Ek5vWtaMh<$?b;B+3bZ6U)bS*&)+cni&yXPyP>Q1{Sh>*dZ=|WP1|_z-}Fl( zCo>ERU$yPm^dr4cTb^6!GQrr+n|#W&^V zq2!srTzy6*y^c7`vITJDYT=GdIjw$Y;ON~2$bAY_oD}~>zNzuMjjQ9A_MueO`%K4j zTfaSoBG${Rj{nx)-z$2aG{ziXX^c6pY+q~Q8eMTcmd2RZ?5pm;@A($rU$lSIlcSVA zjpsgG^Ir4p3zR)d?f3ZX*_yL~ey;KRm-#yaH!b~XUEBSiZ{eKKruV1wJGG9bl<&CA zhv(mMYxI46*1PgP>zCTVxRUJIxmHF7?{?pg&bRa?0+jNe5_uR@TAgAvb4Jti9YpwkG zJ5O5CtkU!Eehpp*MJJ`6 z$7Oud?mB_vf#)eJL0kM+(f(G|pZwSM$By|P3Ze}9`aAuIJO(U_MQn@zO79=~-NX5e z0^k2@oOyn9*aZc>Y@B>Wbtntp0SveS3<)g4f4x!NI zerlZYtgWq}q}Bd_hW8JP^G9{QFaH*XPcJEN$d!`*K-2TB|MYs2D$^!Cw2lo!Op;R z0|-5%@NB~Kx!r+#dC%xPoA7+jbe>NP0-nuzKH=G%XL5T2ukTGbEaGc*VEzCj;8cY5l#kEz`nr`L<2_&L#x9B2BW!2IM~qsqAkmUHFgT1au;lG_A~ z1&XFGr%VLuJ_yLUjF|>pK}-j7<~;+r&YB72%x^MK{~RD^JzO^wxy|^TRv6B>wuSG? z`TZe3yT7jXdwnA~B62(FGkZPBWd1vV&%RYP3;*Kppw#i%)uz{d$KE&DeFHtMI>%fv z!i7#&Uc)5r@2$h;z*UmGaS!&-yxsW`GUAOdz)&aLg%nAfm0%pLEfghU3=aBa^I{?)&jX*fOe{A*K+pfXrLt9wfwH9Os@{p+1D$8HgGAB z^X%hVpj-!%j_Wg~T{|~#a_(O40OoNQkaO(a4myInf!sRaV4yq-m{ANo_fW&vO6%3C7=&bQoe(U&u2kYW`C7z&ieh`)zyK(df101??f*&oo+(_d41g$;wzD=e-93z1Jil=e?6jQC9xq z`0m=kp1Lb>n}Hse7L+v%C$HSP%7W11zVarOJ&1&aO&oYi%L5^#J0g zs{sRnlIq@*xOG>C0n_Q3_W?>8FLISiCBI|cj|ZRmpI$QxHe~Kf7)K1fEmg;R#JP^24`Cg2a4BC z*B6WditVo+y@%JdE&E294&)qjX++EA^-uQO`Wu$LKgKf}cm36$g;rCR=4Z0yF|x+kZXo5M1V}t13?o^YQ3! zChF1poN$KIPu6pW%KE^bOg+37@vVUVTh0;U{G$hUJs{_3)w8Yvwg)Ml*3g{m4Ce?; zR%{+xmG^6H-n%B~2ej7YskAolGkq;EopI+F#Zj6#J-Ydg42~ePV$1EQk5TDYB=awa zR@&U2%mcz^^HACO$AAW(qqfT8`GZ!vFKFr+DyNs-no3=4#gKCSX;qo0t@N+@T_f0z z)#|Sy?Q>P>*Z-Ca`ZK-iR?1W7SDlG&j)dj)PxDwLt`M|E|DojbT;x@ze_+F^zJlVQ zZ2!FG`M)ivY`pSMqMivT<@&2?|Mre6$9T2v-vQlss~joQKOmcH^K>o!Yx^I-#nc8Z zr7QB+@Zld-)PF$cEsA%p8gEPg`_9uYIuxY%Y%zKF^eY@u#4MewQCBZ=j&=Q;lFkO? zGRI4pW^4VM{!h6Ld)vK-YtMWa*p}}vt@^UyKkjq_dPX5}5e%BUVmvt)kol znTGF2EBc#SE715|Deb_UMp zmF&N@^W#dpsx)@D_}+iLL$;Y7!zA5^sCzMRoub&fW&Y2116q@|_@C#?~Ye^#siF4F3&lrsJ9^jedeHmpDHBvVfglxoj8 zi*Lou!s3@ugT~)V*lELFzc;t$Es(sfGeOboYKi){-kD804w6T-$Gz&zpR7;MDCafT z&&pmv&NTL?G91XcgB}4CcY1Q$1Lr7Ze~?OAd~R!>eCGT|b(C?v`2J7h@9`I3XDaRv z)4JaKlUTOURrw2gTu=A8TeV(FEwJ3y*?K9XftUymET>(L2TGbj z)+L^1kbDd*hcUGtVnxI+i_qFFY{qTO=O;i%@IqW$lki1gAHNiw+OGu4Z-6?~?&{xt zx+_4rtObcUpZJEhoZj-cKp7dFHslkMPJ})cG2Mp1ry%NI9-OUneQ;k0&Mx(dmU%c& z@P9TRIzQOrj|OL19w%;o&jshbFA_K3uLS4ymxZSnt=zB!rv|JwJQ_d}Fr8V!>;=U57RStz>zx$eN3QPJbcInJ~_CE2Ix zl6`8crgQAp0%atSs|BNgatV;rKVAxyt3bN<>Ws09Og$9_wa6|0qhhH-snq$$_$EKn|OS$}A!)y%*B8_r={E<;*>tWNzM3sWP@vikRH znC5*m2Z!y_IgT8amc_s`~jeGJZByt^?OICeUi{Vp@2RjQ z-Odp`E55&3o&HrrCM2m-C*1Kp6z& z)(84qr54CJ%V?j7nzg-m2{8RKU^>g$;9$E|AmS4hD+0 zkkZ+=_J_70=XzKhQIcKULR`C0P5`F64V(y+(}0}zbr#qToCD;hgVTZHJTGVYt^n(S ztALyo)_r+d;bb?%*B`&UBA~+2HBm%`?wluhN2~$~aV-M$VjOXu9Oy$Z5 z%2nO_1kIm^nn(ULc@p_lnipDI%B4pa{;p-qzYA#FR9ZEEoKfGWP~x&*JIPO88h3)# z{gR+oG_JH=Tb>KYaLVK_{kdiEY4betsspWkZ>0G3m*m?f!$5?qDsg}+Q zeM-yH{CryN2Z5$0HG^02|Zk9kE14+lL#2t-q z1*eXm0%y4Y2yPDH;}QQugj!{q6Xfz4ML(I()aKs-SXcA39TI0-$ff$5?ug)yB24L~ z2Ul0%>@)9OP~a8^cWi-M9^CQ4Szg<5OJEzSqcgY&bOfnAO?NqP4!Q!E&Uvc`P(BCb zwgWo?MJ}(uzeQEa&sR6nS{uiA)IRW>`qW<(?MqJk>mC=h3%Q;^dr?JH#|@LpwE9>mE= zrSsS7+OPO-&U=eC=wh}>N2ti&WRv?8u-)uu+f2^B?^SyKJfPv36iHhU_rLpa%@)e7 zqJ@M7`ViDFjG~t9e+OiJSGci4v@QGpsp$6IaHUNDz-(=pr)%low&?#gnWdASa{Yr_ zQrp1W{#vbVuQXgJiFnHToNg!+Z9I(&eWQNPi?zT;a!%04EBZINEx>4?=-=eDF~^1J z^+$60t`)#Bsh^Q^9eX`c^d)lMa|2Lr1adooF97qn2gvEq?gaXmZ=)0pzq%$A&Tj$n^mufie!r>0kAR$|N9X|4s&qV?@p|cQ{beJYt#BJTjZO z>CB@JD2stye^3t;`#{cdd&j9&1Cuxt_?;l%=J4%}bHHbSZ*|C@Pj~^iFh2Wchi`QF^x;y%%Yyff zjw``c;A(IU@a+!Y>hOu&=fDl%M&KJBH-lTit>8BBd2l%^A1>!!v z`y#j>JOI4*5TS2<_%zQad5-~~;ynR;^TRY>CVUD!4W0?^Il||GPl`LAiV*+_C3Py1D_`O`Axzffggjnfb+gjm3*4?HuxF% zckpxY4)BT6e}H$vFTt(@t?i~1*!MDJRy{=Lxs zSY%tK->-PKCh9+kM6N)p)qfEB538#FLt9hNlg`zD|8gd}d(!txS^fJr?3?nmmHt(~ zD;ayL+WNZ_`F&(orr*CY+?t?2)2nW!we()MRrP^Nx&E{U$kSH(w=McdlhMq`tW3YZ z+tHe&{&$s9ZT-Jb+D*d#^88&>OKbsLbMFA|0&=duoh@Deq&4?O#2*B%KOX|7+Y~se zO#dWE+?RuUF1W1-zXUb}&w-@l`QW}5oHP0(U=8p}aO!oPt1j2L-n%up5Gbz!In$j7 zl*E}X?Fqg^Ja4UI+Pwa+{>(O=**$T|8Wuh)p<$BlL{h13Wmlv2yxb_z11ODS%q#Yl zDRXg^Zi{(k6X3{^ODkGAPcB^H4+Ey#94zLp)_*H(T~ZFGrF_@%I98)0dFD75Zg0xh z*5?KLlTSL)-teHOGk;{Miqe@6avOs#z(h@3q4ArD6S;N_P?iJl(<`q4$_XHikRoS` zYqNSW?@>ozAeUNnGvci}%emij)8uuqXjJ5Xvtx_3Bn?{#!1Zr|X>6*$jbOs8$9 zbd!TSq`(~>+|&X$Ex4J%Ifk?m^#8be|t&x&Es5f0^FZssD2HpR5TXW%>tK+5YzM5un=opN9TF zs63M$Bh)7H9DJ@(?NiV>*l_db#l1Ki@;9mcn?Cu7^)IbW%|3Z%(~ElbW^LUYzuEXK zbrEU(``^dIt@>MKm%jSa1{O5TCd!kRY>iaRd3&4DAJ79^kGe55Z> z>VWAiL-IxS!MPe(0?ar01k1M+IEO3)-fKNh2FfWwZfkG`P|gH$*6A#uoDJkG%eg>t zohIkHaV1bL1}WV=8I%77E;;o+0Bp|(ft=-g2-u#F06Eutj|2040?1ik=OfcU3ljHS za9;^d9WMv>YH-&5OTe|~H-l5hw}AN;*OZs>S$Q3(!@m41P!eZbrE&IM;%TH-w??h> zyA$b`B}Y{le~n|x-#1#!SYDZpK7ZS?`R_lJ`JevPJ^xv4|EI6=OhhTyukDme+W(9s zS!&htJMz8PR#oWt$DUdf^*f921*+9QpR~V@jLYgjpt|#i)o%ay&^^5h{r$7Gb|h>e zu>J$MHXKx2|KE_-k))K>e_(a>Z$FNF^pw@=zm2q;0Hs`iRsFx(?SDUdAIh}1roUgL zYB{j|M{{{BsJ8y<_Dok<^^K*KDgm$1+C9iaS|0@GaHJGj_7-`X5BM&#siR`VX$I{_T$>pM{`W{a-@A&mfd?{q}0P*#7EG zQl2`$`YgJC6bW}COndRU@D^)3FfYotgwVV_KWjc$_y$Dz`Cqlq=zIOLZjc2ErA9Nc zbaGm%epB(>MQ%5c-9)%YaPA58Fvkjq@$|NASJD3cV!+_ina5zwo z26C2Z8c?)4IrFFk%3>hr9-8JFr z{v!+iZUGxKhmyy*4Y=N{Io`83P}0c z!n))+!EHvEcFgmL=QUo$+m)_J^V64fCdB2CRKorEoV27qwzR2_)3~jLOXGGSaZA$+ z*gwh&Ag3K22NcJzoZ=W(&H!@Tfir<}0g&4kTnuW!XMvpK`;rLlS29s((yHn1spEMtf?ya6|zc-~fcK$3fh?*`=Ds&AI&DeUD7f%0YGUFQE3P@V;H z%5&Mj_)CbCZa5MB@|fWC%lmi{85^AKFfO?91#V(+2M0HpbcY6aWN;h9IXl%7Ix~6M z{Elir8;|3fXZ271itq0=|1L{!t;dnVYpLO7dbg zklo{gR&6@RowJ>y#memo^b|@Omt%>`E49FMa>IdAzW%T;%B3yqkFzPn%aLuletmJd zxc)neB-*!9o;tt!9rQaQm2&;b|L18d{i}XG$XrmZ{%@lHTR%?VfH8YIh*t4Hu6H!l#lU$~ zITXk_Po*`EH_N#m&6X2{jtV*FTxWG9t%Lg!KQUt(zjvZPzcRRM3B7lFa9wcs652%Z zu^}*>^TT*h3tUMg?jYg^gGs?TkGkq`em^2OJ*#UsCDp^#N2-S-+x*rA^MGP|y>(^(rurjAjz|r=^xx+bCq(*IrOi#|JxY-`VOUBzjj(K zZP9-T`o9p_mh10duAHm3zt%ksRNMZSqyM@!^Q`lG9_IsO3*Vc_Q?~T)v0PXmECuG_ z7+VfpZyyKb)&uoGNj|_`#Yw>H=SJu_KCv0sgU@L#eN9|b$N3RYocG=UTn*hA*GzXa zs0FtGb-AX#9w?s&a=U@sfpQO!Q?EWpc?hJ|ZR$S;m7clf-_e@F^YEpt5Q^Wm-r<9N zeqzpQDoPsn)<)0dD%_HoZX@9OZxi6!FL7y==9rT6`kp{Zd$FyE56hVRDR8>C{P%xb zI>R0^_|H0{Oq=aF2K+=c;L$9|KuPd5OafV`X|!wpg+UqM1Fc zLAWbOIvfGofL$c#=yc9d$37tG7(rY;o{pt-V}eWjb!WYCz;J(HI?L>AYd8VOS)WM} zP7codrUGs6sNl4Mqk;9&XL+ynnF%c493W@iox2Q=0dn5!Y;3v(K+ZBO268KboYtt9 zv2Le)BSOpUNr-lHOmLRPckAR91!v#PiFkd4Q0E3IuZ&RJzCPlgi%>t%1@JNZK98X`v<^`GZcn+#&eNrT%YToect(@QoBsXd-VNWh zw~eL&+jKgxT(-vyVEObfa@I-zWZmav_$1z6E1tW0CeEI7<_`xGWMwc+(wm6ovfR5z zykCTt(YP`Yn65Jz1eB9Oy7!cfX|zG}8{|dAXH7ioEW zPqh4f=)NCILu*f?=8^jlP`;+~tkCtu!t71>rK|_iDd7z6ZOc<*-*#;NmPO+`&M9|C zUZwXVRz1^g{Oy;;K_^PNlQw1 zba1l@>1GFaOmLmKXF+gFg4-4D*x*hGt_$3W!JQVI^*uefbAt2q_A|j<7@VX1qTnts zq`M-xYYXYF3+~q7tnY2XeIYpOdslGx7t%ct+@pnbj|KNsaF*}s;9dyM^1T?`*9+-h z3GTH*x^D;f{or=u-X8?_li(b$Zw2@BLb`W?`&A*`d%?XQoVM{naDNHTKKg5L9|mV1 zeH7f9Yvg@yx=zHE^@20q`oV1y+|F>D2Depk{o%F_ZpYv(OHFXygX;s=Be>mytAXnk z+<@S^zzqy;kKnYIJ%bw_oZfRpaQg;lJ;nw%J~+!fA-E~QS>}U-J1V#uxTAxc72Gax zvx7S((?8Xi~8$HavZ2u|DQ;^m@+8k`iJI; zO8#xj`H$Z8y~wj%|KJkM`6cUby_2+h0|`Dt|J{+$zS|po-1ms{b7WV+m7e-nH%Fyk zv`I6bBX%sS?dH$-T3eqKf3>@DcDBQZF;}l{ZmCqZly0W{#H7+Mfq3T#@Za@aiDBp( zUu8|p>~Cmw=dbM-qwiRt4HC2}{!;NPk*Zw3^GCU~W&GWZDfpyXDc7G?-+9_f|2qDb zaA6s!w*D8P`@O34>(|SrE%on8`=1)KKw13$JIZTowk;CY2ouD`nZX9oEk2CCKX`N+#vwf`s6|DLT(p$tm-{=53$gM9Ry53{ka zS-YFq(ae$G0lA`lz=zaU9f^+wrg5L{N=w-v$hlwd0+a)RoGYc2{{-SGFQN@+V&?k~ zFc$n1c;C99hR7a-oeAaK5AQ`dEIw~c+%ua_gy}7nbRDYQA(75 zL+E$>_&+QE@kA_hI#)5>32<8xo*3z@`)7#j@y-oyQ{v|nceQvyaF**r;#~>#BmAG8 zbDT$HE#emkXFYBuuCBX++k*Hb#MSk9a5oYs+O7uN1C)D#oM%?I0^CJ*)+uMcw>0Bw z`1}k|o&~0>0nY>F1t8~+@?l_pF9SKt^bja=#s2*o*HZsFuPOTg@7)NLze`^E`Aft4 z;^L`)CyOjE!z4Y4q_Vl%_UzHMNaEZjDfU(J5U!!TZXHuO4-IZRLj8lX6qwGwUj`J< zZsc|Vrvl|%AZJ^g2b4>Ioc4G*Q0@bAmgS2;`7)533Z4SW>p)JsO=CxHOz@5gS8qxh zXPt?U&zQzvw4BE0Nx|uJSNEOsPxfy#N5NJjuubLy`%0+;a-+Z;pd16_Y>NdzSqc)D z`tiiz?EjO1awagHWBAiRN&VQL_@x<>zxiM~xvPS^j!;h9x<0r&f*VeFXK+strZFP5 zI{lYtkxr1cbazJ9Ae|O#fqE;gE_o}h$kSp=dkP`{XWtcEXaw;a#zsx|X(EFNed|kZ zTX2REM2~0G(dEgya!qiiyMg%bgq|vU*%5LRkzRy12d9U-g?JA_Js$sOdi8pafG-AT z8SeBV@<4FgGC!1kXCi%LrsZ!#;k_cy4je>uJybTocF#Q z>An}-rf_c(*Gu@VNiS~!-XU^4;V**IGrvt-YyM?$>iq$6#TBPf)BTo+*8P6Acl2pl z^LP83{z`xHn3lQeE@n>{Me8v4n}GJJi~w@C0Oxqc`B={0Iw0cqYCoW)b8dZu8Wj$!Pyu4M|@I* z&dED9<4kuboN`25bN%Amy~_09wj(|xxVqrBhx7TBlDyOa;y&k+_BocJZIISxi5mlV zoEMSgrSu%92B&8-+8LY`-1)(Efpg8JTpFCGL6-%WJd(DjM^f}IMjdruh`8QC&JnA} zG%lC>Yb~{LZgpLujVp%$(>ksW1;@ZN= zp!j#)%6|L2hP0J_tGKnZnDmXi#=jM}HaT4!rxX9T{MBe%s?s+qt2?)<)NcBPok98c zPAh+xPybQrIZ}0{Y3WH%^5I&P{a&B_DnQx(cW8qL&TgsrkLM5i&Xu6J2C0}h$YCAw zH?RCyu76-zHrX}LU(}nV)f-6gDfH{lm2&-hnsQP9Qj+N3Ekk+g{Hjl~b^uDbemzOK zwB`I~G`hR!3^M7$zYEsL<4Xv=;A-{Q;EoSYkFheiQ-agN(@D}WD z#8s4iw+XP`8kqekw+l$N?3j{sEw_8A{SC=>l_V<>?ccSMYnRk&CCRf(e?tA*76B=< z{~_7_B2U-SziIrt&Z}1caCAHODdqZ8o8@UM{o9uDw?6s@R8{}#{NH>EX5E!aWo*uU z1Ks+oT(pxtfCX|qj|9pnAm_?z7%<&_Ku%k`9jpmljmm8aJ`XyAyMWvV;6R{!2gtd? z)|V)6fND#f-B9r#b1jOaSx(PpjTG0fa(bu!Kp6xYpAS88eOnskZVI_EHIrjuPvygy-#1_sfE)1mU0XNk|$ZX)fa&3IxCpJ=Q*acOzwg8 z@WVjLqZ@H$G)U=^hu;@2w*ynGDr;wNaQoJuCr)#jmk-U}zV}yY_oNq2!9!2ts=w$n z152uFlA<^LI5xZD8<$Jl)o`9YKTEr;psJpnwZOUx*Im2VcJ_OvXXdT#xytuC^>7ZjR`wP{FVr{FWavZxHUL}2DzPB-loTAXKdT?*>-LZ9KT0J zI4wBCNkEwiOxGXG0*dw{=V~$8>*C-nOS0W$o9b}fc~9cB^}B)g^$_ryw(~HMdj!a7 zJFf!g#BTyQSJI~g<%b}p`vYnCB{=W>8*#b67dU^nz&XO-`+{y)1Jb)08^PJj*1*++ zzimH*@t6N*asE9&*E^NoXiWZsEVAeGDetTJtXvJ`oI5T8rn?cy*}fM7x$^ZxQ$L)1 z*gg0B(J4F2%P@())BGLFo}?-Lf!ste04R=eIpyQ7fAW=m<)?++$-lMzb0uF}X`hh) zqN6j>wxBJ4dA7B4aeM0HoaPu0iUlfhQcx zxobI3V;g@xGhaVD)+;@WYHh8a+iLNBURQtriWS@uHED0OXn$(sK1hR+%O?)H41Q{{fWYpXq9-Pyy@ z62HZCcZ9$hYNnyYqnS*Ofpy4anUBP6x`_ zK<+kh4p1%ta?^oxnUdx=&ojJ#J>Wg2a}K@}tO4!?a;^dH19EB4=)I2z_X1%`_agDx z;FaL6BfKf%uSV!v#`9J0k;~`y^w;eN!mQd3wWaU>l-YOkkRScyjrGYo(`uN+893G4 zotIuqf0MXg#5-X-tA78qaUWLPo%Le$dycT29`@UZv$5nS3S2>P6 zD%nSC{(IJee)jfHr#z(k&YD?ZtOWkx9OJjdW@^1TIG2><= zoodw(cSck6$him2KDPLeeno$x_uUP+lk5xR^m}R7;Z90U5ATj~5Eu;-=gHi3Fd;bm zVmg z*JRyR0MlEhmDHl_{n3`cD}MiyAE-Rb$uLPbBIf=y=pLkdU%6Ys&cXEy&X4Z#6kF7E zJAlDJsReSIf#E>0_2sN-%ho%FR`oBw)iX}~J8j9{Y=`oFQu$l=+FJRpxALjEecKja z>!`_V;;#Yumxv})r?kUptd}kH-}7st2cxNcr`X(krnYxHRQiR5*1TVOk9iU`UqPSx z7yRlO4U1@x#nig76|{*;zX?&D*LPO;?>?Dp?p3wPo~2`?xF6FWl<$O#>k&uST(r6C z)JFH`bNY*dlgVkfs`RF|9m5@!?5nz(FUf4o(X>3Xuk^&Jv1NOZfBDZeoFz`B`XX^l_dsx- zo>@EPVUW^2M%;8y1lNbqS}LjZUVjD{J_o#a7Ypy3{3Y9kh7P50c^QzqE_>Rt4>^7OUE6GODgW+caWv-f=FjfZSUi%v#xtWdUpZDc7K{6?#-8X* zo^AKTtDY{n9;j5tviIMHHhjB{n_CdyzdN35CxA3&TS(eKui2sT-G*}gt{KavE$`p? z?rj&Kl34nul$zjnBi`8?ke!2bJ-$nDdk3eV+mE>U9Uh!I{1(WGgfoMi zLws0@N9b(gti#9b8z9z@XfqjCI>%SPy46Q5`S#SGo4p!~;`}GK4REeh()znI@icGA zRW7A>l**s@!eC!A9l#>K4~|m9>qR)2Avm1a02XY6i1*^SdKBBHe#C|n_UCgy9NAE= zd)FA4Q+P$DsZ;R?!GpniHi{>=vB6xnHWqL+a+Tk4QTPn-s5&zJvoTDjg->h^a zvbyx*T7P0*@5g^5!SF10iY@ZL&yUh9;y$!|SMW(ZKWc5~(9%;g$IE)4EvFi-?a0h~ z12Ce(oZ4D>({3WQs-7pEs;~avh-mq_n0xMj&DrgAa%#)-oXWdo=c4j6iKe^r{{sdU B;8Xwr literal 0 HcmV?d00001 diff --git a/src/anytun.vcproj b/src/anytun.vcproj new file mode 100644 index 0000000..ea6a923 --- /dev/null +++ b/src/anytun.vcproj @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/anytunError.cpp b/src/anytunError.cpp new file mode 100644 index 0000000..1a530a7 --- /dev/null +++ b/src/anytunError.cpp @@ -0,0 +1,53 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "anytunError.h" + +#include +#include + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +std::ostream& operator<<(std::ostream& stream, AnytunGpgError const& value) +{ + char buf[STERROR_TEXT_MAX]; + buf[0] = 0; + gpg_strerror_r(value.err_, buf, STERROR_TEXT_MAX); + return stream << buf; +} +#endif +#endif + +std::ostream& operator<<(std::ostream& stream, AnytunErrno const& value) +{ + boost::system::system_error err(boost::system::error_code(value.err_, boost::system::get_system_category())); + return stream << err.what(); +} diff --git a/src/anytunError.h b/src/anytunError.h new file mode 100644 index 0000000..26b4012 --- /dev/null +++ b/src/anytunError.h @@ -0,0 +1,83 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _ANYTUN_ERROR_H +#define _ANYTUN_ERROR_H + +#include +#include +#include "datatypes.h" + +#define STERROR_TEXT_MAX 200 + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +#include + +class AnytunGpgError +{ +public: + AnytunGpgError(gcry_error_t e) : err_(e) {}; + gcry_error_t err_; +}; +std::ostream& operator<<(std::ostream& stream, AnytunGpgError const& value); +#endif +#endif + +class AnytunErrno +{ +public: + AnytunErrno(system_error_t e) : err_(e) {}; + system_error_t err_; +}; +std::ostream& operator<<(std::ostream& stream, AnytunErrno const& value); + +class ErrorStringBuilder +{ +public: + ErrorStringBuilder(ErrorStringBuilder const& src) { stream << src.stream.str(); }; + ErrorStringBuilder() {}; + ~ErrorStringBuilder() { throw std::runtime_error(stream.str()); }; + + template + std::ostream& operator<<(T const& value) { return stream << value; } + +private: + std::stringstream stream; +}; + +class AnytunError +{ +public: + static ErrorStringBuilder throwErr() { return ErrorStringBuilder(); } +}; + +#endif diff --git a/src/authAlgo.cpp b/src/authAlgo.cpp new file mode 100644 index 0000000..49974ee --- /dev/null +++ b/src/authAlgo.cpp @@ -0,0 +1,167 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "authAlgo.h" +#include "log.h" +#include "anytunError.h" +#include "buffer.h" +#include "encryptedPacket.h" + +#include +#include + +//****** NullAuthAlgo ****** +void NullAuthAlgo::generate(KeyDerivation& kd, EncryptedPacket& packet) +{ +} + +bool NullAuthAlgo::checkTag(KeyDerivation& kd, EncryptedPacket& packet) +{ + return true; +} + +#ifndef NO_CRYPT +//****** Sha1AuthAlgo ****** + +Sha1AuthAlgo::Sha1AuthAlgo(kd_dir_t d) : AuthAlgo(d), key_(DIGEST_LENGTH) +{ +#ifndef USE_SSL_CRYPTO + gcry_error_t err = gcry_md_open(&handle_, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::Sha1AuthAlgo: Failed to open message digest algo"; + return; + } +#else + HMAC_CTX_init(&ctx_); + HMAC_Init_ex(&ctx_, NULL, 0, EVP_sha1(), NULL); +#endif +} + +Sha1AuthAlgo::~Sha1AuthAlgo() +{ +#ifndef USE_SSL_CRYPTO + if(handle_) + gcry_md_close(handle_); +#else + HMAC_CTX_cleanup(&ctx_); +#endif +} + +void Sha1AuthAlgo::generate(KeyDerivation& kd, EncryptedPacket& packet) +{ +#ifndef USE_SSL_CRYPTO + if(!handle_) + return; +#endif + + packet.addAuthTag(); + if(!packet.getAuthTagLength()) + return; + + kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_); +#ifndef USE_SSL_CRYPTO + gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength()); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << AnytunGpgError(err); + return; + } + + gcry_md_reset(handle_); + gcry_md_write(handle_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength()); + gcry_md_final(handle_); + u_int8_t* hmac = gcry_md_read(handle_, 0); +#else + HMAC_Init_ex(&ctx_, key_.getBuf(), key_.getLength(), EVP_sha1(), NULL); + + u_int8_t hmac[DIGEST_LENGTH]; + HMAC_Update(&ctx_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength()); + HMAC_Final(&ctx_, hmac, NULL); +#endif + + u_int8_t* tag = packet.getAuthTag(); + u_int32_t length = (packet.getAuthTagLength() < DIGEST_LENGTH) ? packet.getAuthTagLength() : DIGEST_LENGTH; + + if(length > DIGEST_LENGTH) + std::memset(tag, 0, packet.getAuthTagLength()); + + std::memcpy(&tag[packet.getAuthTagLength() - length], &hmac[DIGEST_LENGTH - length], length); +} + +bool Sha1AuthAlgo::checkTag(KeyDerivation& kd, EncryptedPacket& packet) +{ +#ifndef USE_SSL_CRYPTO + if(!handle_) + return false; +#endif + + packet.withAuthTag(true); + if(!packet.getAuthTagLength()) + return true; + + kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_); +#ifndef USE_SSL_CRYPTO + gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength()); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << AnytunGpgError(err); + return false; + } + + gcry_md_reset(handle_); + gcry_md_write(handle_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength()); + gcry_md_final(handle_); + u_int8_t* hmac = gcry_md_read(handle_, 0); +#else + HMAC_Init_ex(&ctx_, key_.getBuf(), key_.getLength(), EVP_sha1(), NULL); + + u_int8_t hmac[DIGEST_LENGTH]; + HMAC_Update(&ctx_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength()); + HMAC_Final(&ctx_, hmac, NULL); +#endif + + u_int8_t* tag = packet.getAuthTag(); + u_int32_t length = (packet.getAuthTagLength() < DIGEST_LENGTH) ? packet.getAuthTagLength() : DIGEST_LENGTH; + + if(length > DIGEST_LENGTH) + for(u_int32_t i=0; i < (packet.getAuthTagLength() - DIGEST_LENGTH); ++i) + if(tag[i]) return false; + + int ret = std::memcmp(&tag[packet.getAuthTagLength() - length], &hmac[DIGEST_LENGTH - length], length); + packet.removeAuthTag(); + + if(ret) + return false; + + return true; + +} + +#endif + diff --git a/src/authAlgo.h b/src/authAlgo.h new file mode 100644 index 0000000..c446853 --- /dev/null +++ b/src/authAlgo.h @@ -0,0 +1,108 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _AUTHALGO_H_ +#define _AUTHALGO_H_ + +#include "datatypes.h" +#include "buffer.h" +#include "encryptedPacket.h" + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +#include +#else +#include +#endif +#endif +#include "keyDerivation.h" + +class AuthAlgo +{ +public: + AuthAlgo() : dir_(KD_INBOUND) {}; + AuthAlgo(kd_dir_t d) : dir_(d) {}; + virtual ~AuthAlgo() {}; + + /** + * generate the mac + * @param packet the packet to be authenticated + */ + virtual void generate(KeyDerivation& kd, EncryptedPacket& packet) = 0; + + /** + * check the mac + * @param packet the packet to be authenticated + */ + virtual bool checkTag(KeyDerivation& kd, EncryptedPacket& packet) = 0; + +protected: + kd_dir_t dir_; +}; + +//****** NullAuthAlgo ****** + +class NullAuthAlgo : public AuthAlgo +{ +public: + void generate(KeyDerivation& kd, EncryptedPacket& packet); + bool checkTag(KeyDerivation& kd, EncryptedPacket& packet); + + static const u_int32_t DIGEST_LENGTH = 0; +}; + +#ifndef NO_CRYPT +//****** Sha1AuthAlgo ****** +//* HMAC SHA1 Auth Tag Generator Class + +class Sha1AuthAlgo : public AuthAlgo +{ +public: + Sha1AuthAlgo(kd_dir_t d); + ~Sha1AuthAlgo(); + + void generate(KeyDerivation& kd, EncryptedPacket& packet); + bool checkTag(KeyDerivation& kd, EncryptedPacket& packet); + + static const u_int32_t DIGEST_LENGTH = 20; + +private: +#ifndef USE_SSL_CRYPTO + gcry_md_hd_t handle_; +#else + HMAC_CTX ctx_; +#endif + + Buffer key_; +}; +#endif + +#endif diff --git a/src/authAlgoFactory.cpp b/src/authAlgoFactory.cpp new file mode 100644 index 0000000..c284f34 --- /dev/null +++ b/src/authAlgoFactory.cpp @@ -0,0 +1,62 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include "authAlgoFactory.h" +#include "authAlgo.h" + + +AuthAlgo* AuthAlgoFactory::create(std::string const& type, kd_dir_t dir) +{ + if(type == "null") + return new NullAuthAlgo(); +#ifndef NO_CRYPT + else if(type == "sha1") + return new Sha1AuthAlgo(dir); +#endif + else + throw std::invalid_argument("auth algo not available"); +} + +u_int32_t AuthAlgoFactory::getDigestLength(std::string const& type) +{ + if(type == "null") + return NullAuthAlgo::DIGEST_LENGTH; +#ifndef NO_CRYPT + else if(type == "sha1") + return Sha1AuthAlgo::DIGEST_LENGTH; +#endif + else + throw std::invalid_argument("auth algo not available"); +} + diff --git a/src/authAlgoFactory.h b/src/authAlgoFactory.h new file mode 100644 index 0000000..2dca567 --- /dev/null +++ b/src/authAlgoFactory.h @@ -0,0 +1,53 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _AUTHALGO_FACTORY_H_ +#define _AUTHALGO_FACTORY_H_ + +#include + +#include "datatypes.h" +#include "authAlgo.h" + +class AuthAlgoFactory +{ +public: + static AuthAlgo* create(std::string const& type, kd_dir_t dir); + static u_int32_t getDigestLength(std::string const& type); + +private: + AuthAlgoFactory(); + AuthAlgoFactory(const AuthAlgoFactory& src); + void operator=(const AuthAlgoFactory& src); + ~AuthAlgoFactory(); +}; + +#endif diff --git a/src/bsd/tunDevice.cpp b/src/bsd/tunDevice.cpp new file mode 100644 index 0000000..408434e --- /dev/null +++ b/src/bsd/tunDevice.cpp @@ -0,0 +1,283 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "tunDevice.h" +#include "threadUtils.hpp" +#include "log.h" +#include "anytunError.h" + +#define DEVICE_FILE_MAX 255 + +TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, std::string ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400) +{ + std::string device_file = "/dev/"; + bool dynamic = true; + if(dev_name != "") { + device_file.append(dev_name); + dynamic = false; + } +#if defined(__GNUC__) && defined(__OpenBSD__) + else if(conf_.type_ == TYPE_TUN || conf_.type_ == TYPE_TAP) { + device_file.append("tun"); + actual_name_ = "tun"; + } +#else + else if(conf_.type_ == TYPE_TUN) { + device_file.append("tun"); + actual_name_ = "tun"; + } + else if(conf_.type_ == TYPE_TAP) { + device_file.append("tap"); + actual_name_ = "tap"; + } +#endif + else + AnytunError::throwErr() << "unable to recognize type of device (tun or tap)"; + + u_int32_t dev_id=0; + if(dynamic) { + for(; dev_id <= DEVICE_FILE_MAX; ++dev_id) { + std::ostringstream ds; + ds << device_file; + ds << dev_id; + fd_ = ::open(ds.str().c_str(), O_RDWR); + if(fd_ >= 0) + break; + } + } + else + fd_ = ::open(device_file.c_str(), O_RDWR); + + if(fd_ < 0) { + if(dynamic) + AnytunError::throwErr() << "can't open device file dynamically: no unused node left"; + else + AnytunError::throwErr() << "can't open device file (" << device_file << "): " << AnytunErrno(errno); + } + + if(dynamic) { + std::stringstream s; + s << actual_name_; + s << dev_id; + actual_name_ = s.str(); + } + else + actual_name_ = dev_name; + + actual_node_ = device_file; + + init_post(); + + if(ifcfg_addr != "") + do_ifconfig(); +} + +TunDevice::~TunDevice() +{ + if(fd_ > 0) + ::close(fd_); +} + +#if defined(__GNUC__) && defined(__OpenBSD__) + +void TunDevice::init_post() +{ + with_pi_ = true; + if(conf_.type_ == TYPE_TAP) + with_pi_ = false; + + struct tuninfo ti; + + if (ioctl(fd_, TUNGIFINFO, &ti) < 0) { + ::close(fd_); + AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); + } + + ti.flags |= IFF_MULTICAST; + if(conf_.type_ == TYPE_TUN) + ti.flags &= ~IFF_POINTOPOINT; + + if (ioctl(fd_, TUNSIFINFO, &ti) < 0) { + ::close(fd_); + AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); + } +} + +#elif defined(__GNUC__) && defined(__FreeBSD__) + +void TunDevice::init_post() +{ + with_pi_ = true; + if(conf_.type_ == TYPE_TAP) + with_pi_ = false; + + if(dev->type_ == TYPE_TUN) { + int arg = 0; + if(ioctl(dev->fd_, TUNSLMODE, &arg) < 0) { + ::close(fd_); + AnytunError::throwErr() << "can't disable link-layer mode for interface: " << AnytunErrno(errno); + } + + arg = 1; + if(ioctl(dev->fd_, TUNSIFHEAD, &arg) < 0) { + ::close(fd_); + AnytunError::throwErr() << "can't enable multi-af modefor interface: " << AnytunErrno(errno); + } + + arg = IFF_BROADCAST; + arg |= IFF_MULTICAST; + if(ioctl(dev->fd_, TUNSIFMODE, &arg) < 0) { + ::close(fd_); + AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno); + } + } +} + +#elif defined(__GNUC__) && defined(__NetBSD__) + +void TunDevice::init_post() +{ + with_pi_ = false; + + int arg = IFF_POINTOPOINT|IFF_MULTICAST; + ioctl(fd_, TUNSIFMODE, &arg); + arg = 0; + ioctl(fd_, TUNSLMODE, &arg); +} + +#else + #error This Device works just for OpenBSD, FreeBSD or NetBSD +#endif + +int TunDevice::fix_return(int ret, size_t pi_length) const +{ + if(ret < 0) + return ret; + + return (static_cast(ret) > type_length ? (ret - type_length) : 0); +} + +int TunDevice::read(u_int8_t* buf, u_int32_t len) +{ + if(fd_ < 0) + return -1; + + if(with_pi_) { + struct iovec iov[2]; + u_int32_t type; + + iov[0].iov_base = &type; + iov[0].iov_len = sizeof(type); + iov[1].iov_base = buf; + iov[1].iov_len = len; + return(fix_return(::readv(fd_, iov, 2), sizeof(type))); + } + else + return(::read(fd_, buf, len)); +} + +int TunDevice::write(u_int8_t* buf, u_int32_t len) +{ + if(fd_ < 0) + return -1; + + if(!buf) + return 0; + + if(with_pi_) { + struct iovec iov[2]; + u_int32_t type; + struct ip *hdr = reinterpret_cast(buf); + + type = 0; + if(hdr->ip_v == 4) + type = htonl(AF_INET); + else + type = htonl(AF_INET6); + + iov[0].iov_base = &type; + iov[0].iov_len = sizeof(type); + iov[1].iov_base = buf; + iov[1].iov_len = len; + return(fix_return(::writev(fd_, iov, 2), sizeof(type))); + } + else + return(::write(fd_, buf, len)); +} + +void TunDevice::do_ifconfig() +{ + std::ostringstream command; + command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString() + << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_; + + if(conf_.type_ == TYPE_TUN) + command << " up"; + else { +#if defined(__GNUC__) && defined(__OpenBSD__) + command << " link0"; +#elif defined(__GNUC__) && defined(__FreeBSD__) + command << " up"; +#elif defined(__GNUC__) && defined(__NetBSD__) + command << ""; +#else + #error This Device works just for OpenBSD, FreeBSD or NetBSD +#endif + } + + int result = system(command.str().c_str()); + if(result == -1) + cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig failed" << AnytunErrno(errno); + else { + if(WIFEXITED(result)) + cLog.msg(Log::PRIO_NOTICE) << "ifconfig returned " << WEXITSTATUS(result); + else if(WIFSIGNALED(result)) + cLog.msg(Log::PRIO_NOTICE) << "ifconfig terminated after signal " << WTERMSIG(result); + else + cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig: unkown error"; + } + +} diff --git a/src/buffer.cpp b/src/buffer.cpp new file mode 100644 index 0000000..2597845 --- /dev/null +++ b/src/buffer.cpp @@ -0,0 +1,257 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include "datatypes.h" +#include "buffer.h" + +Buffer::Buffer(bool allow_realloc) : buf_(0), length_(0), real_length_(0), allow_realloc_(allow_realloc) +{ +} + +Buffer::Buffer(u_int32_t length, bool allow_realloc) : length_(length), real_length_(length_ + Buffer::OVER_SIZE_), + allow_realloc_(allow_realloc) +{ + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + throw std::bad_alloc(); + } + std::memset(buf_, 0, real_length_); +} + +Buffer::Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc) : length_(length), real_length_(length + Buffer::OVER_SIZE_), + allow_realloc_(allow_realloc) +{ + if(!data) { + length_ = 0; + real_length_ = 0; + return; + } + + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + throw std::bad_alloc(); + } + std::memcpy(buf_, data, length_); +} + +Buffer::Buffer(std::string hex_data, bool allow_realloc) : length_(static_cast(hex_data.size())/2), + real_length_(length_ + Buffer::OVER_SIZE_), + allow_realloc_(allow_realloc) +{ + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + throw std::bad_alloc(); + } + + for(u_int32_t i=0; i> std::hex >> tmp)) tmp = 0; + buf_[i] = static_cast(tmp); + } +} + +Buffer::~Buffer() +{ + if(buf_) + delete[] buf_; +} + +Buffer::Buffer(const Buffer &src) : length_(src.length_), real_length_(src.real_length_), allow_realloc_(src.allow_realloc_) +{ + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + throw std::bad_alloc(); + } + std::memcpy(buf_, src.buf_, length_); +} + +void Buffer::operator=(const Buffer &src) +{ + if(buf_) + delete[] buf_; + + length_ = src.length_; + real_length_ = src.real_length_; + allow_realloc_ = src.allow_realloc_; + + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + throw std::bad_alloc(); + } + std::memcpy(buf_, src.buf_, length_); +} + +bool Buffer::operator==(const Buffer &cmp) const +{ + if(length_ != cmp.length_) + return false; + + if(!std::memcmp(buf_, cmp.buf_, length_)) + return true; + + return false; +} + +Buffer Buffer::operator^(const Buffer &xor_by) const +{ + u_int32_t res_length = (xor_by.length_ > length_) ? xor_by.length_ : length_; + u_int32_t min_length = (xor_by.length_ < length_) ? xor_by.length_ : length_; + Buffer res(res_length); + + for( u_int32_t index = 0; index < min_length; index++ ) + res[index] = buf_[index] ^ xor_by[index]; + + return res; +} + +u_int32_t Buffer::getLength() const +{ + return length_; +} + +void Buffer::setLength(u_int32_t new_length) +{ + if(new_length == length_) + return; + + if(new_length > real_length_) + { + if(!allow_realloc_) + throw std::out_of_range("buffer::setLength() - reallocation not allowed for this Buffer"); + + u_int8_t* old_buf = buf_; + u_int32_t old_length = length_; + + length_ = new_length; + real_length_ = length_ + Buffer::OVER_SIZE_; + + buf_ = new u_int8_t[real_length_]; + if(!buf_) { + length_ = 0; + real_length_ = 0; + if(old_buf) + delete[] old_buf; + + throw std::bad_alloc(); + } + std::memcpy(buf_, old_buf, old_length); + + if(old_buf) + delete[] old_buf; + + old_buf = &buf_[old_length]; + std::memset(old_buf, 0, real_length_ - old_length); + } + else + length_ = new_length; + + reinit(); +} + + +u_int8_t* Buffer::getBuf() +{ + return buf_; +} + +u_int8_t& Buffer::operator[](u_int32_t index) +{ + if(index >= length_) + throw std::out_of_range("buffer::operator[]"); + + return buf_[index]; +} + +u_int8_t Buffer::operator[](u_int32_t index) const +{ + if(index >= length_) + throw std::out_of_range("buffer::operator[] const"); + + return buf_[index]; +} + +Buffer::operator u_int8_t*() +{ + return buf_; +} + +std::string Buffer::getHexDump() const +{ + std::stringstream ss; + ss << "Length=" << length_ << std::endl << std::hex << std::uppercase; + for( u_int32_t index = 0; index < length_; index++ ) + { + ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]) << " "; + if(!((index+1) % 16)) { + ss << std::endl; + continue; + } + if(!((index+1) % 8)) + ss << " "; + } + return ss.str(); +} + +std::string Buffer::getHexDumpOneLine() const +{ + std::stringstream ss; + ss << length_ << " Bytes,'" << std::hex << std::uppercase; + for( u_int32_t index = 0; index < length_; index++ ) + { + ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]); + } + ss << "'"; + return ss.str(); +} + +bool Buffer::isReallocAllowed() const +{ + return allow_realloc_; +} diff --git a/src/buffer.h b/src/buffer.h new file mode 100644 index 0000000..db19947 --- /dev/null +++ b/src/buffer.h @@ -0,0 +1,77 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _BUFFER_H_ +#define _BUFFER_H_ + +#include "datatypes.h" +#include + +class TunDevice; +class UDPPacketSource; + +class Buffer +{ +public: + Buffer(bool allow_realloc = true); + Buffer(u_int32_t length, bool allow_realloc = true); + Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc = true); + Buffer(std::string hex_data, bool allow_realloc = true); + virtual ~Buffer(); + Buffer(const Buffer &src); + void operator=(const Buffer &src); + bool operator==(const Buffer &cmp) const; + Buffer operator^(const Buffer &xor_by) const; + + u_int32_t getLength() const; + virtual void setLength(u_int32_t new_length); + u_int8_t* getBuf(); + u_int8_t& operator[](u_int32_t index); + u_int8_t operator[](u_int32_t index) const; + std::string getHexDump() const; + std::string getHexDumpOneLine() const; + + bool isReallocAllowed() const; + + operator u_int8_t*(); + +protected: + virtual void reinit() {}; + + u_int8_t *buf_; + u_int32_t length_; + u_int32_t real_length_; + bool allow_realloc_; + + static const u_int32_t OVER_SIZE_ = 100; +}; + +#endif diff --git a/src/cipher.cpp b/src/cipher.cpp new file mode 100644 index 0000000..ddde683 --- /dev/null +++ b/src/cipher.cpp @@ -0,0 +1,190 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "endian.h" + +#include "cipher.h" +#include "log.h" +#include "anytunError.h" + +void Cipher::encrypt(KeyDerivation& kd, PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + u_int32_t len = cipher(kd, in, in.getLength(), out.getPayload(), out.getPayloadLength(), seq_nr, sender_id, mux); + out.setSenderId(sender_id); + out.setSeqNr(seq_nr); + out.setMux(mux); + out.setPayloadLength(len); +} + +void Cipher::decrypt(KeyDerivation& kd, EncryptedPacket & in, PlainPacket & out) +{ + u_int32_t len = decipher(kd, in.getPayload() , in.getPayloadLength(), out, out.getLength(), in.getSeqNr(), in.getSenderId(), in.getMux()); + out.setLength(len); +} + + +//******* NullCipher ******* + +u_int32_t NullCipher::cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + std::memcpy(out, in, (ilen < olen) ? ilen : olen); + return (ilen < olen) ? ilen : olen; +} + +u_int32_t NullCipher::decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + std::memcpy(out, in, (ilen < olen) ? ilen : olen); + return (ilen < olen) ? ilen : olen; +} + +#ifndef NO_CRYPT +//****** AesIcmCipher ****** + +AesIcmCipher::AesIcmCipher(kd_dir_t d) : Cipher(d), key_(u_int32_t(DEFAULT_KEY_LENGTH/8)), salt_(u_int32_t(SALT_LENGTH)) +{ + init(); +} + +AesIcmCipher::AesIcmCipher(kd_dir_t d, u_int16_t key_length) : Cipher(d), key_(u_int32_t(key_length/8)), salt_(u_int32_t(SALT_LENGTH)) +{ + init(key_length); +} + +void AesIcmCipher::init(u_int16_t key_length) +{ +#ifndef USE_SSL_CRYPTO + handle_ = NULL; + int algo; + switch(key_length) { + case 128: algo = GCRY_CIPHER_AES128; break; + case 192: algo = GCRY_CIPHER_AES192; break; + case 256: algo = GCRY_CIPHER_AES256; break; + default: { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher::AesIcmCipher: cipher key length of " << key_length << " Bits is not supported"; + return; + } + } + + gcry_error_t err = gcry_cipher_open(&handle_, algo, GCRY_CIPHER_MODE_CTR, 0); + if( err ) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher::AesIcmCipher: Failed to open cipher" << AnytunGpgError(err); + } +#endif +} + + +AesIcmCipher::~AesIcmCipher() +{ +#ifndef USE_SSL_CRYPTO + if(handle_) + gcry_cipher_close(handle_); +#endif +} + +u_int32_t AesIcmCipher::cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + calc(kd, in, ilen, out, olen, seq_nr, sender_id, mux); + return (ilen < olen) ? ilen : olen; +} + +u_int32_t AesIcmCipher::decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + calc(kd, in, ilen, out, olen, seq_nr, sender_id, mux); + return (ilen < olen) ? ilen : olen; +} + +void AesIcmCipher::calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + kd.generate(dir_, LABEL_SALT, seq_nr, salt_); + + std::memcpy(ctr_.salt_.buf_, salt_.getBuf(), SALT_LENGTH); + ctr_.salt_.zero_ = 0; + ctr_.params_.mux_ ^= MUX_T_HTON(mux); + ctr_.params_.sender_id_ ^= SENDER_ID_T_HTON(sender_id); + ctr_.params_.seq_nr_ ^= SEQ_NR_T_HTON(seq_nr); + + return; +} + +void AesIcmCipher::calc(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ +#ifndef USE_SSL_CRYPTO + if(!handle_) + return; +#endif + + kd.generate(dir_, LABEL_ENC, seq_nr, key_); +#ifdef USE_SSL_CRYPTO + int ret = AES_set_encrypt_key(key_.getBuf(), key_.getLength()*8, &aes_key_); + if(ret) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher ssl key (code: " << ret << ")"; + return; + } +#else + gcry_error_t err = gcry_cipher_setkey(handle_, key_.getBuf(), key_.getLength()); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher key: " << AnytunGpgError(err); + return; + } +#endif + + calcCtr(kd, seq_nr, sender_id, mux); + +#ifndef USE_SSL_CRYPTO + err = gcry_cipher_setctr(handle_, ctr_.buf_, CTR_LENGTH); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: " << AnytunGpgError(err); + return; + } + + err = gcry_cipher_encrypt(handle_, out, olen, in, ilen); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to de/encrypt packet: " << AnytunGpgError(err); + return; + } +#else + if(CTR_LENGTH != AES_BLOCK_SIZE) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits"; + return; + } + unsigned int num = 0; + std::memset(ecount_buf_, 0, AES_BLOCK_SIZE); + AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, &aes_key_, ctr_.buf_, ecount_buf_, &num); +#endif +} +#endif + diff --git a/src/cipher.h b/src/cipher.h new file mode 100644 index 0000000..3d922c0 --- /dev/null +++ b/src/cipher.h @@ -0,0 +1,132 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CIPHER_H_ +#define _CIPHER_H_ + +#include "datatypes.h" +#include "buffer.h" +#include "encryptedPacket.h" +#include "plainPacket.h" +#include "keyDerivation.h" + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +#include +#else +#include +#endif +#endif + +class Cipher +{ +public: + Cipher() : dir_(KD_INBOUND) {}; + Cipher(kd_dir_t d) : dir_(d) {}; + virtual ~Cipher() {}; + + void encrypt(KeyDerivation& kd, PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + void decrypt(KeyDerivation& kd, EncryptedPacket & in, PlainPacket & out); + +protected: + virtual u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0; + virtual u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0; + + kd_dir_t dir_; +}; + +//****** NullCipher ****** + +class NullCipher : public Cipher +{ +protected: + u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); +}; + +#ifndef NO_CRYPT +//****** AesIcmCipher ****** + +class AesIcmCipher : public Cipher +{ +public: + AesIcmCipher(kd_dir_t d); + AesIcmCipher(kd_dir_t d, u_int16_t key_length); + ~AesIcmCipher(); + + static const u_int16_t DEFAULT_KEY_LENGTH = 128; + static const u_int16_t CTR_LENGTH = 16; + static const u_int16_t SALT_LENGTH = 14; + +protected: + u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + +private: + void init(u_int16_t key_length = DEFAULT_KEY_LENGTH); + + void calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + void calc(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + +#ifndef USE_SSL_CRYPTO + gcry_cipher_hd_t handle_; +#else + AES_KEY aes_key_; + u_int8_t ecount_buf_[AES_BLOCK_SIZE]; +#endif + Buffer key_; + Buffer salt_; + +#ifdef _MSC_VER + #pragma pack(push, 1) +#endif + union ATTR_PACKED cipher_aesctr_ctr_union { + u_int8_t buf_[CTR_LENGTH]; + struct ATTR_PACKED { + u_int8_t buf_[SALT_LENGTH]; + u_int16_t zero_; + } salt_; + struct ATTR_PACKED { + u_int8_t fill_[SALT_LENGTH - sizeof(mux_t) - sizeof(sender_id_t) - 2*sizeof(u_int8_t) - sizeof(seq_nr_t)]; + mux_t mux_; + sender_id_t sender_id_; + u_int8_t empty_[2]; + seq_nr_t seq_nr_; + u_int16_t zero_; + } params_; + } ctr_; +#ifdef _MSC_VER + #pragma pack(pop) +#endif +}; +#endif + +#endif diff --git a/src/cipherFactory.cpp b/src/cipherFactory.cpp new file mode 100644 index 0000000..e9f0292 --- /dev/null +++ b/src/cipherFactory.cpp @@ -0,0 +1,56 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include "cipherFactory.h" +#include "cipher.h" + + +Cipher* CipherFactory::create(std::string const& type, kd_dir_t dir) +{ + if(type == "null") + return new NullCipher(); +#ifndef NO_CRYPT + else if(type == "aes-ctr") + return new AesIcmCipher(dir); + else if(type == "aes-ctr-128") + return new AesIcmCipher(dir, 128); + else if(type == "aes-ctr-192") + return new AesIcmCipher(dir, 192); + else if(type == "aes-ctr-256") + return new AesIcmCipher(dir, 256); +#endif + else + throw std::invalid_argument("cipher not available"); +} + diff --git a/src/cipherFactory.h b/src/cipherFactory.h new file mode 100644 index 0000000..23d3b92 --- /dev/null +++ b/src/cipherFactory.h @@ -0,0 +1,52 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CIPHER_FACTORY_H_ +#define _CIPHER_FACTORY_H_ + +#include + +#include "datatypes.h" +#include "cipher.h" + +class CipherFactory +{ +public: + static Cipher* create(std::string const& type, kd_dir_t dir); + +private: + CipherFactory(); + CipherFactory(const CipherFactory& src); + void operator=(const CipherFactory& src); + ~CipherFactory(); +}; + +#endif diff --git a/src/configure b/src/configure new file mode 100755 index 0000000..770318b --- /dev/null +++ b/src/configure @@ -0,0 +1,136 @@ +#!/bin/sh +# +# anytun +# +# The secure anycast tunneling protocol (satp) defines a protocol used +# for communication between any combination of unicast and anycast +# tunnel endpoints. It has less protocol overhead than IPSec in Tunnel +# mode and allows tunneling of every ETHER TYPE protocol (e.g. +# ethernet, ip, arp ...). satp directly includes cryptography and +# message authentication based on the methodes used by SRTP. It is +# intended to deliver a generic, scaleable and secure solution for +# tunneling and relaying of packets of any protocol. +# +# +# Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, +# Christian Pointner +# +# This file is part of Anytun. +# +# Anytun is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3 as +# published by the Free Software Foundation. +# +# Anytun 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 anytun. If not, see . +# + +TARGET=`uname -s` + +CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG -DLOG_FILE -DLOG_STDOUT' +LDFLAGS='-g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system' + +CRYPTO_LIB='gcrypt' +PASSPHRASE=1 +ROUTING=1 + +print_usage() { + echo "configure --help print this" + echo " --use-ssl-crypto use ssl crypto library instead of libgcrypt" + echo " --disable-crypto disable crypto at all (only NULL cipher)" + echo " --disable-passphrase disable master key and salt passphrase" + echo " --disable-routing disable built-in routing capability" +} + +for arg +do + case $arg in + --use-ssl-crypto) + CRYPTO_LIB='ssl' + ;; + --disable-crypto) + CRYPTO_LIB='none' + ;; + --disable-passphrase) + PASSPHRASE=0 + ;; + --disable-routing) + ROUTING=0 + ;; + --help) + print_usage + exit 0 + ;; + *) + echo "Unknown argument: $arg" + print_usage + exit 1 + ;; + esac +done + +rm -f include.mk +case $TARGET in + Linux) + rm -rf tunDevice.cpp + ln -sf linux/tunDevice.cpp + echo "loading Linux specific TUN Device" + ;; + OpenBSD|FreeBSD|NetBSD) + rm -rf tunDevice.cpp + ln -sf bsd/tunDevice.cpp + echo "loading BSD specific TUN Device" + CXXFLAGS=$CXXFLAGS' -I/usr/local/include' + LDFLAGS=$LDFLAGS' -L/usr/local/lib' + ;; + *) + echo "Plattform not supported" + exit 1 + ;; +esac + +case $CRYPTO_LIB in + gcrypt) + LDFLAGS=$LDFLAGS' -lgcrypt -lgpg-error' + echo "using libgcrypt library" + ;; + ssl) + CXXFLAGS=$CXXFLAGS' -DUSE_SSL_CRYPTO' + LDFLAGS=$LDFLAGS' -lcrypto' + echo "using ssl crypto library" + ;; + none) + CXXFLAGS=$CXXFLAGS' -DNO_CRYPT' + echo "NO_CRYPT_OBJ = 1" >> include.mk + echo "disabling crypto" + ;; +esac + +if [ $PASSPHRASE -eq 0 ]; then + CXXFLAGS=$CXXFLAGS' -DNO_PASSPHRASE' + echo "disabling master key and salt passphrase" +fi + +if [ $ROUTING -eq 0 ]; then + CXXFLAGS=$CXXFLAGS' -DNO_ROUTING' + echo "disabling built-in routing capability" +fi + +cat >> include.mk < + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "threadUtils.hpp" +#include "datatypes.h" +#include "keyDerivationFactory.h" +#include "options.h" +#include "packetSource.h" + +#include "connectionList.h" + +ConnectionList* ConnectionList::inst = NULL; +Mutex ConnectionList::instMutex; +ConnectionList& gConnectionList = ConnectionList::instance(); + + +ConnectionList& ConnectionList::instance() +{ + Lock lock(instMutex); + static instanceCleaner c; + if(!inst) + inst = new ConnectionList(); + + return *inst; +} + +ConnectionList::ConnectionList() +{ +} + +ConnectionList::~ConnectionList() +{ +// TODO: comment this in as soon as threads @ main get cleaned up properly +// Lock lock(mutex_); +// ConnectionMap::iterator it; +// for(it = connections_.begin(); it != connections_.end(); ++it) { +// delete &it->second.kd_; +// delete &it->second.seq_window_; +// } +} + +void ConnectionList::addConnection(ConnectionParam &conn, u_int16_t mux ) +{ + Lock lock(mutex_); + + std::pair ret = connections_.insert(ConnectionMap::value_type(mux, conn)); + if(!ret.second) + { + connections_.erase(ret.first); + connections_.insert(ConnectionMap::value_type(mux, conn)); + } +} + +const ConnectionMap::iterator ConnectionList::getEnd() +{ + Lock lock(mutex_); + return connections_.end(); +} + +ConnectionMap::iterator ConnectionList::getBeginUnlocked() +{ + return connections_.begin(); +} + +const ConnectionMap::iterator ConnectionList::getBegin() +{ + Lock lock(mutex_); + return connections_.begin(); +} + + +ConnectionMap::iterator ConnectionList::getEndUnlocked() +{ + return connections_.end(); +} + +const ConnectionMap::iterator ConnectionList::getConnection(u_int16_t mux) +{ + Lock lock(mutex_); + ConnectionMap::iterator it = connections_.find(mux); + return it; +} + + +ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux) +{ + ConnectionMap::iterator it = connections_.find(mux); + if(it!=connections_.end()) + return it->second; + + u_int8_t key[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' + }; + + u_int8_t salt[] = { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n' + }; + + SeqWindow * seq= new SeqWindow(0); + seq_nr_t seq_nr_=0; + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf()); + kd->init(Buffer(key, sizeof(key)), Buffer(salt, sizeof(salt))); + ConnectionParam conn ((*kd), (*seq), seq_nr_, PacketSourceEndpoint()); + connections_.insert(ConnectionMap::value_type(mux, conn)); + it = connections_.find(mux); + return it->second; +} + +void ConnectionList::clear() +{ + Lock lock(mutex_); + connections_.clear(); +} + +bool ConnectionList::empty() +{ + Lock lock(mutex_); + return connections_.empty(); +} + +Mutex& ConnectionList::getMutex() +{ + return mutex_; +} diff --git a/src/connectionList.h b/src/connectionList.h new file mode 100644 index 0000000..cdf5268 --- /dev/null +++ b/src/connectionList.h @@ -0,0 +1,78 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CONNECTION_LIST_H +#define _CONNECTION_LIST_H + +#include +#include + +#include "threadUtils.hpp" +#include "datatypes.h" +#include "connectionParam.h" +#include "networkAddress.h" +typedef std::map ConnectionMap; + +class ConnectionList +{ +public: + ConnectionList(); + ~ConnectionList(); + static ConnectionList& instance(); + void addConnection(ConnectionParam &conn, u_int16_t mux); + const ConnectionMap::iterator getConnection(u_int16_t mux); + const ConnectionMap::iterator getEnd(); + ConnectionMap::iterator getEndUnlocked(); + ConnectionMap::iterator getBeginUnlocked(); + const ConnectionMap::iterator getBegin(); + ConnectionParam & getOrNewConnectionUnlocked(u_int16_t mux); + bool empty(); + void clear(); + Mutex& getMutex(); + +private: + static Mutex instMutex; + static ConnectionList* inst; + class instanceCleaner { + public: ~instanceCleaner() { + if(ConnectionList::inst != 0) + delete ConnectionList::inst; + } + }; + ConnectionList(const ConnectionList &s); + void operator=(const ConnectionList &s); + ConnectionMap connections_; + Mutex mutex_; +}; + +extern ConnectionList& gConnectionList; + +#endif diff --git a/src/connectionParam.cpp b/src/connectionParam.cpp new file mode 100644 index 0000000..c6b3ded --- /dev/null +++ b/src/connectionParam.cpp @@ -0,0 +1,40 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include "connectionParam.h" + +ConnectionParam::ConnectionParam(KeyDerivation& kd, SeqWindow& seq_window,seq_nr_t seq_nr, PacketSourceEndpoint remote_end) : kd_(kd),seq_window_(seq_window),seq_nr_(seq_nr), remote_end_(remote_end) +{ +} + +ConnectionParam::ConnectionParam(const ConnectionParam & src) : kd_(src.kd_),seq_window_(src.seq_window_),seq_nr_(src.seq_nr_),remote_end_(src.remote_end_),mutex_() +{ +} diff --git a/src/connectionParam.h b/src/connectionParam.h new file mode 100644 index 0000000..f929211 --- /dev/null +++ b/src/connectionParam.h @@ -0,0 +1,79 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CONNECTIONPARAM_H_ +#define _CONNECTIONPARAM_H_ + +#include "keyDerivation.h" +#include "seqWindow.h" +#include "threadUtils.hpp" +#include "packetSource.h" +#include "log.h" + +#include +#include + +class ConnectionParam +{ +public: + ConnectionParam(const ConnectionParam & src); + ConnectionParam( KeyDerivation& kd, SeqWindow& seq_window, seq_nr_t seq_nr_, PacketSourceEndpoint remote_end); + + KeyDerivation& kd_; + SeqWindow& seq_window_; + seq_nr_t seq_nr_; + PacketSourceEndpoint remote_end_; + +private: + //TODO: check if this is ok + Mutex mutex_; + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + Lock lock(mutex_); + std::string remote_host(remote_end_.address().to_string()); + u_int16_t remote_port = remote_end_.port(); + ar & kd_; + ar & seq_window_; + ar & seq_nr_; + ar & remote_host; + ar & remote_port; + PacketSourceEndpoint emptyEndpoint; + UDPPacketSource::proto::endpoint endpoint(boost::asio::ip::address::from_string(remote_host), remote_port); + //This is a workarround, against race condition in sync process + //TODO: find a better solution + if (endpoint != emptyEndpoint && remote_host != "::" && remote_host != "[::]" && remote_host != "0.0.0.0") + remote_end_ = endpoint; + } +}; + +#endif diff --git a/src/cryptinit.hpp b/src/cryptinit.hpp new file mode 100644 index 0000000..4460de0 --- /dev/null +++ b/src/cryptinit.hpp @@ -0,0 +1,113 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _CRYPTINIT_HPP +#define _CRYPTINIT_HPP + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +#include + +// boost thread callbacks for libgcrypt +#if defined(BOOST_HAS_PTHREADS) + +static int boost_mutex_init(void **priv) +{ + boost::mutex *lock = new boost::mutex(); + if (!lock) + return ENOMEM; + *priv = lock; + return 0; +} + +static int boost_mutex_destroy(void **lock) +{ + delete reinterpret_cast(*lock); + return 0; +} + +static int boost_mutex_lock(void **lock) +{ + reinterpret_cast(*lock)->lock(); + return 0; +} + +static int boost_mutex_unlock(void **lock) +{ + reinterpret_cast(*lock)->unlock(); + return 0; +} + +static struct gcry_thread_cbs gcry_threads_boost = +{ GCRY_THREAD_OPTION_USER, NULL, + boost_mutex_init, boost_mutex_destroy, + boost_mutex_lock, boost_mutex_unlock }; +#else +#error this libgcrypt thread callbacks only work with pthreads +#endif + + +#define MIN_GCRYPT_VERSION "1.2.0" + +bool initLibGCrypt() +{ + // make libgcrypt thread safe + // this must be called before any other libgcrypt call + gcry_control( GCRYCTL_SET_THREAD_CBS, &gcry_threads_boost ); + + // this must be called right after the GCRYCTL_SET_THREAD_CBS command + // no other function must be called till now + if( !gcry_check_version( MIN_GCRYPT_VERSION ) ) { + std::cout << "initLibGCrypt: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION << std::endl; + return false; + } + + gcry_error_t err = gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if( err ) { + std::cout << "initLibGCrypt: Failed to disable secure memory: " << AnytunGpgError(err) << std::endl; + return false; + } + + // Tell Libgcrypt that initialization has completed. + err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED); + if( err ) { + std::cout << "initLibGCrypt: Failed to finish initialization: " << AnytunGpgError(err) << std::endl; + return false; + } + + cLog.msg(Log::PRIO_NOTICE) << "initLibGCrypt: libgcrypt init finished"; + return true; +} +#endif +#endif + +#endif + diff --git a/src/daemon.hpp b/src/daemon.hpp new file mode 100644 index 0000000..b62da17 --- /dev/null +++ b/src/daemon.hpp @@ -0,0 +1,165 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _DAEMON_HPP +#define _DAEMON_HPP +#ifndef NO_DAEMON + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "anytunError.h" + +#ifndef NO_PRIVDROP +class PrivInfo +{ +public: + PrivInfo(std::string const& username, std::string const& groupname) + { + pw_ = NULL; + gr_ = NULL; + + if(username == "") + return; + + pw_ = getpwnam(username.c_str()); + if(!pw_) + AnytunError::throwErr() << "unkown user " << username; + + if(groupname != "") + gr_ = getgrnam(groupname.c_str()); + else + gr_ = getgrgid(pw_->pw_gid); + + if(!gr_) + AnytunError::throwErr() << "unkown group " << groupname; + } + + void drop() + { + if(!pw_ || !gr_) + return; + + if(setgid(gr_->gr_gid)) + AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno); + + gid_t gr_list[1]; + gr_list[0] = gr_->gr_gid; + if(setgroups (1, gr_list)) + AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno); + + if(setuid(pw_->pw_uid)) + AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno); + + cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name; + } + +private: + struct passwd* pw_; + struct group* gr_; +}; +#endif + +void do_chroot(std::string const& chrootdir) +{ + if (getuid() != 0) + AnytunError::throwErr() << "this programm has to be run as root in order to run in a chroot"; + + if(chroot(chrootdir.c_str())) + AnytunError::throwErr() << "can't chroot to " << chrootdir; + + cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl; + if(chdir("/")) + AnytunError::throwErr() << "can't change to /"; +} + +void daemonize() +{ + std::ofstream pidFile; + if(gOpt.getPidFile() != "") { + pidFile.open(gOpt.getPidFile().c_str()); + if(!pidFile.is_open()) + AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno); + } + + pid_t pid; + + pid = fork(); + if(pid < 0) + AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; + + if(pid) exit(0); + + umask(0); + + if(setsid() < 0) + AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting"; + + pid = fork(); + if(pid < 0) + AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting"; + + if(pid) exit(0); + + if ((chdir("/")) < 0) + AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting"; + +// std::cout << "running in background now..." << std::endl; + + int fd; +// for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors + for (fd=0;fd<=2;fd++) // close all file descriptors + close(fd); + fd = open("/dev/null",O_RDWR); // stdin + if(fd == -1) + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin"; + else { + if(dup(fd) == -1) // stdout + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout"; + if(dup(fd) == -1) // stderr + cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr"; + } + + if(pidFile.is_open()) { + pid_t pid = getpid(); + pidFile << pid; + pidFile.close(); + } +} +#endif +#endif + diff --git a/src/datatypes.h b/src/datatypes.h new file mode 100644 index 0000000..141aae3 --- /dev/null +++ b/src/datatypes.h @@ -0,0 +1,67 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _DATATYPES_H_ +#define _DATATYPES_H_ + +#include +#include + +typedef boost::uint8_t u_int8_t; +typedef boost::uint16_t u_int16_t; +typedef boost::uint32_t u_int32_t; +typedef boost::uint64_t u_int64_t; +typedef boost::int8_t int8_t; +typedef boost::int16_t int16_t; +typedef boost::int32_t int32_t; +typedef boost::int64_t int64_t; + +typedef u_int32_t window_size_t; + +typedef u_int32_t seq_nr_t; +#define SEQ_NR_MAX 0xFFFFFFFF +typedef u_int16_t sender_id_t; +typedef u_int16_t payload_type_t; +typedef u_int16_t mux_t; +typedef u_int32_t satp_prf_label_t; + +typedef enum { ANY, IPV4_ONLY, IPV6_ONLY } ResolvAddrType; + +#ifndef _MSC_VER +#define ATTR_PACKED __attribute__((__packed__)) +typedef int system_error_t; +#else +#include +#define ATTR_PACKED +typedef DWORD system_error_t; +#endif + +#endif diff --git a/src/deviceConfig.hpp b/src/deviceConfig.hpp new file mode 100644 index 0000000..d8702b9 --- /dev/null +++ b/src/deviceConfig.hpp @@ -0,0 +1,97 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _DEVICE_CONFIG_HPP_ +#define _DEVICE_CONFIG_HPP_ + +#include "networkAddress.h" +#include +#include "anytunError.h" + +class TunDevice; + +enum device_type_t { TYPE_UNDEF, TYPE_TUN, TYPE_TAP }; + +class DeviceConfig +{ +public: + DeviceConfig(std::string dev_name ,std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix, u_int16_t mtu) + { + mtu_ = mtu; + type_ = TYPE_UNDEF; +#ifndef _MSC_VER + if(dev_type != "") { + if(!dev_type.compare(0,3,"tun")) + type_ = TYPE_TUN; + else if (!dev_type.compare(0,3,"tap")) + type_ = TYPE_TAP; + } + else if(dev_name != "") { + if(!dev_name.compare(0,3,"tun")) + type_ = TYPE_TUN; + else if(!dev_name.compare(0,3,"tap")) + type_ = TYPE_TAP; + } +#else + if(dev_type == "") + AnytunError::throwErr() << "Device type must be specified on Windows"; + + if(dev_type == "tun") + type_ = TYPE_TUN; + else if(dev_type == "tap") + type_ = TYPE_TAP; + + if(type_ == TYPE_TUN && ifcfg_addr == "") + AnytunError::throwErr() << "Device type tun requires ifconfig parameter (--ifconfig)"; +#endif + + if(ifcfg_addr != "") + addr_.setNetworkAddress(ipv4, ifcfg_addr.c_str()); + prefix_ = ifcfg_prefix; + u_int32_t mask = 0; + for(u_int16_t i = 0; i < prefix_; ++i) { + mask = mask >> 1; + mask |= 0x80000000L; + } + netmask_.setNetworkAddress(boost::asio::ip::address_v4(mask)); + } + +private: + device_type_t type_; + NetworkAddress addr_; + NetworkAddress netmask_; + u_int16_t prefix_; + u_int16_t mtu_; + + friend class TunDevice; +}; + +#endif diff --git a/src/encryptedPacket.cpp b/src/encryptedPacket.cpp new file mode 100644 index 0000000..a5aec86 --- /dev/null +++ b/src/encryptedPacket.cpp @@ -0,0 +1,222 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include // for std::memcpy + +#include "encryptedPacket.h" +#include "endian.h" +#include "datatypes.h" +#include "log.h" +#include "anytunError.h" + +EncryptedPacket::EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc) + : Buffer(payload_length + sizeof(struct HeaderStruct), allow_realloc), auth_tag_length_(auth_tag_length) +{ + header_ = reinterpret_cast(buf_); + payload_ = buf_ + sizeof(struct HeaderStruct); + auth_tag_ = NULL; + if(header_) + { + header_->seq_nr = 0; + header_->sender_id = 0; + header_->mux = 0; + } +} + +u_int32_t EncryptedPacket::getHeaderLength() +{ + return sizeof(struct HeaderStruct); +} + +seq_nr_t EncryptedPacket::getSeqNr() const +{ + if(header_) + return SEQ_NR_T_NTOH(header_->seq_nr); + + return 0; +} + +sender_id_t EncryptedPacket::getSenderId() const +{ + if(header_) + return SENDER_ID_T_NTOH(header_->sender_id); + + return 0; +} + +mux_t EncryptedPacket::getMux() const +{ + if(header_) + return MUX_T_NTOH(header_->mux); + + return 0; +} + +void EncryptedPacket::setSeqNr(seq_nr_t seq_nr) +{ + if(header_) + header_->seq_nr = SEQ_NR_T_HTON(seq_nr); +} + +void EncryptedPacket::setSenderId(sender_id_t sender_id) +{ + if(header_) + header_->sender_id = SENDER_ID_T_HTON(sender_id); +} + +void EncryptedPacket::setMux(mux_t mux) +{ + if(header_) + header_->mux = MUX_T_HTON(mux); +} + +void EncryptedPacket::setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) +{ + if(!header_) + return; + + header_->seq_nr = SEQ_NR_T_HTON(seq_nr); + header_->sender_id = SENDER_ID_T_HTON(sender_id); + header_->mux = MUX_T_HTON(mux); +} + +u_int32_t EncryptedPacket::getPayloadLength() const +{ + if(!payload_) + return 0; + + if(!auth_tag_) + return (length_ > sizeof(struct HeaderStruct)) ? (length_ - sizeof(struct HeaderStruct)) : 0; + + return (length_ > (sizeof(struct HeaderStruct) + auth_tag_length_)) ? (length_ - sizeof(struct HeaderStruct) - auth_tag_length_) : 0; +} + +void EncryptedPacket::setPayloadLength(u_int32_t payload_length) +{ + Buffer::setLength(payload_length + sizeof(struct HeaderStruct)); + // depending on allow_realloc buf_ may point to another address + // therefore in this case reinit() gets called by Buffer::setLength() +} + +void EncryptedPacket::reinit() +{ + header_ = reinterpret_cast(buf_); + payload_ = buf_ + sizeof(struct HeaderStruct); + + if(length_ <= (sizeof(struct HeaderStruct))) + payload_ = NULL; + + if(length_ < (sizeof(struct HeaderStruct))) { + header_ = NULL; + AnytunError::throwErr() << "encrypted packet can't be initialized, buffer is too small"; + } + + if(auth_tag_) + { + if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_)) { + auth_tag_ = NULL; + AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small"; + } + auth_tag_ = buf_ + length_ - auth_tag_length_; + } +} + +u_int8_t* EncryptedPacket::getPayload() +{ + return payload_; +} + +u_int8_t* EncryptedPacket::getAuthenticatedPortion() +{ + return buf_; +} + +u_int32_t EncryptedPacket::getAuthenticatedPortionLength() +{ + if(!buf_) + return 0; + + if(!auth_tag_) + return length_; + + return (length_ > auth_tag_length_) ? (length_ - auth_tag_length_) : 0; +} + +void EncryptedPacket::withAuthTag(bool b) +{ + if((b && auth_tag_) || (!b && !auth_tag_)) + return; + + if(b) + { + if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_)) + AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small"; + + auth_tag_ = buf_ + length_ - auth_tag_length_; + } + else + auth_tag_ = NULL; +} + +void EncryptedPacket::addAuthTag() +{ + if(auth_tag_) + return; + + auth_tag_ = buf_; // will be set to the correct value @ reinit + setLength(length_ + auth_tag_length_); + if(auth_tag_ == buf_) // reinit was not called by setLength + reinit(); +} + +void EncryptedPacket::removeAuthTag() +{ + if(!auth_tag_) + return; + + auth_tag_ = NULL; + setLength(length_ - auth_tag_length_); +} + +u_int8_t* EncryptedPacket::getAuthTag() +{ + return auth_tag_; +} + +u_int32_t EncryptedPacket::getAuthTagLength() +{ + if(auth_tag_) + return auth_tag_length_; + + return 0; +} diff --git a/src/encryptedPacket.h b/src/encryptedPacket.h new file mode 100644 index 0000000..618fa44 --- /dev/null +++ b/src/encryptedPacket.h @@ -0,0 +1,158 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _ENCRYPTED_PACKET_H_ +#define _ENCRYPTED_PACKET_H_ + +#include "datatypes.h" +#include "buffer.h" + +class Cipher; +class EncryptedPacket : public Buffer +{ +public: + + /** + * Packet constructor + * @param the length of the payload + * @param allow reallocation of buffer + */ + EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc = false); + + /** + * Packet destructor + */ + ~EncryptedPacket() {}; + + /** + * Get the length of the header + * @return the length of the header + */ + static u_int32_t getHeaderLength(); + + /** + * Get the sequence number + * @return seqence number + */ + seq_nr_t getSeqNr() const; + + /** + * Set the seqence number + * @param seq_nr sequence number + */ + void setSeqNr(seq_nr_t seq_nr); + + /** + * Get the sender id + * @return sender id + */ + sender_id_t getSenderId() const; + + /** + * Set the sender id + * @param sender_id sender id + */ + void setSenderId(sender_id_t sender_id); + + /** + * Get the mulitplex id + * @return multiplex id + */ + mux_t getMux() const; + + /** + * Set the multiplex id + * @param mux multiplex id + */ + void setMux(mux_t mux); + + /** + * Set the header of a packet + * @param seq_nr sequence number + * @param sender_id sender id + * @param mux multiplex id + */ + void setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux); + + /** + * Get the length of the payload + * @return the length of the payload + */ + u_int32_t getPayloadLength() const; + + /** + * Set the length of the payload + * @param length length of the payload + */ + void setPayloadLength(u_int32_t payload_length); + + /** + * Get the the payload + * @return the Pointer to the payload + */ + u_int8_t* getPayload(); + + + u_int8_t* getAuthenticatedPortion(); + u_int32_t getAuthenticatedPortionLength(); + + void withAuthTag(bool b); + void addAuthTag(); + void removeAuthTag(); + u_int8_t* getAuthTag(); + u_int32_t getAuthTagLength(); + +private: + EncryptedPacket(); + EncryptedPacket(const EncryptedPacket &src); + + void reinit(); + +#ifdef _MSC_VER + #pragma pack(push, 1) +#endif + struct ATTR_PACKED HeaderStruct + { + seq_nr_t seq_nr; + sender_id_t sender_id; + mux_t mux; + }; +#ifdef _MSC_VER + #pragma pack(pop) +#endif + + struct HeaderStruct* header_; + u_int8_t * payload_; + u_int8_t * auth_tag_; + u_int32_t auth_tag_length_; +}; + +#endif diff --git a/src/endian.h b/src/endian.h new file mode 100644 index 0000000..9d96126 --- /dev/null +++ b/src/endian.h @@ -0,0 +1,59 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _ENDIAN_H_ +#define _ENDIAN_H_ + +#ifndef _WIN32 +#include +#else +#include +#endif + +#define SEQ_NR_T_NTOH(a) ntohl(a) +#define SEQ_NR_T_HTON(a) htonl(a) + +#define SENDER_ID_T_NTOH(a) ntohs(a) +#define SENDER_ID_T_HTON(a) htons(a) + +#define PAYLOAD_TYPE_T_NTOH(a) ntohs(a) +#define PAYLOAD_TYPE_T_HTON(a) htons(a) + +#define MUX_T_NTOH(a) ntohs(a) +#define MUX_T_HTON(a) htons(a) + +#define SATP_PRF_LABEL_T_NTOH(a) ntohl(a) +#define SATP_PRF_LABEL_T_HTON(a) htonl(a) + +//#define AUTH_TAG_T_NTOH(a) ntohl(a) +//#define AUTH_TAG_T_HTON(a) htonl(a) + +#endif diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp new file mode 100644 index 0000000..cdf6368 --- /dev/null +++ b/src/keyDerivation.cpp @@ -0,0 +1,340 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + + +#include "log.h" +#include "anytunError.h" +#include "keyDerivation.h" +#include "threadUtils.hpp" +#include "datatypes.h" +#include "endian.h" + +#include +#include +#include +#include + +#ifndef NO_CRYPT +#ifndef NO_PASSPHRASE +#ifdef USE_SSL_CRYPTO +#include +#endif +#endif +#endif + +void KeyDerivation::setRole(const role_t role) +{ + WritersLock lock(mutex_); + role_ = role; + cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: using role " << role_; +} + +#ifndef NO_CRYPT +#ifndef NO_PASSPHRASE +void KeyDerivation::calcMasterKey(std::string passphrase, u_int16_t length) +{ + cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase"; + if(!length) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master key length"; + return; + } + +#ifndef USE_SSL_CRYPTO + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) { +#else + if(length > SHA256_DIGEST_LENGTH) { +#endif + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm"; + return; + } + +#ifndef USE_SSL_CRYPTO + Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA256)); + gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length()); +#else + Buffer digest(u_int32_t(SHA256_DIGEST_LENGTH)); + SHA256(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#endif + master_key_.setLength(length); + + memcpy(master_key_.getBuf(), &digest.getBuf()[digest.getLength() - master_key_.getLength()], master_key_.getLength()); +} + +void KeyDerivation::calcMasterSalt(std::string passphrase, u_int16_t length) +{ + cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master salt from passphrase"; + if(!length) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master salt length"; + return; + } + +#ifndef USE_SSL_CRYPTO + if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) { +#else + if(length > SHA_DIGEST_LENGTH) { +#endif + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm"; + return; + } + +#ifndef USE_SSL_CRYPTO + Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA1)); + gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length()); +#else + Buffer digest(u_int32_t(SHA_DIGEST_LENGTH)); + SHA1(reinterpret_cast(passphrase.c_str()), passphrase.length(), digest.getBuf()); +#endif + master_salt_.setLength(length); + + memcpy(master_salt_.getBuf(), &digest.getBuf()[digest.getLength() - master_salt_.getLength()], master_salt_.getLength()); +} +#endif +#endif + +satp_prf_label_t KeyDerivation::convertLabel(kd_dir_t dir, satp_prf_label_t label) +{ + switch(label) { + case LABEL_ENC: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_ENC; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_ENC; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_ENC; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_ENC; + } + break; + } + case LABEL_SALT: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_SALT; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_SALT; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_SALT; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_SALT; + } + break; + } + case LABEL_AUTH: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_AUTH; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_AUTH; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_AUTH; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_AUTH; + } + break; + } + } + + return label; +} + +//****** NullKeyDerivation ****** + +bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) +{ + std::memset(key.getBuf(), 0, key.getLength()); + return true; +} + +#ifndef NO_CRYPT +//****** AesIcmKeyDerivation ****** + +AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH) +{ +#ifndef USE_SSL_CRYPTO + for(int i=0; i<2; i++) + handle_[i] = NULL; +#endif +} + +AesIcmKeyDerivation::AesIcmKeyDerivation(u_int16_t key_length) : KeyDerivation(key_length) +{ +#ifndef USE_SSL_CRYPTO + for(int i=0; i<2; i++) + handle_[i] = NULL; +#endif +} + +AesIcmKeyDerivation::~AesIcmKeyDerivation() +{ + WritersLock lock(mutex_); +#ifndef USE_SSL_CRYPTO + for(int i=0; i<2; i++) + if(handle_[i]) + gcry_cipher_close(handle_[i]); +#endif +} + +void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase) +{ + WritersLock lock(mutex_); + + is_initialized_ = false; +#ifndef NO_PASSPHRASE + if(passphrase != "" && !key.getLength()) + calcMasterKey(passphrase, key_length_/8); + else + master_key_ = SyncBuffer(key); + + if(passphrase != "" && !salt.getLength()) + calcMasterSalt(passphrase, SALT_LENGTH); + else + master_salt_ = SyncBuffer(salt); +#else + master_key_ = SyncBuffer(key); + master_salt_ = SyncBuffer(salt); +#endif + + updateMasterKey(); +} + +void AesIcmKeyDerivation::updateMasterKey() +{ + if(master_key_.getLength()*8 != key_length_) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: key lengths don't match"; + return; + } + + if(master_salt_.getLength() != SALT_LENGTH) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: salt lengths don't match"; + return; + } + +#ifndef USE_SSL_CRYPTO + int algo; + switch(key_length_) { + case 128: algo = GCRY_CIPHER_AES128; break; + case 192: algo = GCRY_CIPHER_AES192; break; + case 256: algo = GCRY_CIPHER_AES256; break; + default: { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: cipher key length of " << key_length_ << " Bits is not supported"; + return; + } + } + + for(int i=0; i<2; i++) { + if(handle_[i]) + gcry_cipher_close(handle_[i]); + + gcry_error_t err = gcry_cipher_open(&handle_[i], algo, GCRY_CIPHER_MODE_CTR, 0); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to open cipher: " << AnytunGpgError(err); + return; + } + + err = gcry_cipher_setkey(handle_[i], master_key_.getBuf(), master_key_.getLength()); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set cipher key: " << AnytunGpgError(err); + return; + } + } +#else + for(int i=0; i<2; i++) { + int ret = AES_set_encrypt_key(master_key_.getBuf(), master_key_.getLength()*8, &aes_key_[i]); + if(ret) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")"; + return; + } + } +#endif + is_initialized_ = true; +} + +std::string AesIcmKeyDerivation::printType() +{ + ReadersLock lock(mutex_); + + std::stringstream sstr; + sstr << "AesIcm" << key_length_ << "KeyDerivation"; + return sstr.str(); +} + +bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr) +{ + if(master_salt_.getLength() != SALT_LENGTH) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::calcCtr: salt lengths don't match"; + return false; + } + memcpy(ctr_[dir].salt_.buf_, master_salt_.getBuf(), SALT_LENGTH); + ctr_[dir].salt_.zero_ = 0; + ctr_[dir].params_.label_ ^= SATP_PRF_LABEL_T_HTON(convertLabel(dir, label)); + ctr_[dir].params_.seq_ ^= SEQ_NR_T_HTON(seq_nr); + + return true; +} + +bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) +{ + ReadersLock lock(mutex_); + + if(!is_initialized_) + return false; + + if(!calcCtr(dir, label, seq_nr)) { + return false; + } + +#ifndef USE_SSL_CRYPTO + gcry_error_t err = gcry_cipher_reset(handle_[dir]); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to reset cipher: " << AnytunGpgError(err); + } + + err = gcry_cipher_setctr(handle_[dir], ctr_[dir].buf_, CTR_LENGTH); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to set CTR: " << AnytunGpgError(err); + return false; + } + + std::memset(key.getBuf(), 0, key.getLength()); + err = gcry_cipher_encrypt(handle_[dir], key, key.getLength(), NULL, 0); + if(err) { + cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err); + } +#else + if(CTR_LENGTH != AES_BLOCK_SIZE) { + cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits"; + return false; + } + unsigned int num = 0; + std::memset(ecount_buf_[dir], 0, AES_BLOCK_SIZE); + std::memset(key.getBuf(), 0, key.getLength()); + AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num); +#endif + + return true; +} +#endif + diff --git a/src/keyDerivation.h b/src/keyDerivation.h new file mode 100644 index 0000000..12d370c --- /dev/null +++ b/src/keyDerivation.h @@ -0,0 +1,203 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _KEYDERIVATION_H_ +#define _KEYDERIVATION_H_ + +#include "datatypes.h" +#include "buffer.h" +#include "threadUtils.hpp" +#include "syncBuffer.h" +#include "options.h" + +#ifndef NO_CRYPT +#ifndef USE_SSL_CRYPTO +#include +#else +#include +#endif +#endif +#include +#include + +#define LABEL_ENC 0 +#define LABEL_AUTH 1 +#define LABEL_SALT 2 + +#define LABEL_LEFT_ENC 0x356A192B +#define LABEL_RIGHT_ENC 0xDA4B9237 +#define LABEL_LEFT_SALT 0x77DE68DA +#define LABEL_RIGHT_SALT 0x1B645389 +#define LABEL_LEFT_AUTH 0xAC3478D6 +#define LABEL_RIGHT_AUTH 0xC1DFD96E + +typedef enum { KD_INBOUND, KD_OUTBOUND } kd_dir_t; + +class KeyDerivation +{ +public: + KeyDerivation() : is_initialized_(false), role_(ROLE_LEFT), key_length_(0), master_salt_(0), master_key_(0) {}; + KeyDerivation(u_int16_t key_length) : is_initialized_(false), role_(ROLE_LEFT), key_length_(key_length), master_salt_(0), master_key_(0) {}; + virtual ~KeyDerivation() {}; + + void setRole(const role_t role); + + virtual void init(Buffer key, Buffer salt, std::string passphrase = "") = 0; + virtual bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) = 0; + + virtual std::string printType() { return "GenericKeyDerivation"; }; + + satp_prf_label_t convertLabel(kd_dir_t dir, satp_prf_label_t label); + +protected: + virtual void updateMasterKey() = 0; + +#ifndef NO_PASSPHRASE + void calcMasterKey(std::string passphrase, u_int16_t length); + void calcMasterSalt(std::string passphrase, u_int16_t length); +#endif + + KeyDerivation(const KeyDerivation & src); + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + WritersLock lock(mutex_); + ar & role_; + ar & key_length_; + ar & master_salt_; + ar & master_key_; + updateMasterKey(); + } + + bool is_initialized_; + role_t role_; + u_int16_t key_length_; + SyncBuffer master_salt_; + SyncBuffer master_key_; + + SharedMutex mutex_; +}; + +#if BOOST_VERSION <= 103500 +BOOST_IS_ABSTRACT(KeyDerivation); +#else +BOOST_SERIALIZATION_ASSUME_ABSTRACT(KeyDerivation); +#endif + +//****** NullKeyDerivation ****** + +class NullKeyDerivation : public KeyDerivation +{ +public: + NullKeyDerivation() {}; + ~NullKeyDerivation() {}; + + void init(Buffer key, Buffer salt, std::string passphrase = "") {}; + bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key); + + std::string printType() { return "NullKeyDerivation"; }; + +private: + void updateMasterKey() {}; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & boost::serialization::base_object(*this); + } + +}; + +#ifndef NO_CRYPT +//****** AesIcmKeyDerivation ****** + +class AesIcmKeyDerivation : public KeyDerivation +{ +public: + AesIcmKeyDerivation(); + AesIcmKeyDerivation(u_int16_t key_length); + ~AesIcmKeyDerivation(); + + static const u_int16_t DEFAULT_KEY_LENGTH = 128; + static const u_int16_t CTR_LENGTH = 16; + static const u_int16_t SALT_LENGTH = 14; + + void init(Buffer key, Buffer salt, std::string passphrase = ""); + bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key); + + std::string printType(); + +private: + void updateMasterKey(); + + bool calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr); + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & boost::serialization::base_object(*this); + } + +#ifndef USE_SSL_CRYPTO + gcry_cipher_hd_t handle_[2]; +#else + AES_KEY aes_key_[2]; + u_int8_t ecount_buf_[2][AES_BLOCK_SIZE]; +#endif + +#ifdef _MSC_VER + #pragma pack(push, 1) +#endif + union ATTR_PACKED key_derivation_aesctr_ctr_union { + u_int8_t buf_[CTR_LENGTH]; + struct ATTR_PACKED { + u_int8_t buf_[SALT_LENGTH]; + u_int16_t zero_; + } salt_; + struct ATTR_PACKED { + u_int8_t fill_[SALT_LENGTH - sizeof(satp_prf_label_t) - sizeof(seq_nr_t)]; + satp_prf_label_t label_; + seq_nr_t seq_; + u_int16_t zero_; + } params_; + } ctr_[2]; +#ifdef _MSC_VER + #pragma pack(pop) +#endif +}; + +#endif + +#endif + diff --git a/src/keyDerivationFactory.cpp b/src/keyDerivationFactory.cpp new file mode 100644 index 0000000..75df38a --- /dev/null +++ b/src/keyDerivationFactory.cpp @@ -0,0 +1,56 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include "keyDerivationFactory.h" +#include "keyDerivation.h" + + +KeyDerivation* KeyDerivationFactory::create(std::string const& type) +{ + if(type == "null") + return new NullKeyDerivation(); +#ifndef NO_CRYPT + else if(type == "aes-ctr") + return new AesIcmKeyDerivation(); + else if(type == "aes-ctr-128") + return new AesIcmKeyDerivation(128); + else if(type == "aes-ctr-192") + return new AesIcmKeyDerivation(192); + else if(type == "aes-ctr-256") + return new AesIcmKeyDerivation(256); +#endif + else + throw std::invalid_argument("key derivation prf not available"); +} + diff --git a/src/keyDerivationFactory.h b/src/keyDerivationFactory.h new file mode 100644 index 0000000..77caf58 --- /dev/null +++ b/src/keyDerivationFactory.h @@ -0,0 +1,52 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _KEYDERIVATION_FACTORY_H_ +#define _KEYDERIVATION_FACTORY_H_ + +#include + +#include "datatypes.h" +#include "keyDerivation.h" + +class KeyDerivationFactory +{ +public: + static KeyDerivation* create(std::string const& type); + +private: + KeyDerivationFactory(); + KeyDerivationFactory(const KeyDerivationFactory& src); + void operator=(const KeyDerivationFactory& src); + ~KeyDerivationFactory(); +}; + +#endif diff --git a/src/linux/tunDevice.cpp b/src/linux/tunDevice.cpp new file mode 100644 index 0000000..b34ae9d --- /dev/null +++ b/src/linux/tunDevice.cpp @@ -0,0 +1,173 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#define DEFAULT_DEVICE "/dev/net/tun" + +#include "tunDevice.h" +#include "threadUtils.hpp" +#include "log.h" +#include "anytunError.h" + +TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400) +{ + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + + if(conf_.type_ == TYPE_TUN) { + ifr.ifr_flags = IFF_TUN; + with_pi_ = true; + } + else if(conf_.type_ == TYPE_TAP) { + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + with_pi_ = false; + } + else + AnytunError::throwErr() << "unable to recognize type of device (tun or tap)"; + + if(dev_name != "") + strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ); + + fd_ = ::open(DEFAULT_DEVICE, O_RDWR); + if(fd_ < 0) + AnytunError::throwErr() << "can't open device file (" << DEFAULT_DEVICE << "): " << AnytunErrno(errno); + + if(!ioctl(fd_, TUNSETIFF, &ifr)) { + actual_name_ = ifr.ifr_name; + } else if(!ioctl(fd_, (('T' << 8) | 202), &ifr)) { + actual_name_ = ifr.ifr_name; + } else { + ::close(fd_); + AnytunError::throwErr() << "tun/tap device ioctl failed: " << AnytunErrno(errno); + } + actual_node_ = DEFAULT_DEVICE; + + if(ifcfg_addr != "") + do_ifconfig(); +} + +TunDevice::~TunDevice() +{ + if(fd_ > 0) + ::close(fd_); +} + +int TunDevice::fix_return(int ret, size_t pi_length) const +{ + if(ret < 0) + return ret; + + return (static_cast(ret) > pi_length ? (ret - pi_length) : 0); +} + +int TunDevice::read(u_int8_t* buf, u_int32_t len) +{ + if(fd_ < 0) + return -1; + + if(with_pi_) + { + struct iovec iov[2]; + struct tun_pi tpi; + + iov[0].iov_base = &tpi; + iov[0].iov_len = sizeof(tpi); + iov[1].iov_base = buf; + iov[1].iov_len = len; + return(fix_return(::readv(fd_, iov, 2), sizeof(tpi))); + } + else + return(::read(fd_, buf, len)); +} + +int TunDevice::write(u_int8_t* buf, u_int32_t len) +{ + if(fd_ < 0) + return -1; + + if(!buf) + return 0; + + if(with_pi_) + { + struct iovec iov[2]; + struct tun_pi tpi; + struct iphdr *hdr = reinterpret_cast(buf); + + tpi.flags = 0; + if(hdr->version == 4) + tpi.proto = htons(ETH_P_IP); + else + tpi.proto = htons(ETH_P_IPV6); + + iov[0].iov_base = &tpi; + iov[0].iov_len = sizeof(tpi); + iov[1].iov_base = buf; + iov[1].iov_len = len; + return(fix_return(::writev(fd_, iov, 2), sizeof(tpi))); + } + else + return(::write(fd_, buf, len)); +} + +void TunDevice::init_post() +{ +// nothing to be done here +} + +void TunDevice::do_ifconfig() +{ + std::ostringstream command; + command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString() + << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_; + + int result = system(command.str().c_str()); + if(result == -1) + cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig failed: " << AnytunErrno(errno); + else { + if(WIFEXITED(result)) + cLog.msg(Log::PRIO_NOTICE) << "ifconfig returned " << WEXITSTATUS(result); + else if(WIFSIGNALED(result)) + cLog.msg(Log::PRIO_NOTICE) << "ifconfig terminated after signal " << WTERMSIG(result); + else + cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig: unkown error"; + } +} diff --git a/src/log.cpp b/src/log.cpp new file mode 100644 index 0000000..d0ed7f8 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,101 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include +#include +#include "log.h" + +#include "threadUtils.hpp" + +Log* Log::inst = NULL; +Mutex Log::instMutex; +Log& cLog = Log::instance(); + +LogStringBuilder::LogStringBuilder(LogStringBuilder const& src) : log(src.log), prio(src.prio) +{ + stream << src.stream.str(); +} + +LogStringBuilder::LogStringBuilder(Log& l, int p) : log(l), prio(p) +{ + // do something on the start of the line. +} + +LogStringBuilder::~LogStringBuilder() +{ + log.log(stream.str(), prio); +} + +Log& Log::instance() +{ + Lock lock(instMutex); + static instanceCleaner c; + if(!inst) + inst = new Log(); + + return *inst; +} + +void Log::addTarget(std::string conf) +{ + Lock lock(mutex); + LogTarget* target = targets.add(conf); + target->open(); + if(target->getMaxPrio() > 0) + target->enable(); +} + +void Log::addTarget(LogTargetList::target_type_t type, int prio, std::string conf) +{ + Lock lock(mutex); + LogTarget* target = targets.add(type, prio, conf); + target->open(); + if(target->getMaxPrio() > 0) + target->enable(); +} + +void Log::log(std::string msg, int prio) +{ + Lock lock(mutex); + targets.log(msg, prio); +} + +std::string Log::prioToString(int prio) +{ + switch(prio) { + case PRIO_ERROR: return "ERROR"; + case PRIO_WARNING: return "WARNING"; + case PRIO_NOTICE: return "NOTICE"; + case PRIO_INFO: return "INFO"; + case PRIO_DEBUG: return "DEBUG"; + default: return "UNKNOWN"; + } +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..dcdedc4 --- /dev/null +++ b/src/log.h @@ -0,0 +1,102 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _LOG_H_ +#define _LOG_H_ + +#include +#include + +#include "logTargets.h" +#include "threadUtils.hpp" + +class Log; + +class LogStringBuilder +{ +public: + LogStringBuilder(LogStringBuilder const& src); + LogStringBuilder(Log& l, int p); + ~LogStringBuilder(); + + template + std::ostream& operator<<(T const& value) { return stream << value; } + +private: + Log& log; + int prio; + std::stringstream stream; +}; + +class Log +{ +public: + static const int PRIO_ERROR = 1; + static const int PRIO_WARNING = 2; + static const int PRIO_NOTICE = 3; + static const int PRIO_INFO = 4; + static const int PRIO_DEBUG = 5; + + static std::string prioToString(int prio); + + static Log& instance(); + + void addTarget(std::string conf); + void addTarget(LogTargetList::target_type_t type, int prio, std::string conf); + LogStringBuilder msg(int prio=PRIO_INFO) { return LogStringBuilder(*this, prio); } + +private: + Log() {}; + ~Log() {}; + Log(const Log &l); + void operator=(const Log &l); + + static Log* inst; + static Mutex instMutex; + class instanceCleaner { + public: ~instanceCleaner() { + if(Log::inst != 0) + delete Log::inst; + } + }; + friend class instanceCleaner; + + void log(std::string msg, int prio); + + Mutex mutex; + friend class LogStringBuilder; + + LogTargetList targets; +}; + +extern Log& cLog; + +#endif diff --git a/src/logTargets.cpp b/src/logTargets.cpp new file mode 100644 index 0000000..9a07309 --- /dev/null +++ b/src/logTargets.cpp @@ -0,0 +1,436 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#include + +#include "datatypes.h" + +#include "logTargets.h" +#include "log.h" +#include "anytunError.h" + +#include "options.h" + +#ifdef LOG_WINEVENTLOG +#include +#include +#endif + +LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE) +{ +} + +LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio) +{ +} + +LogTargetList::~LogTargetList() +{ + clear(); +} + +LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type) +{ + if(type == "syslog") return TARGET_SYSLOG; + if(type == "file") return TARGET_FILE; + if(type == "stdout") return TARGET_STDOUT; + if(type == "stderr") return TARGET_STDERR; + if(type == "eventlog") return TARGET_WINEVENTLOG; + return TARGET_UNKNOWN; +} + +std::string LogTargetList::targetTypeToString(target_type_t type) +{ + switch(type) { + case TARGET_SYSLOG: return "syslog"; + case TARGET_FILE: return "file"; + case TARGET_STDOUT: return "stdout"; + case TARGET_STDERR: return "stderr"; + case TARGET_WINEVENTLOG: return "eventlog"; + default: return "unknown"; + } +} + +LogTarget* LogTargetList::add(std::string conf) +{ + std::stringstream s(conf); + std::string type; + getline(s, type, ':'); + if(!s.good()) + throw syntax_error(conf, 0); + + int prio = Log::PRIO_NOTICE; + s >> prio; + if(s.fail()) + throw syntax_error(conf, conf.find_first_of(':')+1); + + char buff[100]; + if(s.good()) { + s.get(buff[0]); + if(buff[0] != ',') + throw syntax_error(conf, (s.tellg() > 0) ? static_cast(s.tellg()) - 1 : 0); + s.get(buff, 100); + } + else + buff[0] = 0; + + return add(targetTypeFromString(type), prio, buff); +} + +LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf) +{ + switch(type) { + case TARGET_SYSLOG: { + #ifdef LOG_SYSLOG + if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG)) + AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is supported only once"; + + return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second; + #else + AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is not supported"; + #endif + } + case TARGET_FILE: { + #ifdef LOG_FILE + if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE)) + AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is supported only once"; + + return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second; + #else + AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is not supported"; + #endif + } + case TARGET_STDOUT: + case TARGET_STDERR: { + #ifdef LOG_STDOUT + if(!LogTargetStdout::duplicateAllowed() && targets.count(type)) + AnytunError::throwErr() << targetTypeToString(type) << " logtarget is supported only once"; + + if(type == TARGET_STDERR) + return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second; + else + return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second; + #else + AnytunError::throwErr() << targetTypeToString(type) + " logtarget is not supported"; + #endif + } + case TARGET_WINEVENTLOG: { + #ifdef LOG_WINEVENTLOG + if(!LogTargetWinEventlog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG)) + AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is supported only once"; + + return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second; + #else + AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is not supported"; + #endif + } + default: + AnytunError::throwErr() << "unknown log target"; + } + return NULL; +} + +void LogTargetList::clear() +{ + TargetsMap::iterator it; + for(it = targets.begin(); it != targets.end(); ++it) + delete it->second; + targets.clear(); +} + +void LogTargetList::log(std::string msg, int prio) +{ + TargetsMap::const_iterator it; + for(it = targets.begin(); it != targets.end(); ++it) { + if(it->second->isEnabled() && it->second->getMaxPrio() >= prio) + it->second->log(msg, prio); + } +} + + +#ifdef LOG_SYSLOG +int LogTargetSyslog::facilityFromString(std::string fac) +{ + if(fac == "user") return FAC_USER; + if(fac == "mail") return FAC_MAIL; + if(fac == "daemon") return FAC_DAEMON; + if(fac == "auth") return FAC_AUTH; + if(fac == "syslog") return FAC_SYSLOG; + if(fac == "lpr") return FAC_LPR; + if(fac == "news") return FAC_NEWS; + if(fac == "uucp") return FAC_UUCP; + if(fac == "cron") return FAC_CRON; + if(fac == "authpriv") return FAC_AUTHPRIV; + if(fac == "ftp") return FAC_FTP; + if(fac == "local0") return FAC_LOCAL0; + if(fac == "local1") return FAC_LOCAL1; + if(fac == "local2") return FAC_LOCAL2; + if(fac == "local3") return FAC_LOCAL3; + if(fac == "local4") return FAC_LOCAL4; + if(fac == "local5") return FAC_LOCAL5; + if(fac == "local6") return FAC_LOCAL6; + if(fac == "local7") return FAC_LOCAL7; + + AnytunError::throwErr() << "unknown syslog facility"; + return 0; +} + +std::string LogTargetSyslog::facilityToString(int fac) +{ + switch(fac) { + case FAC_USER: return "user"; + case FAC_MAIL: return "mail"; + case FAC_DAEMON: return "daemon"; + case FAC_AUTH: return "auth"; + case FAC_SYSLOG: return "syslog"; + case FAC_LPR: return "lpr"; + case FAC_NEWS: return "news"; + case FAC_UUCP: return "uucp"; + case FAC_CRON: return "cron"; + case FAC_AUTHPRIV: return "authpriv"; + case FAC_FTP: return "ftp"; + case FAC_LOCAL0: return "local0"; + case FAC_LOCAL1: return "local1"; + case FAC_LOCAL2: return "local2"; + case FAC_LOCAL3: return "local3"; + case FAC_LOCAL4: return "local4"; + case FAC_LOCAL5: return "local5"; + case FAC_LOCAL6: return "local6"; + case FAC_LOCAL7: return "local7"; + default: AnytunError::throwErr() << "unknown syslog facility"; + } + return ""; +} + +LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + facility = FAC_DAEMON; + getline(s, logname, ','); + if(s.fail()) { + logname = "anytun"; + return; + } + std::string fac; + getline(s, fac, ','); + if(s.fail()) + return; + + facility = LogTargetSyslog::facilityFromString(fac); +} + +LogTargetSyslog::~LogTargetSyslog() +{ + if(opened) + close(); +} + +void LogTargetSyslog::open() +{ + openlog(logname.c_str(), LOG_PID, facility); + opened = true; +} + +void LogTargetSyslog::close() +{ + closelog(); + opened = false; +} + +void LogTargetSyslog::log(std::string msg, int prio) +{ + if(!opened) + return; + + syslog((prio + 2) | facility, "%s", msg.c_str()); +} + +LogTargetSyslog& LogTargetSyslog::setLogName(std::string l) +{ + logname = l; + if(opened) + close(); + open(); + return *this; +} + +LogTargetSyslog& LogTargetSyslog::setFacility(int f) +{ + facility = f; + if(opened) + close(); + open(); + return *this; +} +#endif + + +#ifdef LOG_FILE +LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + getline(s, logfilename, ','); + if(s.fail()) + logfilename = "anytun.log"; +} + +LogTargetFile::~LogTargetFile() +{ + if(opened) + close(); +} + +void LogTargetFile::open() +{ + logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app); + opened = logfile.is_open(); +} + +void LogTargetFile::close() +{ + if(logfile.is_open()) + logfile.close(); + opened = false; +} + +void LogTargetFile::log(std::string msg, int prio) +{ + if(!opened) + return; + + logfile << Log::prioToString(prio) << ": " << msg << std::endl; +} + +LogTargetFile& LogTargetFile::setLogFilename(std::string l) +{ + logfilename = l; + if(opened) + close(); + open(); + return *this; +} +#endif + + +#ifdef LOG_STDOUT +LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s) +{ +} + +LogTargetStdout::~LogTargetStdout() +{ + if(opened) + close(); +} + +void LogTargetStdout::open() +{ + opened = true; +} + +void LogTargetStdout::close() +{ + opened = false; +} + +void LogTargetStdout::log(std::string msg, int prio) +{ + if(!opened) + return; + + stream << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl; +} +#endif + + +#ifdef LOG_WINEVENTLOG +LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio) +{ + std::stringstream s(conf); + getline(s, logname, ','); + if(s.fail()) + logname = "anytun"; +} + +LogTargetWinEventlog::~LogTargetWinEventlog() +{ + if(opened) + close(); +} + +void LogTargetWinEventlog::open() +{ + h_event_source = RegisterEventSourceA(NULL, logname.c_str()); + if(h_event_source) + opened = true; +} + +void LogTargetWinEventlog::close() +{ + if(h_event_source) + DeregisterEventSource(h_event_source); + opened = false; +} + +void LogTargetWinEventlog::log(std::string msg, int prio) +{ + if(!opened) + return; + + LPCTSTR lpszStrings[1]; + CHAR buffer[STERROR_TEXT_MAX]; + StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str()); + lpszStrings[0] = buffer; + if(h_event_source) + ReportEventA(h_event_source, prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL); +} + +LogTargetWinEventlog& LogTargetWinEventlog::setLogName(std::string l) +{ + logname = l; + if(opened) + close(); + open(); + return *this; +} + +WORD LogTargetWinEventlog::prioToEventLogType(int prio) +{ + switch(prio) { + case Log::PRIO_ERROR: return EVENTLOG_ERROR_TYPE; + case Log::PRIO_WARNING: return EVENTLOG_WARNING_TYPE; + case Log::PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE; + case Log::PRIO_INFO: return EVENTLOG_SUCCESS; + case Log::PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE; + default: return EVENTLOG_ERROR_TYPE; + } +} +#endif diff --git a/src/logTargets.h b/src/logTargets.h new file mode 100644 index 0000000..64ad945 --- /dev/null +++ b/src/logTargets.h @@ -0,0 +1,203 @@ +/* + * anytun + * + * The secure anycast tunneling protocol (satp) defines a protocol used + * for communication between any combination of unicast and anycast + * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel + * mode and allows tunneling of every ETHER TYPE protocol (e.g. + * ethernet, ip, arp ...). satp directly includes cryptography and + * message authentication based on the methodes used by SRTP. It is + * intended to deliver a generic, scaleable and secure solution for + * tunneling and relaying of packets of any protocol. + * + * + * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, + * Christian Pointner + * + * This file is part of Anytun. + * + * Anytun is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * Anytun 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 anytun. If not, see . + */ + +#ifndef _LOG_TARGETS_H_ +#define _LOG_TARGETS_H_ + +#include +#include + +#ifdef LOG_SYSLOG +#include +#endif + +#ifdef LOG_FILE +#include +#endif + +#include "datatypes.h" + +class LogTarget +{ +public: + LogTarget(); + LogTarget(int prio); + virtual ~LogTarget() {}; + + virtual void open() = 0; + virtual void close() = 0; + bool isOpen() { return opened; }; + + void enable() { enabled = true; }; + void disable() { enabled = false; }; + bool isEnabled() { return enabled; }; + + int getMaxPrio() { return max_prio; }; + void setMaxPrio(int p) { max_prio = p; }; + + virtual void log(std::string msg, int prio) = 0; + +protected: + bool opened; + bool enabled; + int max_prio; +}; + +class LogTargetList +{ +public: + typedef enum { TARGET_UNKNOWN, TARGET_SYSLOG, TARGET_FILE, + TARGET_STDOUT, TARGET_STDERR, TARGET_WINEVENTLOG } target_type_t; + + static target_type_t targetTypeFromString(std::string type); + static std::string targetTypeToString(target_type_t type); + + ~LogTargetList(); + LogTarget* add(std::string conf); + LogTarget* add(target_type_t type, int prio, std::string conf); + void clear(); + + void log(std::string msg, int prio); + +private: + typedef std::multimap TargetsMap; + TargetsMap targets; +}; + + +#ifdef LOG_SYSLOG +class LogTargetSyslog : public LogTarget +{ +public: + static const int FAC_USER = LOG_USER; + static const int FAC_MAIL = LOG_MAIL; + static const int FAC_DAEMON = LOG_DAEMON; + static const int FAC_AUTH = LOG_AUTH; + static const int FAC_SYSLOG = LOG_SYSLOG; + static const int FAC_LPR = LOG_LPR; + static const int FAC_NEWS = LOG_NEWS; + static const int FAC_UUCP = LOG_UUCP; + static const int FAC_CRON = LOG_CRON; + static const int FAC_AUTHPRIV = LOG_AUTHPRIV; + static const int FAC_FTP = LOG_FTP; + static const int FAC_LOCAL0 = LOG_LOCAL0; + static const int FAC_LOCAL1 = LOG_LOCAL1; + static const int FAC_LOCAL2 = LOG_LOCAL2; + static const int FAC_LOCAL3 = LOG_LOCAL3; + static const int FAC_LOCAL4 = LOG_LOCAL4; + static const int FAC_LOCAL5 = LOG_LOCAL5; + static const int FAC_LOCAL6 = LOG_LOCAL6; + static const int FAC_LOCAL7 = LOG_LOCAL7; + + static int facilityFromString(std::string fac); + static std::string facilityToString(int fac); + + LogTargetSyslog(int prio, std::string conf); + ~LogTargetSyslog(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + + LogTargetSyslog& setLogName(std::string l); + std::string getLogName() const { return logname; } + LogTargetSyslog& setFacility(int f); + int getFacility() const { return facility; } + +private: + std::string logname; + int facility; +}; +#endif + +#ifdef LOG_FILE +class LogTargetFile : public LogTarget +{ +public: + LogTargetFile(int prio, std::string conf); + ~LogTargetFile(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return true; }; + + LogTargetFile& setLogFilename(std::string l); + std::string getLogFilename() const { return logfilename; } + +private: + std::string logfilename; + std::ofstream logfile; +}; +#endif + +#ifdef LOG_STDOUT +class LogTargetStdout : public LogTarget +{ +public: + LogTargetStdout(int prio, std::ostream& s); + ~LogTargetStdout(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + +private: + std::ostream& stream; +}; +#endif + +#ifdef LOG_WINEVENTLOG +class LogTargetWinEventlog : public LogTarget +{ +public: + static WORD prioToEventLogType(int prio); + + LogTargetWinEventlog(int prio, std::string conf); + ~LogTargetWinEventlog(); + + void open(); + void close(); + void log(std::string msg, int prio); + static bool duplicateAllowed() { return false; }; + + LogTargetWinEventlog& setLogName(std::string l); + std::string getLogName() const { return logname; }; + +private: + std::string logname; + HANDLE h_event_source; +}; +#endif + +#endif diff --git a/src/man/Makefile b/src/man/Makefile new file mode 100644 index 0000000..cdd45a6 --- /dev/null +++ b/src/man/Makefile @@ -0,0 +1,57 @@ +## +## anytun +## +## The secure anycast tunneling protocol (satp) defines a protocol used +## for communication between any combination of unicast and anycast +## tunnel endpoints. It has less protocol overhead than IPSec in Tunnel +## mode and allows tunneling of every ETHER TYPE protocol (e.g. +## ethernet, ip, arp ...). satp directly includes cryptography and +## message authentication based on the methodes used by SRTP. It is +## intended to deliver a generic, scaleable and secure solution for +## tunneling and relaying of packets of any protocol. +## +## +## Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, +## Christian Pointner +## +## This file is part of Anytun. +## +## Anytun is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License version 3 as +## published by the Free Software Foundation. +## +## Anytun 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 anytun. If not, see . +## + +all: manpage + +anytun.8: anytun.8.txt + a2x -f manpage anytun.8.txt + +anytun-controld.8: anytun-controld.8.txt + a2x -f manpage anytun-controld.8.txt + +anytun-config.8: anytun-config.8.txt + a2x -f manpage anytun-config.8.txt + +anytun-showtables.8: anytun-showtables.8.txt + a2x -f manpage anytun-showtables.8.txt + +anyrtpproxy.8: anyrtpproxy.8.txt + a2x -f manpage anyrtpproxy.8.txt + + +manpage: anytun.8 anytun-controld.8 anytun-config.8 anytun-showtables.8 anyrtpproxy.8 + +clean: + rm -f anytun.8 anytun.8.xml + rm -f anytun-controld.8 anytun-controld.8.xml + rm -f anytun-config.8 anytun-config.8.xml + rm -f anytun-showtables.8 anytun-showtables.8.xml + rm -f anyrtpproxy.8 anyrtpproxy.8.xml \ No newline at end of file diff --git a/src/man/anyrtpproxy.8.txt b/src/man/anyrtpproxy.8.txt new file mode 100644 index 0000000..a867631 --- /dev/null +++ b/src/man/anyrtpproxy.8.txt @@ -0,0 +1,184 @@ +anyrtpproxy(8) +============== + +NAME +---- +anyrtpproxy - anycast rtpproxy + +SYNOPSIS +-------- + +*anyrtpproxy* +[ *-h|--help* ] +[ *-D|--nodaemonize* ] +[ *-C|--chroot* ] +[ *-u|--username* ] +[ *-H|--chroot-dir* ] +[ *-P|--write-pid* ] +[ *-i|--interface* ] +[ *-s|--control* [:] ] +[ *-p|--port-range* ] +[ *-n|--nat* ] +[ *-o|--no-nat-once* ] +[ *-S|--sync-port* port> ] +[ *-M|--sync-hosts* :[,:[...]] ] + + +DESCRIPTION +----------- + +*anyrtpproxy* is a rtpproxy which can be used in combination with anycast. It uses +the same control protocol than rtpproxy though it can be controled through the nathelper +plugin of openser. *anyrtpproxy* uses the same synchronisation protocol than *anytun* +to sync the session information among all anycast instances. + + +OPTIONS +------- + +-D|--nodaemonize +~~~~~~~~~~~~~~~~ + +This option instructs *anyrtpproxy* to run in the foreground +instead of becoming a daemon. + +-C|--chroot +~~~~~~~~~~~ + +chroot and drop privileges + +-u|--username +~~~~~~~~~~~~~~~~~~~~~~~~ + +if chroot change to this user + +-H|--chroot-dir +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +chroot to this directory + +-P|--write-pid +~~~~~~~~~~~~~~~~~~~~~~~~~ + +write pid to this file + +-i|--interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The local interface to listen on for RTP packets + +-s|--control [:] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The local address and port to listen on for control messages from openser + +-p|--port-range +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A pool of ports which should be used by *anyrtpproxy* to relay RTP packets. +The range may not overlap between the anycast instances + +-n|--nat +~~~~~~~~ + +Allow to learn the remote address and port in order to handle clients behind nat. +This option should only be enabled if the source is authenticated (i.e. through +*anytun*) + +-o|--no-nat-once +~~~~~~~~~~~~~~~~ + +Disable learning of remote address and port in case the first packet does not +come from the client which is specified by openser during configuration. Invoking +this parameter increases the security level of the system but in case of nat needs +a working nat transversal such as stun. + +-S|--sync-port +~~~~~~~~~~~~~~~~~~~~~ + +local unicast(sync) port to bind to + +This port is used by anycast hosts to synchronize information about tunnel +endpoints. No payload data is transmitted via this port. + +It is possible to obtain a list of active connections by telnetting into +this port. This port is read-only and unprotected by default. It is advised +to protect this port using firewall rules and, eventually, IPsec. + +-M|--sync-hosts :,[:[...]] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +remote hosts to sync with + +Here, one has to specify all unicast IP addresses of all +other anycast hosts that comprise the anycast tunnel endpoint. + +EXAMPLES +-------- + +Anycast Setup with 3 instances: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On the host with unicast hostname unicast1.anycast.anytun.org and anycast +hostname anycast.anytun.org: +-------------------------------------------------------------------------------------- +# anyrtpproxy -i anycast.anytun.org -p 20000 25000 -S 2342 \ + -M unicast2.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342 +-------------------------------------------------------------------------------------- + +On the host with unicast hostname unicast2.anycast.anytun.org and anycast +hostname anycast.anytun.org: +-------------------------------------------------------------------------------------- +# anyrtpproxy -i anycast.anytun.org -p 25000 30000 -S 2342 \ + -M unicast1.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342 +-------------------------------------------------------------------------------------- + +On the host with unicast hostname unicast3.anycast.anytun.org and anycast +hostname anycast.anytun.org: +-------------------------------------------------------------------------------------- +# anyrtpproxy -i anycast.anytun.org -p 30000 35000 -S 2342 \ + -M unicast1.anycast.anytun.org:2342,unicast2.anycast.anytun.org:2342 +-------------------------------------------------------------------------------------- + + + + +BUGS +---- +Most likely there are some bugs in *anyrtpproxy*. If you find a bug, please let +the developers know at satp@anytun.org. Of course, patches are preferred. + +SEE ALSO +-------- +anytun(8) + +AUTHORS +------- +Design of SATP and wizards of this implementation: + +Othmar Gsenger +Erwin Nindl +Christian Pointner + +Debian packaging: + +Andreas Hirczy + +Manual page: + +Alexander List + +RESOURCES +--------- + +Main web site: http://www.anytun.org/ + + +COPYING +------- + +Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian +Pointner. This program is free software; you can redistribute +it and/or modify it under the terms of the GNU General Public License +version 2 as published by the Free Software Foundation. + diff --git a/src/man/anytun-config.8.txt b/src/man/anytun-config.8.txt new file mode 100644 index 0000000..8eb2839 --- /dev/null +++ b/src/man/anytun-config.8.txt @@ -0,0 +1,217 @@ +anytun-config(8) +================ + +NAME +---- +anytun-config - anycast tunneling configuration utility + +SYNOPSIS +-------- + +*anytun-config* +[ *-h|--help* ] +[ *-L|--log* :[,[,[..]]] +[ *-r|--remote-host* ] +[ *-o|--remote-port* ] +[ *-4|--ipv4-only* ] +[ *-6|--ipv6-only* ] +[ *-R|--route* / ] +[ *-m|--mux* ] +[ *-w|--window-size* ] +[ *-k|--kd-prf* ] +[ *-e|--role * ] +[ *-E|--passphrase* ] +[ *-K|--key* ] +[ *-A|--salt* ] + +DESCRIPTION +----------- + +*anytun-config* writes routing/connection table entries, that can be read by *anytun-controld*. + +OPTIONS +------- + +-L|--log :[,[,[..]]] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +add log target to logging system. This can be invoked several times +in order to log to different targets at the same time. Every target +hast its own log level which is a number between 0 and 5. Where 0 means +disabling log and 5 means debug messages are enabled. + +The following targets are supported: + +* *syslog* - log to syslog daemon, parameters [,[,]] +* *file* - log to file, parameters [,] +* *stdout* - log to standard output, parameters +* *stderr* - log to standard error, parameters + +The file target can be used more the once with different levels. +If no target is provided at the command line a single target with the +following config is added: + +*syslog:3,uanytun,daemon* + +-r|--remote-host +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +remote host + +This option can be used to specify the remote tunnel +endpoint. In case of anycast tunnel endpoints, the +anycast IP address has to be used. If you do not specify +an address, it is automatically determined after receiving +the first data packet. + +-o|--remote-port +~~~~~~~~~~~~~~~~~~~~~~~ +remote port + +The UDP port used for payload data by the remote host +(specified with -p on the remote host). If you do not specify +a port, it is automatically determined after receiving +the first data packet. + +-4|--ipv4-only +~~~~~~~~~~~~~~ + +Resolv to IPv4 addresses only. The default is to resolv both +IPv4 and IPv6 addresses. + +-6|--ipv6-only +~~~~~~~~~~~~~~ + +Resolv to IPv6 addresses only. The default is to resolv both +IPv4 and IPv6 addresses. + +-R|--route / +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +add a route to connection. This can be invoked several times. + +-m|--mux +~~~~~~~~~~~~~~~~~ + +the multiplex id to use. default: 0 + +-w|--window-size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +seqence window size + +Sometimes, packets arrive out of order on the receiver +side. This option defines the size of a list of received +packets' sequence numbers. If, according to this list, +a received packet has been previously received or has +been transmitted in the past, and is therefore not in +the list anymore, this is interpreted as a replay attack +and the packet is dropped. A value of 0 deactivates this +list and, as a consequence, the replay protection employed +by filtering packets according to their secuence number. +By default the sequence window is disabled and therefore a +window size of 0 is used. + +-k|--kd--prf +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +key derivation pseudo random function. + +The pseudo random function which is used for calculating the +session keys and session salt. + +Possible values: + +* *null* - no random function, keys and salt are set to 0..00 +* *aes-ctr* - AES in counter mode with 128 Bits, default value +* *aes-ctr-128* - AES in counter mode with 128 Bits +* *aes-ctr-192* - AES in counter mode with 192 Bits +* *aes-ctr-256* - AES in counter mode with 256 Bits + +-e|--role +~~~~~~~~~~~~~~~~ + +SATP uses different session keys for inbound and outbound traffic. The +role parameter is used to determine which keys to use for outbound or +inbound packets. On both sides of a vpn connection different roles have +to be used. Possible values are *left* and *right*. You may also use +*alice* or *server* as a replacement for *left* and *bob* or *client* as +a replacement for *right*. By default *left* is used. + +-E|--passphrase +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This passphrase is used to generate the master key and master salt. +For the master key the last n bits of the SHA256 digest of the +passphrase (where n is the length of the master key in bits) is used. +The master salt gets generated with the SHA1 digest. +You may force a specific key and or salt by using *--key* and *--salt*. + +-K|--key +~~~~~~~~~~~~~~~~~~~~~ + +master key to use for key derivation + +Master key in hexadecimal notation, eg +01a2b3c4d5e6f708a9b0cadbecfd0fa1, with a mandatory length +of 32, 48 or 64 characters (128, 192 or 256 bits). + +-A|--salt +~~~~~~~~~~~~~~~~~~~~~~~ + +master salt to use for key derivation + +Master salt in hexadecimal notation, eg +01a2b3c4d5e6f708a9b0cadbecfd, with a mandatory length +of 28 characters (14 bytes). + + +EXAMPLES +-------- + +Add a client with Connection ID (Mux) 12 and add 2 Routes to this client + +------------------------------------------------------------------------------------------------ +# anytun-config -w 0 -m 12 -K 0123456789ABCDEFFEDCBA9876543210 -A 0123456789ABCDDCBA9876543210 \ + -R 192.0.2.0/24 -R 192.168.1.1/32 -e server >> routingtable +------------------------------------------------------------------------------------------------ + +BUGS +---- +Most likely there are some bugs in *anytun*. If you find a bug, please let +the developers know at satp@anytun.org. Of course, patches are preferred. + +SEE ALSO +-------- +anytun(8), anytun-controld(8), anytun-showtables(8) + +AUTHORS +------- +Design of SATP and wizards of this implementation: + +Othmar Gsenger +Erwin Nindl +Christian Pointner + +Debian packaging: + +Andreas Hirczy + +Manual page: + +Alexander List + +RESOURCES +--------- + +Main web site: http://www.anytun.org/ + + +COPYING +------- + +Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian +Pointner. This program is free software; you can redistribute +it and/or modify it under the terms of the GNU General Public License +version 2 as published by the Free Software Foundation. + diff --git a/src/man/anytun-controld.8.txt b/src/man/anytun-controld.8.txt new file mode 100644 index 0000000..2b1c7a1 --- /dev/null +++ b/src/man/anytun-controld.8.txt @@ -0,0 +1,136 @@ +anytun-controld(8) +================== + +NAME +---- +anytun-controld - anycast tunneling control daemon + +SYNOPSIS +-------- + +*anytun-controld* +[ *-h|--help* ] +[ *-D|--nodaemonize* ] +[ *-u|--username* ] +[ *-g|--groupname* ] +[ *-C|--chroot* ] +[ *-P|--write-pid* ] +[ *-L|--log* :[,[,[..]]] ] +[ *-f|--file* ] +[ *-X|--control-host* < [:port>] | : > ] + +DESCRIPTION +----------- + +*anytun-controld* configures the multi-connection support for *anytun*. It reads a connection/routing table and outputs it via a tcp socket to all connected *anytun* servers. When the control daemon is restarted with a new connection/routing table all *anytun* servers automatically load the new configuration. Please make sure to protect that information as it contains the connection keys. + +OPTIONS +------- + +-D|--nodaemonize +~~~~~~~~~~~~~~~~ + +This option instructs *anytun* to run in foreground +instead of becoming a daemon which is the default. + +-u|--username +~~~~~~~~~~~~~~~~~~~~~~~~ + +run as this user. If no group is specified (*-g*) the default group of +the user is used. The default is to not drop privileges. + +-g|--groupname +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +run as this group. If no username is specified (*-u*) this gets ignored. +The default is to not drop privileges. + +-C|--chroot +~~~~~~~~~~~~~~~~~~ + +Instruct *anytun* to run in a chroot jail. The default is +to not run in chroot. + +-P|--write-pid +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instruct *anytun* to write it's pid to this file. The default is +to not create a pid file. + +-L|--log :[,[,[..]]] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +add log target to logging system. This can be invoked several times +in order to log to different targets at the same time. Every target +hast its own log level which is a number between 0 and 5. Where 0 means +disabling log and 5 means debug messages are enabled. + +The following targets are supported: + +* *syslog* - log to syslog daemon, parameters [,[,]] +* *file* - log to file, parameters [,] +* *stdout* - log to standard output, parameters +* *stderr* - log to standard error, parameters + +The file target can be used more the once with different levels. +If no target is provided at the command line a single target with the +following config is added: + +*syslog:3,uanytun,daemon* + +-f|--file +~~~~~~~~~~~~~~~~ + +The path to the file which holds the sync information. + +-X|--control-host < [:] | : > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The local ip address and or tcp port to bind to. Mind that if an +address is given the port can be omitted in which case port 2323 +is used. You can also specify to listen on an specific port but on +all interfaces by omitting the address. If you want to specify an +ipv6 address and a port you have to use [ and ] to seperate the address +from the port, eg.: [::1]:1234. If you want to use the default port +[ and ] can be omitted. default: 127.0.0.1:2323 + + +BUGS +---- +Most likely there are some bugs in *anytun*. If you find a bug, please let +the developers know at satp@anytun.org. Of course, patches are preferred. + +SEE ALSO +-------- +anytun(8), anytun-config(8), anytun-showtables(8) + +AUTHORS +------- +Design of SATP and wizards of this implementation: + +Othmar Gsenger +Erwin Nindl +Christian Pointner + +Debian packaging: + +Andreas Hirczy + +Manual page: + +Alexander List + +RESOURCES +--------- + +Main web site: http://www.anytun.org/ + + +COPYING +------- + +Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian +Pointner. This program is free software; you can redistribute +it and/or modify it under the terms of the GNU General Public License +version 2 as published by the Free Software Foundation. + diff --git a/src/man/anytun-showtables.8.txt b/src/man/anytun-showtables.8.txt new file mode 100644 index 0000000..9a04f26 --- /dev/null +++ b/src/man/anytun-showtables.8.txt @@ -0,0 +1,77 @@ +anytun-showtables(8) +==================== + +NAME +---- +anytun-showtables - anycast tunneling routing table visualization utility + +SYNOPSIS +-------- + +*anytun-showtables* + +DESCRIPTION +----------- + +*anytun-showtables* displays routing and connection tables used by *anytun*. It can be used to display a saved routing/connection table used by *anytun-controld* or to connect to a the sync port of *anytun*. + +OPTIONS +------- + +This Tool does not take any options. It takes the sync information from +the standard input and prints the routing table to the standard output. + +EXAMPLES +-------- + +Print routing table stored in local file + +----------------------------------------------------------------------------------- +# perl -ne 'chomp; print' < routingtable | ./anytun-showtables +----------------------------------------------------------------------------------- + +Print current routing table and watch changes + +----------------------------------------------------------------------------------- +# nc unicast1.anycast.anytun.org 23 | ./anytun-showtables +----------------------------------------------------------------------------------- + +BUGS +---- +Most likely there are some bugs in *anytun*. If you find a bug, please let +the developers know at satp@anytun.org. Of course, patches are preferred. + +SEE ALSO +-------- +anytun(8), anytun-controld(8), anytun-config(8) + +AUTHORS +------- +Design of SATP and wizards of this implementation: + +Othmar Gsenger +Erwin Nindl +Christian Pointner + +Debian packaging: + +Andreas Hirczy + +Manual page: + +Alexander List + +RESOURCES +--------- + +Main web site: http://www.anytun.org/ + + +COPYING +------- + +Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian +Pointner. This program is free software; you can redistribute +it and/or modify it under the terms of the GNU General Public License +version 2 as published by the Free Software Foundation. + diff --git a/src/man/anytun.8.txt b/src/man/anytun.8.txt new file mode 100644 index 0000000..fa30441 --- /dev/null +++ b/src/man/anytun.8.txt @@ -0,0 +1,468 @@ +anytun(8) +========= + +NAME +---- +anytun - anycast tunneling daemon + +SYNOPSIS +-------- + +*anytun* +[ *-h|--help* ] +[ *-D|--nodaemonize* ] +[ *-u|--username* ] +[ *-g|--groupname* ] +[ *-C|--chroot* ] +[ *-P|--write-pid* ] +[ *-L|--log* :[,[,[..]]] ] +[ *-i|--interface* ] +[ *-p|--port* ] +[ *-r|--remote-host* ] +[ *-o|--remote-port* ] +[ *-4|--ipv4-only* ] +[ *-6|--ipv6-only* ] +[ *-I|--sync-interface* ] +[ *-S|--sync-port* port> ] +[ *-M|--sync-hosts* [:][,[:][...]] ] +[ *-X|--control-host* [:] +[ *-d|--dev* ] +[ *-t|--type* ] +[ *-n|--ifconfig* / ] +[ *-x|--post-up-script*