4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program (see the file COPYING included with this
27 * distribution); if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 #include <cerrno> // for ENOMEM
42 #include "datatypes.h"
46 #include "plainPacket.h"
47 #include "encryptedPacket.h"
49 #include "keyDerivation.h"
51 #include "cipherFactory.h"
52 #include "authAlgoFactory.h"
53 #include "keyDerivationFactory.h"
54 #include "signalController.h"
55 #include "packetSource.h"
56 #include "tunDevice.h"
58 #include "seqWindow.h"
59 #include "connectionList.h"
60 #include "routingTable.h"
61 #include "networkAddress.h"
63 #include "syncQueue.h"
64 #include "syncSocketHandler.h"
65 #include "syncListenSocket.h"
67 #include "syncSocket.h"
68 #include "syncClientSocket.h"
69 #include "syncCommand.h"
71 #include "threadParam.h"
73 #define MAX_PACKET_LENGTH 1600
75 #define SESSION_KEYLEN_AUTH 20 // TODO: hardcoded size
76 #define SESSION_KEYLEN_ENCR 16 // TODO: hardcoded size
77 #define SESSION_KEYLEN_SALT 14 // TODO: hardcoded size
79 void createConnection(const std::string
& remote_host
, u_int16_t remote_port
, ConnectionList
& cl
, u_int16_t seqSize
, SyncQueue
& queue
, mux_t mux
)
81 SeqWindow
* seq
= new SeqWindow(seqSize
);
83 KeyDerivation
* kd
= KeyDerivationFactory::create(gOpt
.getKdPrf());
84 kd
->init(gOpt
.getKey(), gOpt
.getSalt());
85 cLog
.msg(Log::PRIO_NOTICE
) << "added connection remote host " << remote_host
<< ":" << remote_port
;
86 ConnectionParam
connparam ( (*kd
), (*seq
), seq_nr_
, remote_host
, remote_port
);
87 cl
.addConnection(connparam
,mux
);
88 NetworkAddress
addr(ipv4
,gOpt
.getIfconfigParamRemoteNetmask().c_str());
89 NetworkPrefix
prefix(addr
,32);
90 gRoutingTable
.addRoute(prefix
,mux
);
91 SyncCommand
sc (cl
,mux
);
93 SyncCommand
sc2 (prefix
);
97 bool checkPacketSeqNr(EncryptedPacket
& pack
,ConnectionParam
& conn
)
99 // compare sender_id and seq with window
100 if(conn
.seq_window_
.hasSeqNr(pack
.getSenderId(), pack
.getSeqNr()))
102 cLog
.msg(Log::PRIO_NOTICE
) << "Replay attack from " << conn
.remote_host_
<<":"<< conn
.remote_port_
103 << " seq:"<<pack
.getSeqNr() << " sid: "<<pack
.getSenderId();
107 conn
.seq_window_
.addSeqNr(pack
.getSenderId(), pack
.getSeqNr());
111 void* sender(void* p
)
113 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
115 std::auto_ptr
<Cipher
> c(CipherFactory::create(gOpt
.getCipher()));
116 std::auto_ptr
<AuthAlgo
> a(AuthAlgoFactory::create(gOpt
.getAuthAlgo()) );
118 PlainPacket
plain_packet(MAX_PACKET_LENGTH
);
119 EncryptedPacket
encrypted_packet(MAX_PACKET_LENGTH
);
121 Buffer
session_key(u_int32_t(SESSION_KEYLEN_ENCR
)); // TODO: hardcoded size
122 Buffer
session_salt(u_int32_t(SESSION_KEYLEN_SALT
)); // TODO: hardcoded size
123 Buffer
session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH
)); // TODO: hardcoded size
126 u_int16_t mux
= gOpt
.getMux();
129 plain_packet
.setLength(MAX_PACKET_LENGTH
);
130 encrypted_packet
.withAuthTag(false);
131 encrypted_packet
.setLength(MAX_PACKET_LENGTH
);
133 // read packet from device
134 u_int32_t len
= param
->dev
.read(plain_packet
.getPayload(), plain_packet
.getPayloadLength());
135 plain_packet
.setPayloadLength(len
);
137 if(param
->dev
.getType() == TunDevice::TYPE_TUN
)
138 plain_packet
.setPayloadType(PAYLOAD_TYPE_TUN
);
139 else if(param
->dev
.getType() == TunDevice::TYPE_TAP
)
140 plain_packet
.setPayloadType(PAYLOAD_TYPE_TAP
);
142 plain_packet
.setPayloadType(0);
144 if(param
->cl
.empty())
146 //std::cout << "got Packet for plain "<<plain_packet.getDstAddr().toString();
147 mux
= gRoutingTable
.getRoute(plain_packet
.getDstAddr());
148 //std::cout << " -> "<<mux << std::endl;
149 ConnectionMap::iterator cit
= param
->cl
.getConnection(mux
);
150 if(cit
==param
->cl
.getEnd())
152 ConnectionParam
& conn
= cit
->second
;
154 if(conn
.remote_host_
==""||!conn
.remote_port_
)
156 // generate packet-key TODO: do this only when needed
157 conn
.kd_
.generate(LABEL_SATP_ENCRYPTION
, conn
.seq_nr_
, session_key
);
158 conn
.kd_
.generate(LABEL_SATP_SALT
, conn
.seq_nr_
, session_salt
);
160 c
->setKey(session_key
);
161 c
->setSalt(session_salt
);
164 c
->encrypt(plain_packet
, encrypted_packet
, conn
.seq_nr_
, gOpt
.getSenderId(), mux
);
166 encrypted_packet
.setHeader(conn
.seq_nr_
, gOpt
.getSenderId(), mux
);
169 // add authentication tag
170 if(a
->getMaxLength()) {
171 encrypted_packet
.addAuthTag();
172 conn
.kd_
.generate(LABEL_SATP_MSG_AUTH
, encrypted_packet
.getSeqNr(), session_auth_key
);
173 a
->setKey(session_auth_key
);
174 a
->generate(encrypted_packet
);
178 param
->src
.send(encrypted_packet
.getBuf(), encrypted_packet
.getLength(), conn
.remote_host_
, conn
.remote_port_
);
187 void* syncConnector(void* p
)
189 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
192 SyncClientSocket
sock(h
,param
->cl
);
194 sock
.Open( param
->connto
.host
, param
->connto
.port
);
203 void* syncListener(void* p
)
205 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
207 SyncSocketHandler
h(param
->queue
);
208 SyncListenSocket
<SyncSocket
,ConnectionList
> l(h
,param
->cl
);
210 if (l
.Bind(gOpt
.getLocalSyncPort()))
213 Utility::ResolveLocal(); // resolve local hostname
221 void* receiver(void* p
)
223 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
225 std::auto_ptr
<Cipher
> c( CipherFactory::create(gOpt
.getCipher()) );
226 std::auto_ptr
<AuthAlgo
> a( AuthAlgoFactory::create(gOpt
.getAuthAlgo()) );
228 EncryptedPacket
encrypted_packet(MAX_PACKET_LENGTH
);
229 PlainPacket
plain_packet(MAX_PACKET_LENGTH
);
231 Buffer
session_key(u_int32_t(SESSION_KEYLEN_ENCR
)); // TODO: hardcoded size
232 Buffer
session_salt(u_int32_t(SESSION_KEYLEN_SALT
)); // TODO: hardcoded size
233 Buffer
session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH
)); // TODO: hardcoded size
238 u_int16_t remote_port
;
240 plain_packet
.setLength(MAX_PACKET_LENGTH
);
241 encrypted_packet
.withAuthTag(false);
242 encrypted_packet
.setLength(MAX_PACKET_LENGTH
);
244 // read packet from socket
245 u_int32_t len
= param
->src
.recv(encrypted_packet
.getBuf(), encrypted_packet
.getLength(), remote_host
, remote_port
);
246 encrypted_packet
.setLength(len
);
248 mux_t mux
= encrypted_packet
.getMux();
250 if(gOpt
.getRemoteAddr() == "" && param
->cl
.empty())
252 cLog
.msg(Log::PRIO_NOTICE
) << "autodetected remote host " << remote_host
<< ":" << remote_port
;
253 createConnection(remote_host
, remote_port
, param
->cl
, gOpt
.getSeqWindowSize(),param
->queue
,mux
);
256 ConnectionMap::iterator cit
= param
->cl
.getConnection(mux
);
257 if (cit
== param
->cl
.getEnd())
259 ConnectionParam
& conn
= cit
->second
;
261 // check whether auth tag is ok or not
262 if(a
->getMaxLength()) {
263 encrypted_packet
.withAuthTag(true);
264 conn
.kd_
.generate(LABEL_SATP_MSG_AUTH
, encrypted_packet
.getSeqNr(), session_auth_key
);
265 a
->setKey(session_auth_key
);
266 if(!a
->checkTag(encrypted_packet
)) {
267 cLog
.msg(Log::PRIO_NOTICE
) << "wrong Authentication Tag!" << std::endl
;
270 encrypted_packet
.removeAuthTag();
273 //Allow dynamic IP changes
274 //TODO: add command line option to turn this off
275 if (remote_host
!= conn
.remote_host_
|| remote_port
!= conn
.remote_port_
)
277 cLog
.msg(Log::PRIO_NOTICE
) << "connection "<< mux
<< " autodetected remote host ip changed " << remote_host
<< ":" << remote_port
;
278 conn
.remote_host_
=remote_host
;
279 conn
.remote_port_
=remote_port
;
280 SyncCommand
sc (param
->cl
,mux
);
281 param
->queue
.push(sc
);
285 if (!checkPacketSeqNr(encrypted_packet
, conn
))
288 // generate packet-key
289 conn
.kd_
.generate(LABEL_SATP_ENCRYPTION
, encrypted_packet
.getSeqNr(), session_key
);
290 conn
.kd_
.generate(LABEL_SATP_SALT
, encrypted_packet
.getSeqNr(), session_salt
);
291 c
->setKey(session_key
);
292 c
->setSalt(session_salt
);
295 c
->decrypt(encrypted_packet
, plain_packet
);
297 // check payload_type
298 if((param
->dev
.getType() == TunDevice::TYPE_TUN
&& plain_packet
.getPayloadType() != PAYLOAD_TYPE_TUN4
&&
299 plain_packet
.getPayloadType() != PAYLOAD_TYPE_TUN6
) ||
300 (param
->dev
.getType() == TunDevice::TYPE_TAP
&& plain_packet
.getPayloadType() != PAYLOAD_TYPE_TAP
))
303 // write it on the device
304 param
->dev
.write(plain_packet
.getPayload(), plain_packet
.getLength());
309 #define MIN_GCRYPT_VERSION "1.2.0"
310 // make libgcrypt thread safe
312 GCRY_THREAD_OPTION_PTHREAD_IMPL
;
317 // make libgcrypt thread safe
318 // this must be called before any other libgcrypt call
319 gcry_control( GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pthread
);
321 // this must be called right after the GCRYCTL_SET_THREAD_CBS command
322 // no other function must be called till now
323 if( !gcry_check_version( MIN_GCRYPT_VERSION
) ) {
324 std::cout
<< "initLibGCrypt: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION
<< std::endl
;
328 gcry_error_t err
= gcry_control (GCRYCTL_DISABLE_SECMEM
, 0);
330 std::cout
<< "initLibGCrypt: Failed to disable secure memory: " << gpg_strerror( err
) << std::endl
;
334 // Tell Libgcrypt that initialization has completed.
335 err
= gcry_control(GCRYCTL_INITIALIZATION_FINISHED
);
337 std::cout
<< "initLibGCrypt: Failed to finish the initialization of libgcrypt: " << gpg_strerror( err
) << std::endl
;
341 cLog
.msg(Log::PRIO_NOTICE
) << "initLibGCrypt: libgcrypt init finished";
345 void chrootAndDrop(std::string
const& chrootdir
, std::string
const& username
)
349 std::cerr
<< "this programm has to be run as root in order to run in a chroot" << std::endl
;
353 struct passwd
*pw
= getpwnam(username
.c_str());
355 if(chroot(chrootdir
.c_str()))
357 std::cerr
<< "can't chroot to " << chrootdir
<< std::endl
;
360 cLog
.msg(Log::PRIO_NOTICE
) << "we are in chroot jail (" << chrootdir
<< ") now" << std::endl
;
362 if (initgroups(pw
->pw_name
, pw
->pw_gid
) || setgid(pw
->pw_gid
) || setuid(pw
->pw_uid
))
364 std::cerr
<< "can't drop to user " << username
<< " " << pw
->pw_uid
<< ":" << pw
->pw_gid
<< std::endl
;
367 cLog
.msg(Log::PRIO_NOTICE
) << "dropped user to " << username
<< " " << pw
->pw_uid
<< ":" << pw
->pw_gid
<< std::endl
;
371 std::cerr
<< "unknown user " << username
<< std::endl
;
386 // std::cout << "running in background now..." << std::endl;
389 // for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
390 for (fd
=0;fd
<=2;fd
++) // close all file descriptors
392 fd
=open("/dev/null",O_RDWR
); // stdin
398 int execScript(string
const& script
, string
const& ifname
)
404 for (fd
=getdtablesize();fd
>=0;--fd
) // close all file descriptors
406 fd
=open("/dev/null",O_RDWR
); // stdin
409 return execl("/bin/sh", "/bin/sh", script
.c_str(), ifname
.c_str(), NULL
);
412 waitpid(pid
, &status
, 0);
416 int main(int argc
, char* argv
[])
418 // std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
419 if(!gOpt
.parse(argc
, argv
)) {
424 cLog
.msg(Log::PRIO_NOTICE
) << "anytun started...";
426 std::ofstream pidFile
;
427 if(gOpt
.getPidFile() != "") {
428 pidFile
.open(gOpt
.getPidFile().c_str());
429 if(!pidFile
.is_open()) {
430 std::cout
<< "can't open pid file" << std::endl
;
434 std::string
dev_type(gOpt
.getDevType());
435 TunDevice
dev(gOpt
.getDevName().c_str(), dev_type
=="" ? NULL
: dev_type
.c_str(),
436 gOpt
.getIfconfigParamLocal() =="" ? NULL
: gOpt
.getIfconfigParamLocal().c_str(),
437 gOpt
.getIfconfigParamRemoteNetmask() =="" ? NULL
: gOpt
.getIfconfigParamRemoteNetmask().c_str());
438 cLog
.msg(Log::PRIO_NOTICE
) << "dev created (opened)";
439 cLog
.msg(Log::PRIO_NOTICE
) << "dev opened - actual name is '" << dev
.getActualName() << "'";
440 cLog
.msg(Log::PRIO_NOTICE
) << "dev type is '" << dev
.getTypeString() << "'";
441 if(gOpt
.getPostUpScript() != "") {
442 int postup_ret
= execScript(gOpt
.getPostUpScript(), dev
.getActualName());
443 cLog
.msg(Log::PRIO_NOTICE
) << "post up script '" << gOpt
.getPostUpScript() << "' returned " << postup_ret
;
447 chrootAndDrop(gOpt
.getChrootDir(), gOpt
.getUsername());
448 if(gOpt
.getDaemonize())
451 if(pidFile
.is_open()) {
452 pid_t pid
= getpid();
457 SignalController sig
;
461 if(gOpt
.getLocalAddr() == "")
462 src
= new UDPPacketSource(gOpt
.getLocalPort());
464 src
= new UDPPacketSource(gOpt
.getLocalAddr(), gOpt
.getLocalPort());
467 ConnectToList connect_to
= gOpt
.getConnectTo();
470 if(gOpt
.getRemoteAddr() != "")
471 createConnection(gOpt
.getRemoteAddr(),gOpt
.getRemotePort(),cl
,gOpt
.getSeqWindowSize(), queue
, gOpt
.getMux());
473 ThreadParam
p(dev
, *src
, cl
, queue
,*(new OptionConnectTo()));
475 // this must be called before any other libgcrypt call
479 pthread_t senderThread
;
480 pthread_create(&senderThread
, NULL
, sender
, &p
);
481 pthread_t receiverThread
;
482 pthread_create(&receiverThread
, NULL
, receiver
, &p
);
484 pthread_t syncListenerThread
;
485 if ( gOpt
.getLocalSyncPort())
486 pthread_create(&syncListenerThread
, NULL
, syncListener
, &p
);
488 std::list
<pthread_t
> connectThreads
;
489 for(ConnectToList::iterator it
= connect_to
.begin() ;it
!= connect_to
.end(); ++it
) {
490 connectThreads
.push_back(pthread_t());
491 ThreadParam
* point
= new ThreadParam(dev
, *src
, cl
, queue
,*it
);
492 pthread_create(& connectThreads
.back(), NULL
, syncConnector
, point
);
497 pthread_cancel(senderThread
);
498 pthread_cancel(receiverThread
);
499 if ( gOpt
.getLocalSyncPort())
500 pthread_cancel(syncListenerThread
);
501 for( std::list
<pthread_t
>::iterator it
= connectThreads
.begin() ;it
!= connectThreads
.end(); ++it
)
504 pthread_join(senderThread
, NULL
);
505 pthread_join(receiverThread
, NULL
);
506 if ( gOpt
.getLocalSyncPort())
507 pthread_join(syncListenerThread
, NULL
);
509 for( std::list
<pthread_t
>::iterator it
= connectThreads
.begin() ;it
!= connectThreads
.end(); ++it
)
510 pthread_join(*it
, NULL
);