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 methods 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-2014 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 as published by
24 * the Free Software Foundation, either version 3 of the License, or
27 * uAnytun is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
35 * In addition, as a special exception, the copyright holders give
36 * permission to link the code of portions of this program with the
37 * OpenSSL library under certain conditions as described in each
38 * individual source file, and distribute linked combinations
40 * You must obey the GNU General Public License in all respects
41 * for all of the code used other than OpenSSL. If you modify
42 * file(s) with this exception, you may extend this exception to your
43 * version of the file(s), but you are not obligated to do so. If you
44 * do not wish to do so, delete this exception statement from your
45 * version. If you delete this exception statement from all source
46 * files in the program, then also delete it here.
49 #include "datatypes.h"
62 #include "auth_algo.h"
65 #define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
66 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
69 #define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
70 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
73 #define PARSE_INT_PARAM(SHORT, LONG, VALUE) \
74 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
78 VALUE = atoi(argv[i+1]); \
83 #define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \
84 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
86 if(argc < 1 || argv[i+1][0] == '-') \
88 if(VALUE) free(VALUE); \
89 VALUE = strdup(argv[i+1]); \
96 #define PARSE_STRING_PARAM_SEC(SHORT, LONG, VALUE) \
97 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
99 if(argc < 1 || argv[i+1][0] == '-') \
101 if(VALUE) free(VALUE); \
102 VALUE = strdup(argv[i+1]); \
106 for(j=0; j < strlen(argv[i+1]); ++j) \
107 argv[i+1][j] = '#'; \
112 #define PARSE_IFCONFIG_PARAM(SHORT, LONG, VALUE) \
113 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
115 if(argc < 1 || argv[i+1][0] == '-') \
118 ret = options_parse_ifconfig(argv[i+1], &VALUE); \
127 #define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE) \
128 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
130 if(argc < 1 || argv[i+1][0] == '-') \
133 ret = options_parse_hex_string(argv[i+1], &VALUE); \
139 for(j=0; j < strlen(argv[i+1]); ++j) \
140 argv[i+1][j] = '#'; \
145 #define PARSE_STRING_LIST(SHORT, LONG, LIST) \
146 else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
148 if(argc < 1 || argv[i+1][0] == '-') \
150 int ret = string_list_add(&LIST, argv[i+1]); \
159 int options_parse_hex_string(const char* hex, buffer_t* buffer)
164 u_int32_t hex_len = strlen(hex);
171 buffer->length_ = hex_len/2;
172 buffer->buf_ = malloc(buffer->length_);
178 const char* ptr = hex;
180 for(i=0;i<buffer->length_;++i) {
182 sscanf(ptr, "%2X", &tmp);
183 buffer->buf_[i] = (u_int8_t)tmp;
190 int options_parse_ifconfig(const char* arg, ifconfig_param_t* ifcfg)
192 char* str = strdup(arg);
206 ifcfg->prefix_length_ = atoi(ptr);
207 ifcfg->net_addr_ = strdup(str);
210 if(!ifcfg->net_addr_)
215 if(!isdigit(*ptr) && *ptr != '.') {
225 int options_parse(options_t* opt, int argc, char* argv[])
230 options_default(opt);
233 free(opt->progname_);
234 opt->progname_ = strdup(argv[0]);
243 int i, ipv4_only = 0, ipv6_only = 0;
244 for(i=1; argc > 0; ++i)
249 if(!strcmp(str,"-h") || !strcmp(str,"--help"))
251 else if(!strcmp(str,"-v") || !strcmp(str,"--version"))
253 PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", opt->daemonize_)
254 PARSE_STRING_PARAM("-u","--username", opt->username_)
255 PARSE_STRING_PARAM("-g","--groupname", opt->groupname_)
256 PARSE_STRING_PARAM("-C","--chroot", opt->chroot_dir_)
257 PARSE_STRING_PARAM("-P","--write-pid", opt->pid_file_)
258 PARSE_STRING_PARAM("-i","--interface", opt->local_addr_)
259 PARSE_STRING_PARAM("-p","--port", opt->local_port_)
260 PARSE_INT_PARAM("-s","--sender-id", opt->sender_id_)
261 PARSE_STRING_LIST("-L","--log", opt->log_targets_)
262 PARSE_BOOL_PARAM("-U", "--debug", opt->debug_)
263 PARSE_STRING_PARAM("-r","--remote-host", opt->remote_addr_)
264 PARSE_STRING_PARAM("-o","--remote-port", opt->remote_port_)
265 PARSE_BOOL_PARAM("-4","--ipv4-only", ipv4_only)
266 PARSE_BOOL_PARAM("-6","--ipv6-only", ipv6_only)
267 PARSE_STRING_PARAM("-d","--dev", opt->dev_name_)
268 PARSE_STRING_PARAM("-t","--type", opt->dev_type_)
269 PARSE_IFCONFIG_PARAM("-n","--ifconfig", opt->ifconfig_param_)
270 PARSE_STRING_PARAM("-x","--post-up-script", opt->post_up_script_)
271 PARSE_INT_PARAM("-m","--mux", opt->mux_)
272 PARSE_INT_PARAM("-w","--window-size", opt->seq_window_size_)
274 PARSE_STRING_PARAM("-k","--kd-prf", opt->kd_prf_)
275 #ifndef NO_PASSPHRASE
276 PARSE_STRING_PARAM_SEC("-E","--passphrase", opt->passphrase_)
278 PARSE_STRING_PARAM("-e","--role", role)
279 PARSE_HEXSTRING_PARAM_SEC("-K","--key", opt->key_)
280 PARSE_HEXSTRING_PARAM_SEC("-A","--salt", opt->salt_)
281 PARSE_STRING_PARAM("-c","--cipher", opt->cipher_)
282 PARSE_STRING_PARAM("-a","--auth-algo", opt->auth_algo_)
283 PARSE_INT_PARAM("-b","--auth-tag-length", opt->auth_tag_length_)
288 if(ipv4_only && ipv6_only)
291 opt->resolv_addr_type_ = IPV4_ONLY;
293 opt->resolv_addr_type_ = IPV6_ONLY;
296 string_list_add(&opt->log_targets_, "stdout:5");
300 if(!opt->log_targets_.first_)
301 string_list_add(&opt->log_targets_, "syslog:3,uanytun,daemon");
305 if(!strcmp(role, "alice") || !strcmp(role, "server") || !strcmp(role, "left"))
306 opt->role_ = ROLE_LEFT;
307 else if(!strcmp(role, "bob") || !strcmp(role, "client") || !strcmp(role, "right"))
308 opt->role_ = ROLE_RIGHT;
319 void options_parse_post(options_t* opt)
325 if(!strcmp(opt->cipher_, "null") && !strcmp(opt->auth_algo_, "null") &&
326 strcmp(opt->kd_prf_, "null")) {
329 opt->kd_prf_ = strdup("null");
331 if((strcmp(opt->cipher_, "null") || strcmp(opt->auth_algo_, "null")) &&
332 !strcmp(opt->kd_prf_, "null")) {
333 log_printf(WARNING, "using NULL key derivation with encryption and or authentication enabled!");
336 u_int32_t tag_len_max = auth_algo_get_max_length(opt->auth_algo_);
337 if(!tag_len_max) opt->auth_tag_length_ = 0;
338 else if(tag_len_max < opt->auth_tag_length_) {
339 log_printf(WARNING, "%s auth algo can't generate tags of length %d, using maximum tag length(%d)", opt->auth_algo_, opt->auth_tag_length_, tag_len_max);
340 opt->auth_tag_length_ = tag_len_max;
344 if(!(opt->dev_name_) && !(opt->dev_type_))
345 opt->dev_type_ = strdup("tun");
348 void options_default(options_t* opt)
353 opt->progname_ = strdup("uanytun");
355 opt->username_ = NULL;
356 opt->groupname_ = NULL;
357 opt->chroot_dir_ = NULL;
358 opt->pid_file_ = NULL;
359 string_list_init(&opt->log_targets_);
361 opt->local_addr_ = NULL;
362 opt->local_port_ = strdup("4444");
364 opt->remote_addr_ = NULL;
365 opt->remote_port_ = strdup("4444");
366 opt->resolv_addr_type_ = ANY;
367 opt->dev_name_ = NULL;
368 opt->dev_type_ = NULL;
369 opt->ifconfig_param_.net_addr_ = NULL;
370 opt->ifconfig_param_.prefix_length_ = 0;
371 opt->post_up_script_ = NULL;
373 opt->seq_window_size_ = 0;
375 opt->kd_prf_ = strdup("aes-ctr");
376 opt->passphrase_ = NULL;
377 opt->role_ = ROLE_LEFT;
378 opt->cipher_ = strdup("aes-ctr");
379 opt->auth_algo_ = strdup("sha1");
380 opt->auth_tag_length_ = 10;
382 opt->cipher_ = strdup("null");
383 opt->auth_tag_length_ = 0;
385 opt->key_.buf_ = NULL;
386 opt->key_.length_ = 0;
387 opt->salt_.buf_ = NULL;
388 opt->salt_.length_ = 0;
391 void options_clear(options_t* opt)
397 free(opt->progname_);
399 free(opt->username_);
401 free(opt->groupname_);
403 free(opt->chroot_dir_);
405 free(opt->pid_file_);
406 string_list_clear(&opt->log_targets_);
408 free(opt->local_addr_);
410 free(opt->local_port_);
411 if(opt->remote_addr_)
412 free(opt->remote_addr_);
413 if(opt->remote_port_)
414 free(opt->remote_port_);
416 free(opt->dev_name_);
418 free(opt->dev_type_);
419 if(opt->ifconfig_param_.net_addr_)
420 free(opt->ifconfig_param_.net_addr_);
421 if(opt->post_up_script_)
422 free(opt->post_up_script_);
427 free(opt->auth_algo_);
431 free(opt->passphrase_);
434 free(opt->key_.buf_);
436 free(opt->salt_.buf_);
439 void options_print_usage()
442 printf("uanytun [-h|--help] prints this...\n");
443 printf(" [-v|--version] print version info and exit\n");
444 printf(" [-D|--nodaemonize] don't run in background\n");
445 printf(" [-u|--username] <username> change to this user\n");
446 printf(" [-g|--groupname] <groupname> change to this group\n");
447 printf(" [-C|--chroot] <path> chroot to this directory\n");
448 printf(" [-P|--write-pid] <path> write pid to this file\n");
449 printf(" [-i|--interface] <ip-address> local ip address to bind to\n");
450 printf(" [-p|--port] <port> local port to bind to\n");
451 printf(" [-s|--sender-id ] <sender id> the sender id to use\n");
452 printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n");
453 printf(" add a log target, can be invoked several times\n");
454 printf(" [-U|--debug] don't daemonize and log to stdout with maximum log level\n");
456 printf(" [-r|--remote-host] <hostname|ip> remote host\n");
457 printf(" [-o|--remote-port] <port> remote port\n");
458 printf(" [-4|--ipv4-only] always resolv IPv4 addresses\n");
459 printf(" [-6|--ipv6-only] always resolv IPv6 addresses\n");
460 printf(" [-d|--dev] <name> device name\n");
461 printf(" [-t|--type] <tun|tap> device type\n");
463 printf(" [-n|--ifconfig] <local>/<prefix> the local address for the tun/tap device and the used prefix length\n");
464 printf(" [-x|--post-up-script] <script> script gets called after interface is created\n");
465 printf(" [-m|--mux] <mux-id> the multiplex id to use\n");
466 printf(" [-w|--window-size] <window size> seqence number window size\n");
468 printf(" [-k|--kd-prf] <kd-prf type> key derivation pseudo random function\n");
469 #ifndef NO_PASSPHRASE
470 printf(" [-E|--passphrase] <pass phrase> a passprhase to generate master key and salt from\n");
472 printf(" [-K|--key] <master key> master key to use for encryption\n");
473 printf(" [-A|--salt] <master salt> master salt to use for encryption\n");
474 printf(" [-e|--role] <role> left (alice) or right (bob)\n");
475 printf(" [-c|--cipher] <cipher type> payload encryption algorithm\n");
476 printf(" [-a|--auth-algo] <algo type> message authentication algorithm\n");
477 printf(" [-b|--auth-tag-length] <length> length of the auth tag\n");
481 void options_print_version()
483 printf("%s\n", VERSION_STRING_0);
484 printf("%s\n", VERSION_STRING_1);
487 void options_print(options_t* opt)
492 printf("progname: '%s'\n", opt->progname_);
493 printf("daemonize: %d\n", opt->daemonize_);
494 printf("username: '%s'\n", opt->username_);
495 printf("groupname: '%s'\n", opt->groupname_);
496 printf("chroot_dir: '%s'\n", opt->chroot_dir_);
497 printf("pid_file: '%s'\n", opt->pid_file_);
498 printf("log_targets: \n");
499 string_list_print(&opt->log_targets_, " '", "'\n");
500 printf("debug: %s\n", !opt->debug_ ? "false" : "true");
501 printf("local_addr: '%s'\n", opt->local_addr_);
502 printf("local_port: '%s'\n", opt->local_port_);
503 printf("sender_id: %d\n", opt->sender_id_);
504 printf("remote_addr: '%s'\n", opt->remote_addr_);
505 printf("remote_port: '%s'\n", opt->remote_port_);
506 printf("resolv_addr_type: ");
507 switch(opt->resolv_addr_type_) {
508 case ANY: printf("any\n"); break;
509 case IPV4_ONLY: printf("ipv4-only\n"); break;
510 case IPV6_ONLY: printf("ipv6-only\n"); break;
511 default: printf("??\n"); break;
513 printf("dev_name: '%s'\n", opt->dev_name_);
514 printf("dev_type: '%s'\n", opt->dev_type_);
515 printf("ifconfig_net_addr: '%s'\n", opt->ifconfig_param_.net_addr_);
516 printf("ifconfig_prefix_length: %d\n", opt->ifconfig_param_.prefix_length_);
517 printf("post_up_script: '%s'\n", opt->post_up_script_);
518 printf("mux: %d\n", opt->mux_);
519 printf("seq_window_size: %d\n", opt->seq_window_size_);
520 printf("cipher: '%s'\n", opt->cipher_);
522 printf("auth_algo: '%s'\n", opt->auth_algo_);
523 printf("auth_tag_length: %d\n", opt->auth_tag_length_);
524 printf("kd_prf: '%s'\n", opt->kd_prf_);
525 printf("passphrase: '%s'\n", opt->passphrase_);
528 case ROLE_LEFT: printf("left\n"); break;
529 case ROLE_RIGHT: printf("right\n"); break;
530 default: printf("??\n"); break;
535 printf("key_[%d]: '", opt->key_.length_);
536 for(i=0; i<opt->key_.length_; ++i) printf("%02X", opt->key_.buf_[i]);
539 printf("salt_[%d]: '", opt->salt_.length_);
540 for(i=0; i<opt->salt_.length_; ++i) printf("%02X", opt->salt_.buf_[i]);