X-Git-Url: https://git.syn-net.org/debian/?a=blobdiff_plain;f=src%2Foptions.cpp;h=8cfc480c09d676d5ab58c0e4cc66bd748452b02c;hb=326bc57905738d0bd416ce3d0d7cc79b14ef7a4a;hp=236acb1b350886da9a37c9e864d2affd4b2de161;hpb=bb834fe0ed7a38b724f49b944adb801634eb6194;p=anytun.git diff --git a/src/options.cpp b/src/options.cpp index 236acb1..8cfc480 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -6,12 +6,12 @@ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel * mode and allows tunneling of every ETHER TYPE protocol (e.g. * ethernet, ip, arp ...). satp directly includes cryptography and - * message authentication based on the methodes used by SRTP. It is + * message authentication based on the methods used by SRTP. It is * intended to deliver a generic, scaleable and secure solution for * tunneling and relaying of packets of any protocol. * * - * Copyright (C) 2007-2009 Othmar Gsenger, Erwin Nindl, + * Copyright (C) 2007-2014 Markus Grüneis, Othmar Gsenger, Erwin Nindl, * Christian Pointner * * This file is part of Anytun. @@ -27,7 +27,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with anytun. If not, see . + * along with Anytun. If not, see . + * + * In addition, as a special exception, the copyright holders give + * permission to link the code of portions of this program with the + * OpenSSL library under certain conditions as described in each + * individual source file, and distribute linked combinations + * including the two. + * You must obey the GNU General Public License in all respects + * for all of the code used other than OpenSSL. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you + * do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source + * files in the program, then also delete it here. */ #include @@ -37,6 +50,8 @@ #include #include "datatypes.h" +#include "version.h" + #include "options.h" #include "log.h" #include "authAlgoFactory.h" @@ -46,7 +61,7 @@ std::ostream& operator<<(std::ostream& stream, syntax_error const& error) stream << "syntax error: " << error.what() << std::endl; if(error.pos >= 0) { stream << " "; - for(int32_t i = 0; i < error.pos; ++i) stream << " "; + for(int32_t i = 0; i < error.pos; ++i) { stream << " "; } return stream << "^"; } return stream; @@ -55,10 +70,16 @@ std::ostream& operator<<(std::ostream& stream, syntax_error const& error) std::ostream& operator<<(std::ostream& stream, role_t const& role) { switch(role) { - case ROLE_LEFT: stream << "left"; break; - case ROLE_RIGHT: stream << "right"; break; - default: stream << "unknown"; break; - } + case ROLE_LEFT: + stream << "left"; + break; + case ROLE_RIGHT: + stream << "right"; + break; + default: + stream << "unknown"; + break; + } return stream; } @@ -67,30 +88,32 @@ void OptionHost::init(std::string addrPort) std::string origAddrPort(addrPort); size_t pos = addrPort.find_first_of("["); - if(pos != std::string::npos && pos != 0) - throw syntax_error(origAddrPort, pos); // an [ was found but not at the beginning; + if(pos != std::string::npos && pos != 0) { + throw syntax_error(origAddrPort, pos); // an [ was found but not at the beginning; + } bool hasPort = false; if(pos != std::string::npos) { addrPort.erase(pos, 1); pos = addrPort.find_first_of("]"); - if(pos == std::string::npos) - throw syntax_error(origAddrPort, origAddrPort.length()); //no trailing ] although an leading [ was found + if(pos == std::string::npos) { + throw syntax_error(origAddrPort, origAddrPort.length()); //no trailing ] although an leading [ was found + } if(pos < addrPort.length()-2) { - if(addrPort[pos+1] != ':') - throw syntax_error(origAddrPort, pos+2); // wrong port delimieter + if(addrPort[pos+1] != ':') { + throw syntax_error(origAddrPort, pos+2); // wrong port delimieter + } addrPort[pos+1] = '/'; hasPort = true; + } else if(pos != addrPort.length()-1) { + throw syntax_error(origAddrPort, pos+2); // too few characters left } - else if(pos != addrPort.length()-1) - throw syntax_error(origAddrPort, pos+2); // too few characters left addrPort.erase(pos, 1); - } - else { + } else { pos = addrPort.find_first_of(":"); if(pos != std::string::npos && pos == addrPort.find_last_of(":")) { // an ':' has been found and it is the only one -> assuming port present @@ -103,12 +126,12 @@ void OptionHost::init(std::string addrPort) std::stringstream tmp_stream(addrPort); getline(tmp_stream, addr, '/'); - if(!tmp_stream.good()) + if(!tmp_stream.good()) { throw syntax_error(origAddrPort, addr.length()); + } tmp_stream >> port; - } - else { + } else { addr = addrPort; port = "2323"; // default sync port } @@ -122,12 +145,13 @@ std::istream& operator>>(std::istream& stream, OptionHost& host) return stream; } -void OptionNetwork::init(std::string network) +void OptionNetwork::init(std::string network) { std::stringstream tmp_stream(network); getline(tmp_stream, net_addr, '/'); - if(!tmp_stream.good()) + if(!tmp_stream.good()) { throw syntax_error(network, net_addr.length()); + } tmp_stream >> prefix_length; } @@ -139,21 +163,15 @@ std::istream& operator>>(std::istream& stream, OptionNetwork& network) return stream; } -Options* Options::inst = NULL; -Mutex Options::instMutex; Options& gOpt = Options::instance(); Options& Options::instance() { - Lock lock(instMutex); - static instanceCleaner c; - if(!inst) - inst = new Options(); - - return *inst; + static Options instance; + return instance; } -Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0)) +Options::Options() : key_(uint32_t(0)), salt_(uint32_t(0)) { #if defined(ANYCTR_OPTIONS) progname_ = "anytun-controld"; @@ -172,6 +190,8 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0)) chroot_dir_ = ""; pid_file_ = ""; + debug_ = false; + file_name_ = ""; bind_to_.addr = "127.0.0.1"; bind_to_.port = "2323"; @@ -251,7 +271,7 @@ Options::~Options() if(argc < 1) \ throw syntax_error(str, str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ std::stringstream tmp; \ @@ -270,11 +290,11 @@ Options::~Options() if(argc < 2) \ throw syntax_error(str.append(" ").append(argv[i+1]), str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ if(argv[i+2][0] == '-') { \ - u_int32_t pos = str.length() + 1 + strlen(argv[i+1]) + 1; \ + uint32_t pos = str.length() + 1 + strlen(argv[i+1]) + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]).append(" ").append(argv[i+2]), pos); \ } \ std::stringstream tmp; \ @@ -292,7 +312,7 @@ Options::~Options() if(argc < 1) \ throw syntax_error(str, str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ std::stringstream tmp(argv[i+1]); \ @@ -313,7 +333,7 @@ Options::~Options() if(argc < 1) \ throw syntax_error(str, str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ VALUE = Buffer(std::string(argv[i+1])); \ @@ -330,7 +350,7 @@ Options::~Options() if(argc < 1) \ throw syntax_error(str, str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ VALUE = argv[i+1]; \ @@ -347,7 +367,7 @@ Options::~Options() if(argc < 1) \ throw syntax_error(str, str.length()); \ if(argv[i+1][0] == '-') { \ - u_int32_t pos = str.length() + 1; \ + uint32_t pos = str.length() + 1; \ throw syntax_error(str.append(" ").append(argv[i+1]), pos); \ } \ LIST.push_back(argv[i+1]); \ @@ -364,27 +384,32 @@ bool Options::parse(int argc, char* argv[]) argc--; bool ipv4_only = false, ipv6_only = false; std::string role = ""; - for(int i=1; argc > 0; ++i) - { + for(int i=1; argc > 0; ++i) { std::string str(argv[i]); argc--; - if(str == "-h" || str == "--help") + if(str == "-h" || str == "--help") { + printUsage(); + return false; + } else if(str == "-v" || str == "--version") { + printVersion(); return false; + } #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS) - #ifndef NO_DAEMON +#if !defined(_MSC_VER) && !defined(MINGW) PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_, NOTHING) PARSE_SCALAR_PARAM("-u","--username", username_, NOTHING) PARSE_SCALAR_PARAM("-g","--groupname", groupname_, NOTHING) PARSE_SCALAR_PARAM("-C","--chroot", chroot_dir_, NOTHING) PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_, NOTHING) - #endif +#endif #endif PARSE_STRING_LIST("-L","--log", log_targets_, NOTHING) + PARSE_BOOL_PARAM("-U","--debug", debug_, NOTHING) #if defined(ANYCTR_OPTIONS) @@ -417,57 +442,81 @@ bool Options::parse(int argc, char* argv[]) PARSE_SCALAR_PARAM("-d","--dev", dev_name_, NOTHING) PARSE_SCALAR_PARAM("-t","--type", dev_type_, NOTHING) PARSE_SCALAR_PARAM("-n","--ifconfig", ifconfig_param_, NOTHING) - #ifndef NO_EXEC PARSE_SCALAR_PARAM("-x","--post-up-script", post_up_script_, NOTHING) - #endif #endif #if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS) - #ifndef NO_ROUTING +#ifndef NO_ROUTING PARSE_CSLIST_PARAM("-R","--route", routes_, OptionNetwork, connection_opts = true) - #endif +#endif PARSE_SCALAR_PARAM("-m","--mux", mux_, connection_opts = true) PARSE_SCALAR_PARAM("-w","--window-size", seq_window_size_, connection_opts = true) - #ifndef NO_CRYPT +#ifndef NO_CRYPT PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_, connection_opts = true) PARSE_SCALAR_PARAM("-e","--role", role, connection_opts = true) - #ifndef NO_PASSPHRASE +#ifndef NO_PASSPHRASE PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_, connection_opts = true) - #endif +#endif PARSE_HEXSTRING_PARAM_SEC("-K","--key", key_, connection_opts = true) PARSE_HEXSTRING_PARAM_SEC("-A","--salt", salt_, connection_opts = true) - #endif +#endif #endif #if defined(ANYTUN_OPTIONS) - #ifndef NO_CRYPT +#ifndef NO_CRYPT PARSE_SCALAR_PARAM("-c","--cipher", cipher_, NOTHING) PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_, NOTHING) PARSE_SCALAR_PARAM("-b","--auth-tag-length", auth_tag_length_, NOTHING) - #endif +#endif #endif - else + else { throw syntax_error(str, 0); + } } - if(ipv4_only && ipv6_only) + if(ipv4_only && ipv6_only) { throw syntax_error("-4 and -6 are mutual exclusive", -1); - if(ipv4_only) + } + if(ipv4_only) { resolv_addr_type_ = IPV4_ONLY; - if(ipv6_only) + } + if(ipv6_only) { resolv_addr_type_ = IPV6_ONLY; + } if(role != "") { - if(role == "alice" || role == "server" || role == "left") + if(role == "alice" || role == "server" || role == "left") { role_ = ROLE_LEFT; - else if(role == "bob" || role == "client" || role == "right") + } else if(role == "bob" || role == "client" || role == "right") { role_ = ROLE_RIGHT; - else - throw syntax_error("unknown role name: " + role, -1); + } else { + throw syntax_error("unknown role name: " + role, -1); + } + } + + if(debug_) { + log_targets_.push_back("stdout:5"); + daemonize_ = false; + } + + if(log_targets_.empty()) { +#if !defined(_MSC_VER) && !defined(MINGW) +#if !defined(ANYCONF_OPTIONS) + log_targets_.push_back(std::string("syslog:3,").append(progname_).append(",daemon")); +#else + log_targets_.push_back("stderr:2"); +#endif +#else +#ifdef WIN_SERVICE + log_targets_.push_back(std::string("eventlog:3,").append(progname_)); +#else + log_targets_.push_back("stdout:3"); +#endif +#endif } return true; @@ -476,24 +525,49 @@ bool Options::parse(int argc, char* argv[]) void Options::parse_post() { #if defined(ANYTUN_OPTIONS) - if(cluster_opts && connection_opts) + if(cluster_opts && connection_opts) { cLog.msg(Log::PRIO_WARNING) << "you have provided options for cluster support as well as connection oriented options, we strongly recommend to use anytun-config and anytun-controld when building a cluster"; + } - if(cipher_ == "null" && auth_algo_ == "null") + if(cipher_ == "null" && auth_algo_ == "null") { kd_prf_ = "null"; - if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null") + } + if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null") { cLog.msg(Log::PRIO_WARNING) << "using NULL key derivation with encryption and or authentication enabled!"; + } - u_int32_t tag_len_max = AuthAlgoFactory::getDigestLength(auth_algo_); - if(!tag_len_max) auth_tag_length_ = 0; + uint32_t tag_len_max = AuthAlgoFactory::getDigestLength(auth_algo_); + if(!tag_len_max) { auth_tag_length_ = 0; } else if(tag_len_max < auth_tag_length_) { cLog.msg(Log::PRIO_WARNING) << auth_algo_ << " auth algo can't generate tags of length " << auth_tag_length_ << ", using maximum tag length(" << tag_len_max << ")"; auth_tag_length_ = tag_len_max; } #endif - if(dev_name_ == "" && dev_type_ == "") + if(dev_name_ == "" && dev_type_ == "") { dev_type_ = "tun"; + } +} + +void Options::printVersion() +{ +#if defined(ANYCTR_OPTIONS) + std::cout << "anytun-controld"; +#elif defined(ANYCONF_OPTIONS) + std::cout << "anytun-config"; +#else + std::cout << "anytun"; +#endif + std::cout << VERSION_STRING << std::endl; + +#if defined(__clang__) + std::cout << "built using CLANG " << __clang_version__ << " with " << CRYPTO_LIB_NAME << " crypto library." << std::endl; +#elif defined(__GNUC__) + std::cout << "built using GCC " << __GNUC__ << '.' << __GNUC_MINOR__ << '.' << __GNUC_PATCHLEVEL__ + << " with " << CRYPTO_LIB_NAME << " crypto library." << std::endl; +#else + std::cout << "built using an unknown compiler " << CRYPTO_LIB_NAME << " crypto library." << std::endl; +#endif } void Options::printUsage() @@ -509,21 +583,24 @@ void Options::printUsage() #endif std::cout << " [-h|--help] prints this..." << std::endl; + std::cout << " [-v|--version] print version info and exit" << std::endl; #if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS) - #ifndef NO_DAEMON +#if !defined(_MSC_VER) && !defined(MINGW) std::cout << " [-D|--nodaemonize] don't run in background" << std::endl; std::cout << " [-u|--username] change to this user" << std::endl; std::cout << " [-g|--groupname] change to this group" << std::endl; std::cout << " [-C|--chroot] chroot to this directory" << std::endl; std::cout << " [-P|--write-pid] write pid to this file" << std::endl; - #endif +#endif #endif std::cout << " [-L|--log] :[,[,..]]" << std::endl; std::cout << " add a log target, can be invoked several times" << std::endl; + std::cout << " i.e.: stdout:5" << std::endl; + std::cout << " [-U|--debug] don't daemonize and log to stdout with maximum log level" << std::endl; #if defined(ANYCTR_OPTIONS) @@ -559,38 +636,36 @@ void Options::printUsage() std::cout << " [-d|--dev] device name" << std::endl; std::cout << " [-t|--type] device type" << std::endl; std::cout << " [-n|--ifconfig] / the local address for the tun/tap device and the used prefix length" << std::endl; - #ifndef NO_EXEC std::cout << " [-x|--post-up-script]