Imported Upstream version 0.3.5
[anytun.git] / src / anytun.cpp
1 /*
2  *  anytun
3  *
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 methods 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.
12  *
13  *
14  *  Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl,
15  *                          Christian Pointner <satp@wirdorange.org>
16  *
17  *  This file is part of Anytun.
18  *
19  *  Anytun is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License as published by
21  *  the Free Software Foundation, either version 3 of the License, or
22  *  any later version.
23  *
24  *  Anytun is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with Anytun.  If not, see <http://www.gnu.org/licenses/>.
31  *
32  *  In addition, as a special exception, the copyright holders give
33  *  permission to link the code of portions of this program with the
34  *  OpenSSL library under certain conditions as described in each
35  *  individual source file, and distribute linked combinations
36  *  including the two.
37  *  You must obey the GNU General Public License in all respects
38  *  for all of the code used other than OpenSSL.  If you modify
39  *  file(s) with this exception, you may extend this exception to your
40  *  version of the file(s), but you are not obligated to do so.  If you
41  *  do not wish to do so, delete this exception statement from your
42  *  version.  If you delete this exception statement from all source
43  *  files in the program, then also delete it here.
44  */
45
46 #include <boost/bind.hpp>
47 #include <boost/thread.hpp>
48 #include <boost/assign.hpp>
49 #include <iostream>
50 #include <fstream>
51
52 #include "datatypes.h"
53
54 #include "log.h"
55 #include "resolver.h"
56 #include "buffer.h"
57 #include "plainPacket.h"
58 #include "encryptedPacket.h"
59 #include "cipher.h"
60 #include "keyDerivation.h"
61 #include "authAlgo.h"
62 #include "cipherFactory.h"
63 #include "authAlgoFactory.h"
64 #include "keyDerivationFactory.h"
65 #include "signalController.h"
66 #if !defined(_MSC_VER) && !defined(MINGW)
67 # include "daemonService.h"
68 #else
69 # ifdef WIN_SERVICE
70 #  include "win32/winService.h"
71 # else
72 #  include "nullDaemon.h"
73 # endif
74 #endif
75 #include "packetSource.h"
76 #include "tunDevice.h"
77 #include "options.h"
78 #include "seqWindow.h"
79 #include "connectionList.h"
80 #ifndef NO_ROUTING
81 #include "routingTable.h"
82 #include "networkAddress.h"
83 #endif
84
85 #ifndef ANYTUN_NOSYNC
86 #include "syncQueue.h"
87 #include "syncCommand.h"
88 #include "syncServer.h"
89 #include "syncClient.h"
90 #include "syncOnConnect.hpp"
91 #endif
92
93 #include "cryptinit.hpp"
94 #include "sysExec.h"
95
96 bool disableRouting = false;
97
98 void createConnection(const PacketSourceEndpoint& remote_end, window_size_t seqSize, mux_t mux)
99 {
100   SeqWindow* seq = new SeqWindow(seqSize);
101   seq_nr_t seq_nr_=0;
102   KeyDerivation* kd = KeyDerivationFactory::create(gOpt.getKdPrf());
103   kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase());
104   kd->setRole(gOpt.getRole());
105   cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end;
106
107   ConnectionParam connparam((*kd), (*seq), seq_nr_, remote_end);
108   gConnectionList.addConnection(connparam,mux);
109 #ifndef ANYTUN_NOSYNC
110   SyncCommand sc(gConnectionList,mux);
111   gSyncQueue.push(sc);
112 #endif
113 }
114
115 void createConnectionResolver(PacketSourceResolverIt& it, window_size_t seqSize, mux_t mux)
116 {
117   createConnection(*it, seqSize, mux);
118 }
119
120 void createConnectionError(const std::exception& e)
121 {
122   gSignalController.inject(SIGERROR, e.what());
123 }
124
125 #ifndef ANYTUN_NOSYNC
126 void syncConnector(const OptionHost& connto)
127 {
128   SyncClient sc(connto.addr, connto.port);
129   sc.run();
130 }
131
132 void syncListener()
133 {
134   try {
135     SyncServer server(gOpt.getLocalSyncAddr(), gOpt.getLocalSyncPort(), boost::bind(syncOnConnect, _1));
136     gSyncQueue.setSyncServerPtr(&server);
137     server.run();
138   } catch(std::runtime_error& e) {
139     cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what();
140   } catch(std::exception& e) {
141     cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what();
142   }
143 }
144 #endif
145
146 void sender(TunDevice* dev, PacketSource* src)
147 {
148   if(!dev || !src) {
149     cLog.msg(Log::PRIO_ERROR) << "sender thread died because either dev or src pointer is null";
150     return;
151   }
152
153   try {
154     std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher(), KD_OUTBOUND));
155     std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_OUTBOUND));
156
157     PlainPacket plain_packet(MAX_PACKET_LENGTH);
158     EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength());
159
160     uint16_t mux = gOpt.getMux();
161     PacketSourceEndpoint emptyEndpoint;
162     for(;;) {
163       plain_packet.setLength(MAX_PACKET_LENGTH);
164       encrypted_packet.withAuthTag(false);
165       encrypted_packet.setLength(MAX_PACKET_LENGTH);
166
167       // read packet from device
168       int len = dev->read(plain_packet.getPayload(), plain_packet.getPayloadLength());
169       if(len < 0) {
170         continue;  // silently ignore device read errors, this is probably no good idea...
171       }
172
173       if(static_cast<uint32_t>(len) < PlainPacket::getHeaderLength()) {
174         continue;  // ignore short packets
175       }
176       plain_packet.setPayloadLength(len);
177       // set payload type
178       if(dev->getType() == TYPE_TUN) {
179         plain_packet.setPayloadType(PAYLOAD_TYPE_TUN);
180       } else if(dev->getType() == TYPE_TAP) {
181         plain_packet.setPayloadType(PAYLOAD_TYPE_TAP);
182       } else {
183         plain_packet.setPayloadType(0);
184       }
185
186       if(gConnectionList.empty()) {
187         continue;
188       }
189       //std::cout << "got Packet for plain "<<plain_packet.getDstAddr().toString();
190       ConnectionMap::iterator cit;
191 #ifndef NO_ROUTING
192       if(!disableRouting)
193         try {
194           mux = gRoutingTable.getRoute(plain_packet.getDstAddr());
195           //std::cout << " -> "<<mux << std::endl;
196           cit = gConnectionList.getConnection(mux);
197         } catch(std::exception&) { continue; }  // no route
198       else {
199         cit = gConnectionList.getBegin();
200       }
201 #else
202       cit = gConnectionList.getBegin();
203 #endif
204
205       if(cit==gConnectionList.getEnd()) {
206         continue;  //no connection
207       }
208       ConnectionParam& conn = cit->second;
209
210       if(conn.remote_end_ == emptyEndpoint) {
211         //cLog.msg(Log::PRIO_INFO) << "no remote address set";
212         continue;
213       }
214
215       // encrypt packet
216       c->encrypt(conn.kd_, plain_packet, encrypted_packet, conn.seq_nr_, gOpt.getSenderId(), mux);
217
218       encrypted_packet.setHeader(conn.seq_nr_, gOpt.getSenderId(), mux);
219       conn.seq_nr_++;
220
221       // add authentication tag
222       a->generate(conn.kd_, encrypted_packet);
223
224       try {
225         src->send(encrypted_packet.getBuf(), encrypted_packet.getLength(), conn.remote_end_);
226       } catch(std::exception& /*e*/) {
227         //TODO: do something here
228         //cLog.msg(Log::PRIO_ERROR) << "could not send data: " << e.what();
229       }
230     }
231   } catch(std::runtime_error& e) {
232     cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught runtime_error: " << e.what();
233   } catch(std::exception& e) {
234     cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught exception: " << e.what();
235   }
236 }
237
238 void receiver(TunDevice* dev, PacketSource* src)
239 {
240   if(!dev || !src) {
241     cLog.msg(Log::PRIO_ERROR) << "receiver thread died because either dev or src pointer is null";
242     return;
243   }
244
245   try {
246     std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher(), KD_INBOUND));
247     std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND));
248
249     uint32_t auth_tag_length = gOpt.getAuthTagLength();
250     EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, auth_tag_length);
251     PlainPacket plain_packet(MAX_PACKET_LENGTH);
252
253     for(;;) {
254       PacketSourceEndpoint remote_end;
255
256       plain_packet.setLength(MAX_PACKET_LENGTH);
257       encrypted_packet.withAuthTag(false);
258       encrypted_packet.setLength(MAX_PACKET_LENGTH);
259
260       // read packet from socket
261       int len;
262       try {
263         len = src->recv(encrypted_packet.getBuf(), encrypted_packet.getLength(), remote_end);
264       } catch(std::exception& /*e*/) {
265         //TODO: do something here
266         //cLog.msg(Log::PRIO_ERROR) << "could not recive packet "<< e.what();
267         continue;
268       }
269       if(len < 0) {
270         continue;  // silently ignore socket recv errors, this is probably no good idea...
271       }
272
273       if(static_cast<uint32_t>(len) < (EncryptedPacket::getHeaderLength() + auth_tag_length)) {
274         continue;  // ignore short packets
275       }
276       encrypted_packet.setLength(len);
277
278       mux_t mux = encrypted_packet.getMux();
279       // autodetect peer
280       if(gConnectionList.empty() && gOpt.getRemoteAddr() == "") {
281         cLog.msg(Log::PRIO_NOTICE) << "autodetected remote host " << remote_end;
282         createConnection(remote_end, gOpt.getSeqWindowSize(),mux);
283       }
284
285       ConnectionMap::iterator cit = gConnectionList.getConnection(mux);
286       if(cit == gConnectionList.getEnd()) {
287         continue;
288       }
289       ConnectionParam& conn = cit->second;
290
291       // check whether auth tag is ok or not
292       if(!a->checkTag(conn.kd_, encrypted_packet)) {
293         cLog.msg(Log::PRIO_NOTICE) << "wrong Authentication Tag!";
294         continue;
295       }
296
297       // Replay Protection
298       if(conn.seq_window_.checkAndAdd(encrypted_packet.getSenderId(), encrypted_packet.getSeqNr())) {
299         cLog.msg(Log::PRIO_NOTICE) << "Replay attack from " << conn.remote_end_
300                                    << " seq:"<< encrypted_packet.getSeqNr() << " sid: "<< encrypted_packet.getSenderId();
301         continue;
302       }
303
304       //Allow dynamic IP changes
305       //TODO: add command line option to turn this off
306       if(remote_end != conn.remote_end_) {
307         cLog.msg(Log::PRIO_NOTICE) << "connection "<< mux << " autodetected remote host ip changed " << remote_end;
308         conn.remote_end_=remote_end;
309 #ifndef ANYTUN_NOSYNC
310         SyncCommand sc(gConnectionList,mux);
311         gSyncQueue.push(sc);
312 #endif
313       }
314       // ignore zero length packets
315       if(encrypted_packet.getPayloadLength() <= PlainPacket::getHeaderLength()) {
316         continue;
317       }
318
319       // decrypt packet
320       c->decrypt(conn.kd_, encrypted_packet, plain_packet);
321
322       // check payload_type
323       if((dev->getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 &&
324           plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) ||
325           (dev->getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP)) {
326         continue;
327       }
328
329       // write it on the device
330       dev->write(plain_packet.getPayload(), plain_packet.getLength());
331     }
332   } catch(std::runtime_error& e) {
333     cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught runtime_error: " << e.what();
334   } catch(std::exception& e) {
335     cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught exception: " << e.what();
336   }
337 }
338
339 void startSendRecvThreads(TunDevice* dev, PacketSource* src)
340 {
341   src->waitUntilReady();
342
343   boost::thread(boost::bind(sender, dev, src));
344   boost::thread(boost::bind(receiver, dev, src));
345 }
346
347
348 #ifdef WIN_SERVICE
349 int main(int argc, char* argv[])
350 {
351   try {
352     if(argc > 1) {
353       if(std::string(argv[1]) == "install") {
354         WinService::install();
355         return 0;
356       } else if(std::string(argv[1]) == "uninstall") {
357         WinService::uninstall();
358         return 0;
359       }
360     }
361     WinService::start();
362     return 0;
363   } catch(std::runtime_error& e) {
364     std::cout << "caught runtime error, exiting: " << e.what() << std::endl;
365   } catch(std::exception& e) {
366     std::cout << "caught exception, exiting: " << e.what() << std::endl;
367   }
368 }
369
370 int real_main(int argc, char* argv[], WinService& service)
371 {
372 #else
373 int main(int argc, char* argv[])
374 {
375   DaemonService service;
376 #endif
377   try {
378     try {
379       if(!gOpt.parse(argc, argv)) {
380         exit(0);
381       }
382
383       StringList targets = gOpt.getLogTargets();
384       for(StringList::const_iterator it = targets.begin(); it != targets.end(); ++it) {
385         cLog.addTarget(*it);
386       }
387     } catch(syntax_error& e) {
388       std::cerr << e << std::endl;
389       gOpt.printUsage();
390       exit(-1);
391     }
392
393     cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
394     gOpt.parse_post(); // print warnings
395
396     // daemonizing has to done before any thread gets started
397     service.initPrivs(gOpt.getUsername(), gOpt.getGroupname());
398     if(gOpt.getDaemonize()) {
399       service.daemonize();
400     }
401
402     OptionNetwork net = gOpt.getIfconfigParam();
403     TunDevice dev(gOpt.getDevName(), gOpt.getDevType(), net.net_addr, net.prefix_length);
404     cLog.msg(Log::PRIO_NOTICE) << "dev opened - name '" << dev.getActualName() << "', node '" << dev.getActualNode() << "'";
405     cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << dev.getTypeString() << "'";
406
407     SysExec* postup_script = NULL;
408     if(gOpt.getPostUpScript() != "") {
409       cLog.msg(Log::PRIO_NOTICE) << "executing post-up script '" << gOpt.getPostUpScript() << "'";
410       StringVector args = boost::assign::list_of(dev.getActualName())(dev.getActualNode());
411       postup_script = new SysExec(gOpt.getPostUpScript(), args);
412     }
413
414     if(gOpt.getChrootDir() != "") {
415       try {
416         service.chroot(gOpt.getChrootDir());
417       } catch(const std::runtime_error& e) {
418         cLog.msg(Log::PRIO_WARNING) << "ignoring chroot error: " << e.what();
419       }
420     }
421     service.dropPrivs();
422
423     // this has to be called before the first thread is started
424     gSignalController.init(service);
425     gResolver.init();
426     boost::thread(boost::bind(&TunDevice::waitUntilReady,&dev));
427     if(postup_script) {
428       boost::thread(boost::bind(&SysExec::waitAndDestroy,postup_script));
429     }
430
431     initCrypto();
432
433     PacketSource* src = new UDPPacketSource(gOpt.getLocalAddr(), gOpt.getLocalPort());
434
435     if(gOpt.getRemoteAddr() != "") {
436       gResolver.resolveUdp(gOpt.getRemoteAddr(), gOpt.getRemotePort(), boost::bind(createConnectionResolver, _1, gOpt.getSeqWindowSize(), gOpt.getMux()), boost::bind(createConnectionError, _1), gOpt.getResolvAddrType());
437     }
438
439     HostList connect_to = gOpt.getRemoteSyncHosts();
440 #ifndef NO_ROUTING
441     NetworkList routes = gOpt.getRoutes();
442     NetworkList::const_iterator rit;
443     for(rit = routes.begin(); rit != routes.end(); ++rit) {
444       NetworkAddress addr(rit->net_addr);
445       NetworkPrefix prefix(addr, static_cast<uint8_t>(rit->prefix_length));
446       gRoutingTable.addRoute(prefix, gOpt.getMux());
447     }
448     if(connect_to.begin() == connect_to.end() || gOpt.getDevType()!="tun") {
449       cLog.msg(Log::PRIO_NOTICE) << "No sync/control host defined or not a tun device. Disabling multi connection support (routing)";
450       disableRouting=true;
451     }
452 #endif
453
454 #ifndef ANYTUN_NOSYNC
455     boost::thread* syncListenerThread = NULL;
456     if(gOpt.getLocalSyncPort() != "") {
457       syncListenerThread = new boost::thread(boost::bind(syncListener));
458       if(syncListenerThread) syncListenerThread->detach();
459     }
460
461     boost::thread_group connectThreads;
462     for(HostList::const_iterator it = connect_to.begin() ; it != connect_to.end(); ++it) {
463       connectThreads.create_thread(boost::bind(syncConnector, *it));
464     }
465 #endif
466
467     // wait for packet source to finish in a seperate thread in order
468     // to be still able to process signals while waiting
469     boost::thread(boost::bind(startSendRecvThreads, &dev, src));
470
471     int ret = gSignalController.run();
472
473     // TODO: stop all threads and cleanup
474     //
475     //     if(src)
476     //       delete src;
477     //     if(connTo)
478     //       delete connTo;
479     return ret;
480   } catch(std::runtime_error& e) {
481     cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what();
482     if(!service.isDaemonized()) {
483       std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl;
484     }
485   } catch(std::exception& e) {
486     cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what();
487     if(!service.isDaemonized()) {
488       std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
489     }
490   }
491   return -1;
492 }
493
494