From b7792fa9d0d742f05175ff9c01d651ad76d525cc Mon Sep 17 00:00:00 2001 From: Ilia Pavlikhin Date: Tue, 24 Sep 2019 15:34:12 +0000 Subject: [PATCH] Add Subnet checking to tinc cli --- src/conf.c | 18 ++++++------------ src/net.c | 23 ++++++++++------------- src/subnet.h | 1 + src/subnet_parse.c | 11 +++++++++++ src/tincctl.c | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/conf.c b/src/conf.c index a33bdfea..4fcf82de 100644 --- a/src/conf.c +++ b/src/conf.c @@ -206,20 +206,14 @@ bool get_config_subnet(const config_t *cfg, subnet_t **result) { return false; } - /* Teach newbies what subnets are... */ - - if(((subnet.type == SUBNET_IPV4) - && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) - || ((subnet.type == SUBNET_IPV6) - && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", - cfg->variable, cfg->file, cfg->line); - return false; + if (subnetcheck(subnet)) { + *(*result = new_subnet()) = subnet; + return true; } - *(*result = new_subnet()) = subnet; - - return true; + logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d", + cfg->variable, cfg->file, cfg->line); + return false; } /* diff --git a/src/net.c b/src/net.c index 22c9d372..8447d04c 100644 --- a/src/net.c +++ b/src/net.c @@ -404,21 +404,18 @@ int reload_configuration(void) { while(cfg) { subnet_t *subnet, *s2; - if(!get_config_subnet(cfg, &subnet)) { - cfg = lookup_config_next(config_tree, cfg); - continue; - } + if(get_config_subnet(cfg, &subnet)) { + if((s2 = lookup_subnet(myself, subnet))) { + if(s2->expires == 1) { + s2->expires = 0; + } - if((s2 = lookup_subnet(myself, subnet))) { - if(s2->expires == 1) { - s2->expires = 0; + free_subnet(subnet); + } else { + subnet_add(myself, subnet); + send_add_subnet(everyone, subnet); + subnet_update(myself, subnet, true); } - - free_subnet(subnet); - } else { - subnet_add(myself, subnet); - send_add_subnet(everyone, subnet); - subnet_update(myself, subnet, true); } cfg = lookup_config_next(config_tree, cfg); diff --git a/src/subnet.h b/src/subnet.h index cfdf2d0b..942853e9 100644 --- a/src/subnet.h +++ b/src/subnet.h @@ -78,6 +78,7 @@ extern void subnet_update(struct node_t *owner, subnet_t *subnet, bool up); extern int maskcmp(const void *a, const void *b, int masklen); extern void maskcpy(void *dest, const void *src, int masklen, int len); extern void mask(void *mask, int masklen, int len); +extern bool subnetcheck(const subnet_t subnet); extern bool maskcheck(const void *mask, int masklen, int len); extern bool net2str(char *netstr, int len, const subnet_t *subnet); extern bool str2net(subnet_t *subnet, const char *netstr); diff --git a/src/subnet_parse.c b/src/subnet_parse.c index d5b84eb6..8616baa1 100644 --- a/src/subnet_parse.c +++ b/src/subnet_parse.c @@ -87,6 +87,17 @@ void maskcpy(void *va, const void *vb, int masklen, int len) { } } +bool subnetcheck(const subnet_t subnet) { + if(((subnet.type == SUBNET_IPV4) + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(subnet.net.ipv4.address))) + || ((subnet.type == SUBNET_IPV6) + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(subnet.net.ipv6.address)))) { + return false; + } + + return true; +} + bool maskcheck(const void *va, int masklen, int len) { int i; const char *a = va; diff --git a/src/tincctl.c b/src/tincctl.c index 08f30189..0beebc21 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -40,6 +40,7 @@ #include "tincctl.h" #include "top.h" #include "version.h" +#include "subnet.h" #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 @@ -1886,6 +1887,19 @@ static int cmd_config(int argc, char *argv[]) { found = true; variable = (char *)variables[i].name; + if (!strcasecmp(variable, "Subnet")) { + subnet_t s = {0}; + + if(!str2net(&s, value)) { + fprintf(stderr, "Malformed subnet definition %s\n", value); + } + + if(!subnetcheck(s)) { + fprintf(stderr, "Network address and prefix length do not match: %s\n", value); + return 1; + } + } + /* Discourage use of obsolete variables. */ if(variables[i].type & VAR_OBSOLETE && action >= 0) { -- 2.20.1