From 0d10807a75e54515b0efb18a48678c16b8263ab9 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Wed, 5 Oct 2016 11:53:26 +1000 Subject: [PATCH] * source/portknock: update config() --- src/sources/portknock.c | 66 ++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/src/sources/portknock.c b/src/sources/portknock.c index 7b3164c..3554711 100644 --- a/src/sources/portknock.c +++ b/src/sources/portknock.c @@ -6,6 +6,7 @@ */ #include "source.h" +#include #include #include #include @@ -28,6 +29,41 @@ struct _config { f2b_port_t *current; }; +static bool +try_parse_listen_opt(f2b_port_t *port, const char *value) { + char buf[256]; + char *p; + + strlcpy(buf, value, sizeof(buf)); + if (*buf == '[') { + /* IPv6, expected: [XXXX::XXXX:XXXX]:YYYY */ + if ((p = strstr(buf, "]:")) == NULL) { + *p = '\0', p += 2; + strlcpy(port->port, p, sizeof(port->port)); + p = buf + 1; + strlcpy(port->host, p, sizeof(port->host)); + return true; + } + return false; /* can't find port */ + } + if ((p = strchr(buf, ':')) != NULL) { + /* IPv4, expected: XX.XX.XX.XX:YYYY */ + *p = '\0', p += 1; + strlcpy(port->port, p, sizeof(port->port)); + p = buf; + strlcpy(port->host, p, sizeof(port->host)); + return true; + } + if (isdigit(*buf) && strlen(buf) <= 5) { + /* IPv4, expected: YYYY */ + strlcpy(port->host, "0.0.0.0", sizeof(port->host)); + strlcpy(port->port, buf, sizeof(port->port)); + return true; + } + + return false; +} + static void errcb_stub(char *str) { assert(str != NULL); @@ -52,31 +88,19 @@ config(cfg_t *cfg, const char *key, const char *value) { assert(value != NULL); if (strcmp(key, "listen") == 0) { - void *buf = NULL; - if (strchr(value, ':') == NULL) { - cfg->listen_af = AF_INET; - buf = &cfg->listen_addr.v4; - } else { - cfg->listen_af = AF_INET6; - buf = &cfg->listen_addr.v6; - } - if (inet_pton(cfg->listen_af, value, buf) <= 0) { - snprintf(cfg->error, sizeof(cfg->error), "invalid listen address: %s", value); - return false; - } - return true; - } - if (strcmp(key, "port") == 0) { - if (cfg->ports_used >= MAX_PORTS) { - strlcpy(cfg->error, "max ports number reached in this portknock instance", sizeof(cfg->error)); + f2b_port_t *port = NULL; + if ((port = calloc(1, sizeof(f2b_port_t))) == NULL) { + strlcpy(cfg->error, "out of memory", sizeof(cfg->error)); return false; } - cfg->ports[cfg->ports_used] = atoi(value); - if (cfg->ports[cfg->ports_used] == 0) { - snprintf(cfg->error, sizeof(cfg->error), "invalid port number: %s", value); + if (try_parse_listen_opt(port, value) == false) { + snprintf(cfg->error, sizeof(cfg->error), "can't parse: %s", value); + free(port); return false; } - cfg->ports_used++; + port->next = cfg->ports; + cfg->ports = port; + return true; } return false;