diff --git a/common.c b/common.c index 0c5244e..bc405b6 100644 --- a/common.c +++ b/common.c @@ -355,7 +355,7 @@ void init_cnx(struct connection *cnx) memset(cnx, 0, sizeof(*cnx)); cnx->q[0].fd = -1; cnx->q[1].fd = -1; - cnx->proto = get_first_protocol(); + cnx->proto = NULL; } void dump_connection(struct connection *cnx) diff --git a/probe.c b/probe.c index ca4c152..aaf4ac8 100644 --- a/probe.c +++ b/probe.c @@ -43,11 +43,6 @@ static int is_adb_protocol(const char *p, int len, struct sslhcfg_protocols_item static int is_socks5_protocol(const char *p, int len, struct sslhcfg_protocols_item*); static int is_true(const char *p, int len, struct sslhcfg_protocols_item* proto) { return 1; } -struct protocol_probe_desc { - const char* name; - T_PROBE* probe; -}; - /* Table of protocols that have a built-in probe */ static struct protocol_probe_desc builtins[] = { @@ -64,12 +59,11 @@ static struct protocol_probe_desc builtins[] = { { "anyprot", is_true } }; -static struct sslhcfg_protocols_item *protocols; static char* on_timeout = "ssh"; /* TODO I think this has to go */ -struct sslhcfg_protocols_item* get_builtins(void) { - return NULL; +struct protocol_probe_desc* get_builtins(void) { + return builtins; } int get_num_builtins(void) { @@ -90,24 +84,11 @@ struct sslhcfg_protocols_item* timeout_protocol(void) { int i; for (i = 0; i < cfg.protocols_len; i++) { - printf("prot %d:%s vs %s\n",i, cfg.protocols[i].name, on_timeout); if (!strcmp(cfg.protocols[i].name, on_timeout)) return &cfg.protocols[i]; } - return get_first_protocol(); + return &cfg.protocols[0]; } -/* returns the first protocol (caller can then follow the *next pointers) */ -struct sslhcfg_protocols_item* get_first_protocol(void) -{ - return protocols; -} - -void set_protocol_list(struct sslhcfg_protocols_item* prots) -{ -#if 0 - protocols = prots; -#endif -} /* From http://grapsus.net/blog/post/Hexadecimal-dump-in-C */ #define HEXDUMP_COLS 16 @@ -355,7 +336,7 @@ static int regex_probe(const char *p, int len, struct sslhcfg_protocols_item* pr int probe_client_protocol(struct connection *cnx) { char buffer[BUFSIZ]; - struct sslhcfg_protocols_item* p, *last_p = cnx->proto; + struct sslhcfg_protocols_item* p; int i, n, res, again = 0; n = read(cnx->q[0].fd, buffer, sizeof(buffer)); diff --git a/probe.h b/probe.h index 7119789..5ee199c 100644 --- a/probe.h +++ b/probe.h @@ -15,31 +15,16 @@ typedef enum { struct sslhcfg_protocols_item; typedef int T_PROBE(const char*, int, struct sslhcfg_protocols_item*); +struct protocol_probe_desc { + const char* name; + T_PROBE* probe; +}; + + #include "sslh-conf.h" -/* For each protocol we need: */ -#if 0 -struct proto { - const char* description; /* a string that says what it is (for logging and command-line parsing) */ - const char* service; /* service name to do libwrap checks */ - struct addrinfo *saddr; /* list of addresses to try and switch that protocol */ - int log_level; /* 0: No logging of connection - * 1: Log incoming connection - */ - int keepalive; /* 0: No keepalive ; 1: Set Keepalive for this connection */ - int fork; /* 0: Connection can run within shared process ; 1: Separate process required for this connection */ - - /* function to probe that protocol; parameters are buffer and length - * containing the data to probe, and a pointer to the protocol structure */ - T_PROBE* probe; - /* opaque pointer ; used to pass list of regex to regex probe, or TLSProtocol struct to sni/alpn probe */ - void* data; - struct proto *next; /* pointer to next protocol in list, NULL if last */ -}; -#endif - /* Returns a pointer to the array of builtin protocols */ -struct sslhcfg_protocols_item* get_builtins(void); +struct protocol_probe_desc* get_builtins(void); /* Returns the number of builtin protocols */ int get_num_builtins(void); diff --git a/sslh-conf.c b/sslh-conf.c index e4fecdf..c5afa62 100644 --- a/sslh-conf.c +++ b/sslh-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct) - * on Tue Dec 4 21:49:45 2018. */ + * on Fri Dec 7 08:27:14 2018. */ diff --git a/sslh-conf.h b/sslh-conf.h index f0d4046..9b1a3d8 100644 --- a/sslh-conf.h +++ b/sslh-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct) - * on Tue Dec 4 21:49:45 2018. */ + * on Fri Dec 7 08:27:14 2018. */ #ifndef C2S_SSLHCFG_H diff --git a/sslh-main.c b/sslh-main.c index b61ead8..4c715c2 100644 --- a/sslh-main.c +++ b/sslh-main.c @@ -62,14 +62,12 @@ const char* USAGE_STRING = /* Constants for options that have no one-character shorthand */ #define OPT_ONTIMEOUT 257 - /* static struct option const_options[] = { - { "inetd", no_argument, &inetd, 1 }, - { "foreground", no_argument, &foreground, 1 }, - { "background", no_argument, &background, 1 }, - { "transparent", no_argument, &transparent, 1 }, - { "numeric", no_argument, &numeric, 1 }, - { "verbose", no_argument, &verbose, 1 }, + { "inetd", no_argument, &cfg.inetd, 1 }, + { "foreground", no_argument, &cfg.foreground, 1 }, + { "transparent", no_argument, &cfg.transparent, 1 }, + { "numeric", no_argument, &cfg.numeric, 1 }, + { "verbose", no_argument, &cfg.verbose, 1 }, { "user", required_argument, 0, 'u' }, { "config", optional_argument, 0, 'F' }, { "pidfile", required_argument, 0, 'P' }, @@ -79,16 +77,16 @@ static struct option const_options[] = { { "listen", required_argument, 0, 'p' }, {} }; - */ + static struct option* all_options; -static struct sslhcfg_protocols_item* builtins; +static struct protocol_probe_desc* builtins; static const char *optstr = "vt:T:p:VP:C:F::"; static void print_usage(void) { - struct sslhcfg_protocols_item *p; + struct protocol_probe_desc *p; int i; int res; char *prots = ""; @@ -302,7 +300,7 @@ static int config_parse(char *filename, struct addrinfo **listen) * prot: array of protocols * n_prots: number of protocols in *prot * */ -static void append_protocols(struct option *options, int n_opts, struct sslhcfg_protocols_item *prot , int n_prots) +static void append_protocols(struct option *options, int n_opts, struct protocol_probe_desc* prot , int n_prots) { int o, p; @@ -316,7 +314,6 @@ static void append_protocols(struct option *options, int n_opts, struct sslhcfg_ static void make_alloptions(void) { -#if 0 builtins = get_builtins(); /* Create all_options, composed of const_options followed by one option per @@ -325,7 +322,6 @@ static void make_alloptions(void) CHECK_ALLOC(all_options, "calloc"); memcpy(all_options, const_options, sizeof(const_options)); append_protocols(all_options, ARRAY_SIZE(const_options) - 1, builtins, get_num_builtins()); -#endif } /* Performs a first scan of command line options to see if a configuration file @@ -378,11 +374,9 @@ static void cmdline_config(int argc, char* argv[], struct sslhcfg_protocols_item * potentially non-allocated */ static void parse_cmdline(int argc, char* argv[], struct sslhcfg_protocols_item* prots) { -#if 0 int c; struct addrinfo **a; - struct sslhcfg_protocols_item *p; - int background; + int background, i; optind = 1; opterr = 1; @@ -391,29 +385,25 @@ next_arg: if (c == 0) continue; if (c >= PROT_SHIFT) { - if (prots) - for (p = prots; p && p->next; p = p->next) { - /* override if protocol was already defined by config file - * (note it only overrides address and use builtin probe) */ - if (!strcmp(p->name, builtins[c-PROT_SHIFT].name)) { - resolve_name(&(p->saddr), optarg); - p->probe = builtins[c-PROT_SHIFT].probe; - goto next_arg; - } + int prot_num = c - PROT_SHIFT; + for (i = 0; i < cfg.protocols_len; i++) { + /* override if protocol was already defined by config file */ + if (!strcmp(cfg.protocols[i].name, builtins[prot_num].name)) { + resolve_name(&(cfg.protocols[i].saddr), optarg); + goto next_arg; } + } /* At this stage, it's a new protocol: add it to the end of the * list */ - if (!prots) { - /* No protocols yet -- create the list */ - p = prots = calloc(1, sizeof(*p)); - CHECK_ALLOC(p, "calloc"); - } else { - p->next = calloc(1, sizeof(*p)); - CHECK_ALLOC(p->next, "calloc"); - p = p->next; - } - memcpy(p, &builtins[c-PROT_SHIFT], sizeof(*p)); - resolve_name(&(p->saddr), optarg); + cfg.protocols_len++; + cfg.protocols = realloc(cfg.protocols, cfg.protocols_len * sizeof(*cfg.protocols)); + CHECK_ALLOC(cfg.protocols, "realloc"); + + /* set up name, target and probe. everything else defaults to 0 */ + memset(&cfg.protocols[cfg.protocols_len-1], 0, sizeof(cfg.protocols[0])); + cfg.protocols[cfg.protocols_len-1].probe = get_probe(builtins[prot_num].name); + cfg.protocols[cfg.protocols_len-1].name = builtins[prot_num].name; + resolve_name(&cfg.protocols[cfg.protocols_len-1].saddr, optarg); continue; } @@ -422,12 +412,14 @@ next_arg: case 'F': /* Legal option, but do nothing, it was already processed in * cmdline_config() */ +#ifndef LIBCONFIG fprintf(stderr, "Built without libconfig support: configuration file not available.\n"); exit(1); +#endif break; case 't': - probing_timeout = atoi(optarg); + cfg.timeout = atoi(optarg); break; case OPT_ONTIMEOUT: @@ -447,19 +439,19 @@ next_arg: exit(0); case 'u': - user_name = optarg; + cfg.user = optarg; break; case 'P': - pid_file = optarg; + cfg.pidfile = optarg; break; case 'C': - chroot_path = optarg; + cfg.chroot = optarg; break; case 'v': - verbose++; + cfg.verbose++; break; default: @@ -470,15 +462,11 @@ next_arg: return; - if (!prots) { + if (!cfg.protocols_len) { fprintf(stderr, "At least one target protocol must be specified.\n"); exit(2); } - /* - set_protocol_list(prots); - */ - /* If compiling with systemd socket support no need to require listen address */ #ifndef SYSTEMD if (!addr_listen && !cfg.inetd) { @@ -491,7 +479,6 @@ next_arg: if (background) cfg.foreground = 0; -#endif } int main(int argc, char *argv[]) @@ -504,10 +491,13 @@ int main(int argc, char *argv[]) int *listen_sockets; - /* Init defaults */ + /* Init defaults -- conf2struct sets them when parsing a config file + * but we may configure entirely from the command line */ cfg.pidfile = NULL; cfg.user = NULL; cfg.chroot = NULL; + cfg.syslog_facility = "auth"; + cfg.timeout = 2; cmdline_config(argc, argv, &protocols); parse_cmdline(argc, argv, protocols);