diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2017-12-10 19:51:06 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2017-12-10 19:51:06 +0100 |
commit | 2d7031c57b1177442280ac1ebcac463d0a035b4b (patch) | |
tree | fffb8e91aee4996bae2dde52f3f754f2058da777 | |
parent | b499c7305cee6942dc037f34b2e37489f501da47 (diff) |
ptunnel-ng:
* option parsing
4 files changed, 46 insertions, 204 deletions
@@ -37,7 +37,7 @@ static const struct option_usage usage[] = { "and can be used to bypass Cisco IPS\n" "This value has to be the same on the server and client!\n" }, - {"address:port", 1, OPT_STR, {.unum = 0}, + {"address", 1, OPT_STR, {.unum = 0}, "Set address of peer running packet forwarder. This causes\n" "ptunnel to operate in forwarding mode - the absence of this\n" "option causes ptunnel to operate in proxy mode.\n" @@ -242,6 +242,11 @@ int parse_options(int argc, char **argv) { struct group *grnam; #endif + /* set defaults */ + memset(&opts, 0, sizeof(opts)); + opts.proxy_mode = kMode_proxy; + + /* parse command line arguments */ while (1) { c = getopt_long(argc, argv, "m:p:l:r:c:v:a:o:sdSx:u:g:t:eh", &long_options[0], &optind); if (c == -1) break; @@ -251,6 +256,7 @@ int parse_options(int argc, char **argv) { opts.magic = strtoul(optarg, NULL, 16); break; case 'p': + opts.proxy_mode = kMode_forward; if (NULL == (host_ent = gethostbyname(optarg))) { pt_log(kLog_error, "Failed to look up %s as proxy address\n", optarg); return 1; @@ -332,7 +338,7 @@ int parse_options(int argc, char **argv) { #else case 'd': case 'S': - case 'U': + case 'u': case 'g': case 't': pt_log(kLog_error, "%s: feature not supported", optarg); @@ -350,7 +356,7 @@ int parse_options(int argc, char **argv) { print_usage(argv[0]); _exit(EXIT_SUCCESS); default: - printf("Opt ERROR\n"); + pt_log(kLog_error, "%s: option unknown", optarg); break; } } @@ -10,7 +10,12 @@ #include <selinux/selinux.h> #endif +#include "ptunnel.h" + + struct options { + /** proxy or forwarder? */ + int proxy_mode; /** user defined magic value (prevent Cisco WSA/IronPort fingerprint scan) */ uint32_t magic; /** Proxy's internet address */ @@ -124,12 +124,7 @@ const char *state_name[kNum_proto_types] = { "start", "ack", "data", "close", "a // Let the fun begin! int main(int argc, char *argv[]) { - int i, opt; - md5_state_t state; - struct hostent *host_ent; #ifndef WIN32 - struct passwd *pwnam; - struct group *grnam; pid_t pid; #endif #ifdef WIN32 @@ -151,170 +146,21 @@ int main(int argc, char *argv[]) { } #endif /* WIN32 */ - // Seed random generator; it'll be used in combination with a timestamp // when generating authentication challenges. srand(time(0)); memset(password_digest, 0, kMD5_digest_size); - + /* The seq_expiry_tbl is used to prevent the remote ends from prematurely re-using a sequence number. */ seq_expiry_tbl = calloc(65536, sizeof(uint32_t)); - + log_file = stdout; - + // Parse options parse_options(argc, argv); - opt = kOpt_undefined; - mode = kMode_proxy; - for (i=1;i<argc;i++) { - if (strcmp(argv[i], "-a") == 0) { - opt = kOpt_set_magic; - } - else if (strcmp(argv[i], "-p") == 0) { - mode = kMode_forward; - opt = kOpt_set_proxy_addr; - } - else if (strcmp(argv[i], "-x") == 0) - opt = kOpt_set_password; - else if (strcmp(argv[i], "-lp") == 0) - opt = kOpt_set_tcp_port; - else if (strcmp(argv[i], "-da") == 0) - opt = kOpt_set_tcp_dest_addr; - else if (strcmp(argv[i], "-dp") == 0) - opt = kOpt_set_tcp_dest_port; - else if (strcmp(argv[i], "-v") == 0) - opt = kOpt_set_verbosity; - else if (strcmp(argv[i], "-m") == 0) - opt = kOpt_set_max_tunnels; - else if (strcmp(argv[i], "-u") == 0) - unprivileged = !unprivileged; - else if (strcmp(argv[i], "-c") == 0) - opt = kOpt_set_pcap_device; - else if (strcmp(argv[i], "-f") == 0) - opt = kOpt_set_log_file; - else if (strcmp(argv[i], "-s") == 0) - print_stats = !print_stats; - #ifndef WIN32 - else if (strcmp(argv[i], "-syslog") == 0) - use_syslog = !use_syslog; - else if (strcmp(argv[i], "-setuid") == 0) - opt = kOpt_set_unpriv_user; - else if (strcmp(argv[i], "-setgid") == 0) - opt = kOpt_set_unpriv_group; - else if (strcmp(argv[i], "-chroot") == 0) - opt = kOpt_set_root_dir; - else if (strcmp(argv[i], "-setcon") == 0) - opt = kOpt_set_selinux_context; - else if (strcmp(argv[i], "-daemon") == 0) - opt = kOpt_daemonize; - #endif /* !WIN32 */ - else if (strcmp(argv[i], "-udp") == 0) - use_udp = 1; - else { - switch (opt) { - case kOpt_set_magic: - magic = strtoul(argv[i], NULL, 16); - break; - case kOpt_set_proxy_addr: - if (NULL == (host_ent = gethostbyname(argv[i]))) { - pt_log(kLog_error, "Failed to look up %s as proxy address\n", argv[i]); - return 1; - } - given_proxy_ip = *(uint32_t*)host_ent->h_addr_list[0]; - break; - case kOpt_set_password: - password = argv[i]; - pt_log(kLog_debug, "Password set - unauthenicated connections will be refused.\n"); - // Compute the password digest - md5_init(&state); - md5_append(&state, (md5_byte_t*)password, strlen(password)); - md5_finish(&state, (md5_byte_t*)password_digest); - // Hide the password in process listing - memset(argv[i], ' ', strlen(argv[i])); - break; - case kOpt_set_tcp_port: - tcp_listen_port = atoi(argv[i]); - break; - case kOpt_set_tcp_dest_addr: - if (NULL == (host_ent = gethostbyname(argv[i]))) { - pt_log(kLog_error, "Failed to look up %s as destination address\n", argv[i]); - return 1; - } - given_dst_ip = *(uint32_t*)host_ent->h_addr_list[0]; - break; - case kOpt_set_tcp_dest_port: - tcp_port = atoi(argv[i]); - break; - case kOpt_set_max_tunnels: - max_tunnels = atoi(argv[i]); - if (max_tunnels <= 0) - max_tunnels = kMax_tunnels; - break; - case kOpt_set_verbosity: - log_level = atoi(argv[i]); - break; - case kOpt_set_pcap_device: - pcap_device = argv[i]; - pcap = 1; - break; - case kOpt_set_log_file: - log_file = fopen(argv[i], "a"); - if (!log_file) { - log_file = stdout; - pt_log(kLog_error, "Failed to open log file: '%s'. Cause: %s\n", argv[i], strerror(errno)); - pt_log(kLog_error, "Reverting log to standard out.\n"); - } - break; - #ifndef WIN32 - case kOpt_set_unpriv_user: - errno = 0; - if (NULL == (pwnam = getpwnam(argv[i]))) { - pt_log(kLog_error, "%s: %s\n", argv[i], errno ? strerror(errno) : "unknown user"); - exit(1); - } - uid = pwnam->pw_uid; - if (!gid) - gid = pwnam->pw_gid; - break; - case kOpt_set_unpriv_group: - errno = 0; - if (NULL == (grnam = getgrnam(argv[i]))) { - pt_log(kLog_error, "%s: %s\n", argv[i], errno ? strerror(errno) : "unknown group"); - exit(1); - } - gid = grnam->gr_gid; - break; - case kOpt_set_root_dir: - root_dir = strdup(argv[i]); - break; - case kOpt_set_selinux_context: - #ifdef HAVE_SELINUX - selinux_context = strdup(argv[i]); - #else - pt_log(kLog_error, "Sorry: SELinux support missing, please recompile with libselinux.\n"); - return 1; - #endif - break; - case kOpt_daemonize: - daemonize = true; - if (NULL == (pid_file = fopen(argv[i], "w"))) - pt_log(kLog_error, "%s: %s\n", argv[i], strerror(errno)); - break; - #endif /* !WIN32 */ - case kOpt_undefined: - print_usage(argv[0]); - return 1; - } - opt = kOpt_undefined; - } - } - if (opt != kOpt_undefined) { - print_usage(argv[0]); - exit(1); - } if (pcap && use_udp) { pt_log(kLog_error, "Packet capture is not supported (or needed) when using UDP for transport.\n"); pcap = 0; @@ -83,61 +83,46 @@ struct ether_header { #endif /* WIN32 */ enum { - kOpt_undefined = 0, // Constants for parsing options - kOpt_set_magic, - kOpt_set_proxy_addr, - kOpt_set_mode, - kOpt_set_password, - kOpt_set_tcp_port, - kOpt_set_tcp_dest_addr, - kOpt_set_tcp_dest_port, - kOpt_set_verbosity, - kOpt_set_max_tunnels, - kOpt_set_non_privileged, - kOpt_set_pcap_device, - kOpt_set_log_file, - kOpt_set_unpriv_user, - kOpt_set_unpriv_group, - kOpt_set_root_dir, - kOpt_set_selinux_context, - kOpt_daemonize, - - kMode_forward = 0, // Ping tunnel's operating mode (client or - kMode_proxy, // proxy) - - kMax_tunnels = 10,/* Set this constant to the number of concurrent - connections you wish to handle by default. */ - - kNo_log = -1, // Different verbosity levels. - kLog_error = 0, + kMode_forward = 0, // Ping tunnel's operating mode (client) + kMode_proxy, // Ping tunnel's operating mode (server) + + /** Set this constant to the number of + * concurrent connections you wish to handle by default. + */ + kMax_tunnels = 10, + + kNo_log = -1, // Different verbosity levels. + kLog_error = 0, kLog_info, kLog_event, kLog_verbose, kLog_debug, kLog_sendrecv, - kMajor_version = 0, // Major (0.xx) and minor (x.70) version - kMinor_version = 72, // numbers. + kMajor_version = 0, // Major (0.xx) and minor (x.70) version + kMinor_version = 72, // numbers. - kIP_packet_max_size = 576, - kIP_header_size = 20, // In bytes, mind you - kIP_actual_size = (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8), - kICMP_header_size = 8, // Also in bytes + kIP_packet_max_size = 576, + kIP_header_size = 20, // In bytes, mind you + kIP_actual_size = (kIP_packet_max_size - kIP_header_size) - ((kIP_packet_max_size - kIP_header_size) % 8), + kICMP_header_size = 8, // Also in bytes - kDefault_buf_size = 1024, /* This constant control the maximum size of - the payload-portion of the ICMP packets - we send. Note that this does not include - the IP or ICMP headers! */ + /** This constant control the maximum size of + * the payload-portion of the ICMP packets + * we send. Note that this does not include + * the IP or ICMP headers! + */ + kDefault_buf_size = 1024, - kICMP_echo_request = 8, // Type code for echo request and replies - kICMP_echo_reply = 0, + kICMP_echo_request = 8, // Type code for echo request and replies + kICMP_echo_reply = 0, - kPing_window_size = 64, // number of packets we can have in our send/receive ring + kPing_window_size = 64, // number of packets we can have in our send/receive ring - /* Tunnels are automatically closed after one minute of inactivity. Since - we continously send acknowledgements between the two peers, this mechanism - won't disconnect "valid" connections. - */ + /** Tunnels are automatically closed after one minute of inactivity. Since + * we continously send acknowledgements between the two peers, this mechanism + * won't disconnect "valid" connections. + */ kAutomatic_close_timeout = 60, // Seconds! kMD5_digest_size = 16, // size of md5 digest in bytes |