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
35 #include <cerrno> // for ENOMEM
37 #include "datatypes.h"
41 #include "plainPacket.h"
42 #include "encryptedPacket.h"
44 #include "keyDerivation.h"
47 #include "cipherFactory.h"
48 #include "authAlgoFactory.h"
49 #include "signalController.h"
50 #include "packetSource.h"
51 #include "tunDevice.h"
53 #include "seqWindow.h"
54 #include "connectionList.h"
56 #include "mpi.h" // TODO: remove after debug
59 #include "syncQueue.h"
60 #include "syncSocketHandler.h"
61 #include "syncListenSocket.h"
63 #include "syncSocket.h"
64 #include "syncClientSocket.h"
65 #include "syncCommand.h"
67 #include "threadParam.h"
69 #define PAYLOAD_TYPE_TAP 0x6558
70 #define PAYLOAD_TYPE_TUN 0x0800
72 #define MAX_PACKET_LENGTH 1600
74 #define SESSION_KEYLEN_AUTH 20 // TODO: hardcoded size
75 #define SESSION_KEYLEN_ENCR 16 // TODO: hardcoded size
76 #define SESSION_KEYLEN_SALT 14 // TODO: hardcoded size
78 void createConnection(const std::string
& remote_host
, u_int16_t remote_port
, ConnectionList
& cl
, u_int16_t seqSize
, SyncQueue
& queue
)
81 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
82 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'
86 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
87 'i', 'j', 'k', 'l', 'm', 'n'
90 SeqWindow
* seq
= new SeqWindow(seqSize
);
92 KeyDerivation
* kd
= new KeyDerivation
;
93 kd
->init(Buffer(key
, sizeof(key
)), Buffer(salt
, sizeof(salt
)));
95 cLog
.msg(Log::PRIO_NOTICE
) << "added connection remote host " << remote_host
<< ":" << remote_port
;
96 ConnectionParam
connparam ( (*kd
), (*seq
), seq_nr_
, remote_host
, remote_port
);
97 cl
.addConnection(connparam
,0);
98 SyncCommand
sc (cl
,0);
103 void addPacketAuthTag(EncryptedPacket
& pack
, AuthAlgo
* a
, ConnectionParam
& conn
)
105 AuthTag at
= a
->calc(pack
);
106 pack
.setAuthTag( at
);
109 bool checkPacketAuthTag(EncryptedPacket
& pack
, AuthAlgo
* a
, ConnectionParam
& conn
)
111 // check auth_tag and remove it
112 AuthTag at
= pack
.getAuthTag();
113 return (at
== a
->calc(pack
));
116 bool checkPacketSeqNr(EncryptedPacket
& pack
,ConnectionParam
& conn
)
118 // compare sender_id and seq with window
119 if(conn
.seq_window_
.hasSeqNr(pack
.getSenderId(), pack
.getSeqNr()))
121 cLog
.msg(Log::PRIO_NOTICE
) << "Replay attack from " << conn
.remote_host_
<<":"<< conn
.remote_port_
122 << " seq:"<<pack
.getSeqNr() << " sid: "<<pack
.getSenderId();
126 conn
.seq_window_
.addSeqNr(pack
.getSenderId(), pack
.getSeqNr());
130 void* sender(void* p
)
132 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
134 std::auto_ptr
<Cipher
> c(CipherFactory::create(param
->opt
.getCipher()));
135 // std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(param->opt.getAuthAlgo()) );
137 PlainPacket
plain_packet(MAX_PACKET_LENGTH
);
138 EncryptedPacket
encrypted_packet(MAX_PACKET_LENGTH
);
140 Buffer
session_key(u_int32_t(SESSION_KEYLEN_ENCR
)); // TODO: hardcoded size
141 Buffer
session_salt(u_int32_t(SESSION_KEYLEN_SALT
)); // TODO: hardcoded size
142 Buffer
session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH
)); // TODO: hardcoded size
148 plain_packet
.setLength(MAX_PACKET_LENGTH
);
149 encrypted_packet
.setLength(MAX_PACKET_LENGTH
);
150 // read packet from device
151 u_int32_t len
= param
->dev
.read(plain_packet
.getPayload(), plain_packet
.getPayloadLength());
152 plain_packet
.setLength(len
);
154 std::cout
<< "plain_packet.getPayloadLength() = " << plain_packet
.getPayloadLength() << std::endl
;
156 if(param
->cl
.empty())
159 ConnectionMap::iterator cit
= param
->cl
.getConnection(mux
);
160 if(cit
==param
->cl
.getEnd())
162 ConnectionParam
& conn
= cit
->second
;
165 if(param
->dev
.getType() == TunDevice::TYPE_TUN
)
166 plain_packet
.setPayloadType(PAYLOAD_TYPE_TUN
);
167 else if(param
->dev
.getType() == TunDevice::TYPE_TAP
)
168 plain_packet
.setPayloadType(PAYLOAD_TYPE_TAP
);
170 plain_packet
.setPayloadType(0);
172 // generate packet-key
173 conn
.kd_
.generate(LABEL_SATP_ENCRYPTION
, conn
.seq_nr_
, session_key
);
174 conn
.kd_
.generate(LABEL_SATP_SALT
, conn
.seq_nr_
, session_salt
);
176 std::cout
<< "session_key: ";
177 std::cout
<< session_key
.getHexDump();
178 std::cout
<< "session_salt: ";
179 std::cout
<< session_salt
.getHexDump() << std::endl
;
182 c
->setKey(session_key
);
183 c
->setSalt(session_salt
);
186 c
->encrypt(plain_packet
, encrypted_packet
, conn
.seq_nr_
, param
->opt
.getSenderId());
188 encrypted_packet
.setHeader(conn
.seq_nr_
, param
->opt
.getSenderId(), mux
);
191 // TODO: activate authentication
192 // conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
193 // a->setKey(session_auth_key);
194 // addPacketAuthTag(encrypted_packet, a.get(), conn);
196 std::cout
<< "encrypted_packet.getLength() = " << encrypted_packet
.getLength() << std::endl
<< std::endl
;
198 param
->src
.send(encrypted_packet
.getBuf(), encrypted_packet
.getLength(), conn
.remote_host_
, conn
.remote_port_
);
203 void* syncConnector(void* p
)
205 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
208 SyncClientSocket
sock(h
,param
->cl
);
210 sock
.Open( param
->connto
.host
, param
->connto
.port
);
219 void* syncListener(void* p
)
221 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
223 SyncSocketHandler
h(param
->queue
);
224 SyncListenSocket
<SyncSocket
,ConnectionList
> l(h
,param
->cl
);
226 if (l
.Bind(param
->opt
.getLocalSyncPort()))
229 Utility::ResolveLocal(); // resolve local hostname
237 void* receiver(void* p
)
239 ThreadParam
* param
= reinterpret_cast<ThreadParam
*>(p
);
241 std::auto_ptr
<Cipher
> c( CipherFactory::create(param
->opt
.getCipher()) );
242 // std::auto_ptr<AuthAlgo> a( AuthAlgoFactory::create(param->opt.getAuthAlgo()) );
244 EncryptedPacket
encrypted_packet(MAX_PACKET_LENGTH
);
245 PlainPacket
plain_packet(MAX_PACKET_LENGTH
);
247 Buffer
session_key(u_int32_t(SESSION_KEYLEN_ENCR
)); // TODO: hardcoded size
248 Buffer
session_salt(u_int32_t(SESSION_KEYLEN_SALT
)); // TODO: hardcoded size
249 Buffer
session_auth_key(u_int32_t(SESSION_KEYLEN_AUTH
)); // TODO: hardcoded size
254 u_int16_t remote_port
;
256 plain_packet
.setLength(MAX_PACKET_LENGTH
);
257 encrypted_packet
.setLength(MAX_PACKET_LENGTH
);
259 // read packet from socket
260 u_int32_t len
= param
->src
.recv(encrypted_packet
.getBuf(), encrypted_packet
.getLength(), remote_host
, remote_port
);
261 encrypted_packet
.setLength(len
);
263 // TODO: check auth tag first
264 // conn.kd_.generate(LABEL_SATP_MSG_AUTH, encrypted_packet.getSeqNr(), session_auth_key);
265 // a->setKey( session_auth_key );
266 // if(!checkPacketAuthTag(encrypted_packet, a.get(), conn))
271 if(param
->opt
.getRemoteAddr() == "" && param
->cl
.empty())
273 cLog
.msg(Log::PRIO_NOTICE
) << "autodetected remote host " << remote_host
<< ":" << remote_port
;
274 createConnection(remote_host
, remote_port
, param
->cl
,param
->opt
.getSeqWindowSize(),param
->queue
);
277 // TODO: Add multi connection support here
278 ConnectionParam
& conn
= param
->cl
.getConnection(0)->second
;
280 //Allow dynamic IP changes
281 //TODO: add command line option to turn this off
282 if (remote_host
!= conn
.remote_host_
|| remote_port
!= conn
.remote_port_
)
284 cLog
.msg(Log::PRIO_NOTICE
) << "autodetected remote host ip changed " << remote_host
<< ":" << remote_port
;
285 conn
.remote_host_
=remote_host
;
286 conn
.remote_port_
=remote_port
;
287 SyncCommand
sc (param
->cl
,0);
288 param
->queue
.push(sc
);
292 if (!checkPacketSeqNr(encrypted_packet
, conn
))
295 // generate packet-key
296 conn
.kd_
.generate(LABEL_SATP_ENCRYPTION
, encrypted_packet
.getSeqNr(), session_key
);
297 conn
.kd_
.generate(LABEL_SATP_SALT
, encrypted_packet
.getSeqNr(), session_salt
);
298 c
->setKey(session_key
);
299 c
->setSalt(session_salt
);
302 c
->decrypt(encrypted_packet
, plain_packet
);
304 // check payload_type
305 if((param
->dev
.getType() == TunDevice::TYPE_TUN
&& plain_packet
.getPayloadType() != PAYLOAD_TYPE_TUN
) ||
306 (param
->dev
.getType() == TunDevice::TYPE_TAP
&& plain_packet
.getPayloadType() != PAYLOAD_TYPE_TAP
))
309 // write it on the device
310 param
->dev
.write(plain_packet
.getPayload(), plain_packet
.getLength());
315 #define MIN_GCRYPT_VERSION "1.2.3"
316 //#define GCRYPT_SEC_MEM 32768 // 32k secure memory
317 // make libgcrypt thread safe
319 GCRY_THREAD_OPTION_PTHREAD_IMPL
;
324 // make libgcrypt thread safe
325 // this must be called before any other libgcrypt call
326 gcry_control( GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pthread
);
328 // this must be called right after the GCRYCTL_SET_THREAD_CBS command
329 // no other function must be called till now
330 if( !gcry_check_version( MIN_GCRYPT_VERSION
) ) {
331 std::cout
<< "initLibGCrypt: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION
<< std::endl
;
335 // Tell Libgcrypt that initialization has completed.
336 gcry_error_t err
= gcry_control(GCRYCTL_INITIALIZATION_FINISHED
);
338 std::cout
<< "initLibGCrypt: Failed to finish the initialization of libgcrypt: " << gpg_strerror( err
) << std::endl
;
342 cLog
.msg(Log::PRIO_NOTICE
) << "initLibGCrypt: libgcrypt init finished";
346 int main(int argc
, char* argv
[])
348 std::cout
<< "anytun - secure anycast tunneling protocol" << std::endl
;
350 if(!opt
.parse(argc
, argv
))
355 cLog
.msg(Log::PRIO_NOTICE
) << "anytun started...";
357 SignalController sig
;
359 std::string
dev_type(opt
.getDevType());
360 TunDevice
dev(opt
.getDevName().c_str(), dev_type
=="" ? NULL
: dev_type
.c_str(), opt
.getIfconfigParamLocal().c_str(), opt
.getIfconfigParamRemoteNetmask().c_str());
363 if(opt
.getLocalAddr() == "")
364 src
= new UDPPacketSource(opt
.getLocalPort());
366 src
= new UDPPacketSource(opt
.getLocalAddr(), opt
.getLocalPort());
369 ConnectToList connect_to
= opt
.getConnectTo();
372 if(opt
.getRemoteAddr() != "")
373 createConnection(opt
.getRemoteAddr(),opt
.getRemotePort(),cl
,opt
.getSeqWindowSize(), queue
);
375 ThreadParam
p(opt
, dev
, *src
, cl
, queue
,*(new OptionConnectTo()));
377 cLog
.msg(Log::PRIO_NOTICE
) << "dev created (opened)";
378 cLog
.msg(Log::PRIO_NOTICE
) << "dev opened - actual name is '" << p
.dev
.getActualName() << "'";
379 cLog
.msg(Log::PRIO_NOTICE
) << "dev type is '" << p
.dev
.getTypeString() << "'";
381 // this must be called before any other libgcrypt call
385 pthread_t senderThread
;
386 pthread_create(&senderThread
, NULL
, sender
, &p
);
387 pthread_t receiverThread
;
388 pthread_create(&receiverThread
, NULL
, receiver
, &p
);
390 pthread_t syncListenerThread
;
391 if ( opt
.getLocalSyncPort())
392 pthread_create(&syncListenerThread
, NULL
, syncListener
, &p
);
394 std::list
<pthread_t
> connectThreads
;
395 for(ConnectToList::iterator it
= connect_to
.begin() ;it
!= connect_to
.end(); ++it
)
397 connectThreads
.push_back(pthread_t());
398 ThreadParam
* point
= new ThreadParam(opt
, dev
, *src
, cl
, queue
,*it
);
399 pthread_create(& connectThreads
.back(), NULL
, syncConnector
, point
);
404 pthread_cancel(senderThread
);
405 pthread_cancel(receiverThread
);
406 if ( opt
.getLocalSyncPort())
407 pthread_cancel(syncListenerThread
);
408 for( std::list
<pthread_t
>::iterator it
= connectThreads
.begin() ;it
!= connectThreads
.end(); ++it
)
411 pthread_join(senderThread
, NULL
);
412 pthread_join(receiverThread
, NULL
);
413 if ( opt
.getLocalSyncPort())
414 pthread_join(syncListenerThread
, NULL
);
416 for( std::list
<pthread_t
>::iterator it
= connectThreads
.begin() ;it
!= connectThreads
.end(); ++it
)
417 pthread_join(*it
, NULL
);