4 * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
5 * featured implementation uAnytun has no support for multiple connections
6 * or synchronisation. It is a small single threaded implementation intended
7 * to act as a client on small platforms.
8 * The secure anycast tunneling protocol (satp) defines a protocol used
9 * for communication between any combination of unicast and anycast
10 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
11 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
12 * ethernet, ip, arp ...). satp directly includes cryptography and
13 * message authentication based on the methodes used by SRTP. It is
14 * intended to deliver a generic, scaleable and secure solution for
15 * tunneling and relaying of packets of any protocol.
18 * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
20 * This file is part of uAnytun.
22 * uAnytun is free software: you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 3 as
24 * published by the Free Software Foundation.
26 * uAnytun is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
35 #include "datatypes.h"
43 #include "sig_handler.h"
49 #include "plain_packet.h"
50 #include "encrypted_packet.h"
52 #include "seq_window.h"
56 #include "key_derivation.h"
57 #include "auth_algo.h"
59 #ifndef USE_SSL_CRYPTO
69 #ifndef USE_SSL_CRYPTO
71 #define MIN_GCRYPT_VERSION "1.2.0"
75 if(!gcry_check_version(MIN_GCRYPT_VERSION)) {
76 log_printf(NOTICE, "invalid Version of libgcrypt, should be >= %s", MIN_GCRYPT_VERSION);
80 gcry_error_t err = gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
82 log_printf(ERROR, "failed to disable secure memory: %s", gcry_strerror(err));
86 err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
88 log_printf(ERROR, "failed to finish libgcrypt initialization: %s", gcry_strerror(err));
92 log_printf(NOTICE, "libgcrypt init finished");
99 typedef u_int8_t auth_algo_t;
102 int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
104 int ret = cipher_init(c, opt->cipher_);
106 log_printf(ERROR, "could not initialize cipher of type %s", opt->cipher_);
111 ret = auth_algo_init(aa, opt->auth_algo_);
113 log_printf(ERROR, "could not initialize auth algo of type %s", opt->auth_algo_);
118 ret = key_derivation_init(kd, opt->kd_prf_, opt->role_, opt->passphrase_, opt->key_.buf_, opt->key_.length_, opt->salt_.buf_, opt->salt_.length_);
120 log_printf(ERROR, "could not initialize key derivation of type %s", opt->kd_prf_);
127 ret = seq_win_init(seq_win, opt->seq_window_size_);
129 printf("could not initialize sequence window");
133 key_derivation_close(kd);
140 int process_tun_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
141 cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_nr_t seq_nr)
143 plain_packet_set_payload_length(plain_packet, -1);
144 encrypted_packet_set_length(encrypted_packet, -1);
146 int len = tun_read(dev, plain_packet_get_payload(plain_packet), plain_packet_get_payload_length(plain_packet));
148 log_printf(ERROR, "error on reading from device: %s", strerror(errno));
152 plain_packet_set_payload_length(plain_packet, len);
154 if(dev->type_ == TYPE_TUN)
155 plain_packet_set_type(plain_packet, PAYLOAD_TYPE_TUN);
156 else if(dev->type_ == TYPE_TAP)
157 plain_packet_set_type(plain_packet, PAYLOAD_TYPE_TAP);
159 plain_packet_set_type(plain_packet, PAYLOAD_TYPE_UNKNOWN);
161 if(!sock->remote_end_set_)
164 cipher_encrypt(c, kd, kd_outbound, plain_packet, encrypted_packet, seq_nr, opt->sender_id_, opt->mux_);
167 auth_algo_generate(aa, kd, kd_outbound, encrypted_packet);
170 len = udp_write(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet));
172 log_printf(ERROR, "error on sending udp packet: %s", strerror(errno));
177 int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, plain_packet_t* plain_packet, encrypted_packet_t* encrypted_packet,
178 cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
180 plain_packet_set_payload_length(plain_packet, -1);
181 encrypted_packet_set_length(encrypted_packet, -1);
183 udp_endpoint_t remote;
184 memset(&remote, 0, sizeof(udp_endpoint_t));
185 int len = udp_read(sock, encrypted_packet_get_packet(encrypted_packet), encrypted_packet_get_length(encrypted_packet), &remote);
187 log_printf(ERROR, "error on receiving udp packet: %s", strerror(errno));
190 else if(len < encrypted_packet_get_minimum_length(encrypted_packet)) {
191 log_printf(WARNING, "received packet is to short");
194 encrypted_packet_set_length(encrypted_packet, len);
197 if(!auth_algo_check_tag(aa, kd, kd_inbound, encrypted_packet)) {
198 log_printf(WARNING, "wrong authentication tag, discarding packet");
203 if(encrypted_packet_get_mux(encrypted_packet) != opt->mux_) {
204 log_printf(WARNING, "wrong mux value, discarding packet");
208 int result = seq_win_check_and_add(seq_win, encrypted_packet_get_sender_id(encrypted_packet), encrypted_packet_get_seq_nr(encrypted_packet));
210 log_printf(WARNING, "detected replay attack, discarding packet");
213 else if(result < 0) {
214 log_printf(ERROR, "memory error at sequence window");
218 if(memcmp(&remote, &(sock->remote_end_), sizeof(remote))) {
219 memcpy(&(sock->remote_end_), &remote, sizeof(remote));
220 sock->remote_end_set_ = 1;
221 char* addrstring = udp_endpoint_to_string(remote);
222 log_printf(NOTICE, "autodetected remote host changed %s", addrstring);
226 if(encrypted_packet_get_payload_length(encrypted_packet) <= plain_packet_get_header_length()) {
227 log_printf(WARNING, "ignoring packet with zero length payload");
231 int ret = cipher_decrypt(c, kd, kd_inbound, encrypted_packet, plain_packet);
235 len = tun_write(dev, plain_packet_get_payload(plain_packet), plain_packet_get_payload_length(plain_packet));
237 log_printf(ERROR, "error on writing to device: %s", strerror(errno));
243 int main_loop(tun_device_t* dev, udp_socket_t* sock, options_t* opt)
245 log_printf(INFO, "entering main loop");
247 plain_packet_t plain_packet;
248 plain_packet_init(&plain_packet);
249 encrypted_packet_t encrypted_packet;
250 encrypted_packet_init(&encrypted_packet, opt->auth_tag_length_);
259 int ret = init_main_loop(opt, &c, &aa, &kd, &seq_win);
264 int return_value = 0;
265 while(!return_value) {
267 FD_SET(dev->fd_, &readfds);
268 FD_SET(sock->fd_, &readfds);
269 int nfds = dev->fd_ > sock->fd_ ? dev->fd_+1 : sock->fd_+1;
271 int ret = select(nfds, &readfds, NULL, NULL, NULL);
272 if(ret == -1 && errno != EINTR) {
273 log_printf(ERROR, "select returned with error: %s", strerror(errno));
285 if(FD_ISSET(dev->fd_, &readfds)) {
286 return_value = process_tun_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, seq_nr);
292 if(FD_ISSET(sock->fd_, &readfds)) {
293 return_value = process_sock_data(dev, sock, opt, &plain_packet, &encrypted_packet, &c, &aa, &kd, &seq_win);
301 auth_algo_close(&aa);
302 key_derivation_close(&kd);
304 seq_win_clear(&seq_win);
309 int main(int argc, char* argv[])
314 int ret = options_parse(&opt, argc, argv);
317 fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
320 fprintf(stderr, "memory error on options_parse, exitting\n");
323 fprintf(stderr, "syntax error: -4 and -6 are mutual exclusive\n\n");
326 fprintf(stderr, "syntax error: unknown role name\n\n");
330 options_print_usage();
336 string_list_element_t* tmp = opt.log_targets_.first_;
338 log_add_target("syslog:3,uanytun,daemon");
342 ret = log_add_target(tmp->string_);
345 case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
346 case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", tmp->string_); break;
347 case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", tmp->string_); break;
348 default: fprintf(stderr, "syntax error near: '%s', exitting\n", tmp->string_); break;
359 log_printf(NOTICE, "just started...");
360 options_parse_post(&opt);
364 if(priv_init(&priv, opt.username_, opt.groupname_)) {
371 #ifndef USE_SSL_CRYPTO
372 ret = init_libgcrypt();
374 log_printf(ERROR, "error on libgcrpyt initialization, exitting");
383 ret = tun_init(&dev, opt.dev_name_, opt.dev_type_, opt.ifconfig_param_.net_addr_, opt.ifconfig_param_.prefix_length_);
385 log_printf(ERROR, "error on tun_init, exitting");
390 log_printf(NOTICE, "dev of type '%s' opened, actual name is '%s'", tun_get_type_string(&dev), dev.actual_name_);
392 if(opt.post_up_script_) {
393 log_printf(NOTICE, "executing post-up script '%s'", opt.post_up_script_);
394 int ret = exec_script(opt.post_up_script_, dev.actual_name_);
399 ret = udp_init(&sock, opt.local_addr_, opt.local_port_, opt.resolv_addr_type_);
401 log_printf(ERROR, "error on udp_init, exitting");
407 char* local_string = udp_get_local_end_string(&sock);
409 log_printf(NOTICE, "listening on: %s", local_string);
414 if(opt.remote_addr_) {
415 if(!udp_set_remote(&sock, opt.remote_addr_, opt.remote_port_, opt.resolv_addr_type_)) {
416 char* remote_string = udp_get_remote_end_string(&sock);
418 log_printf(NOTICE, "set remote end to: %s", remote_string);
425 FILE* pid_file = NULL;
427 pid_file = fopen(opt.pid_file_, "w");
429 log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
434 if(do_chroot(opt.chroot_dir_)) {
442 if(priv_drop(&priv)) {
451 pid_t oldpid = getpid();
453 log_printf(INFO, "running in background now (old pid: %d)", oldpid);
457 pid_t pid = getpid();
458 fprintf(pid_file, "%d", pid);
462 ret = main_loop(&dev, &sock, &opt);
469 log_printf(NOTICE, "normal shutdown");
471 log_printf(NOTICE, "shutdown after error");
473 log_printf(NOTICE, "shutdown after signal");