From c1023f68217b708b3c1c5f1849f7a4a680e1e012 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Mon, 23 Aug 2021 13:46:42 +0000 Subject: [PATCH] fix regression failing to parse dotted netmask in upstream introduced in 979c737f9b811c5441ae0573a90b72dc1e44e142. when refactoring the "site-spec" parsing code i failed to realize that the code dealing with acl allow/deny directives didn't provide the option to specify netmasks in dotted ipv4 notation, unlike the code in the upstream parser. since both scenarios now use the same parsing, both dotted notation and CIDR slash-notation are possible. while at it, removed the len parameter from fill_netmask_array() which provided the illusion the array length could be of variable size. fixes #394 --- src/hostspec.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/hostspec.c b/src/hostspec.c index adbad53..1f956f2 100644 --- a/src/hostspec.c +++ b/src/hostspec.c @@ -3,6 +3,15 @@ #include "heap.h" #include "network.h" +static int dotted_mask(char *bitmask_string, unsigned char array[]) +{ + unsigned char v4bits[4]; + if (1 != inet_pton (AF_INET, bitmask_string, v4bits)) return -1; + memset (array, 0xff, IPV6_LEN-4); + memcpy (array + IPV6_LEN-4, v4bits, 4); + return 0; +} + /* * Fills in the netmask array given a numeric value. * @@ -13,13 +22,17 @@ */ static int fill_netmask_array (char *bitmask_string, int v6, - unsigned char array[], size_t len) + unsigned char array[]) { unsigned int i; unsigned long int mask; char *endptr; errno = 0; /* to distinguish success/failure after call */ + if (strchr (bitmask_string, '.')) { + if (v6) return -1; /* ipv6 doesn't supported dotted netmasks */ + return dotted_mask(bitmask_string, array); + } mask = strtoul (bitmask_string, &endptr, 10); /* check for various conversion errors */ @@ -35,11 +48,11 @@ fill_netmask_array (char *bitmask_string, int v6, } /* check valid range for a bit mask */ - if (mask > (8 * len)) + if (mask > (8 * IPV6_LEN)) return -1; /* we have a valid range to fill in the array */ - for (i = 0; i != len; ++i) { + for (i = 0; i != IPV6_LEN; ++i) { if (mask >= 8) { array[i] = 0xff; mask -= 8; @@ -88,7 +101,7 @@ int hostspec_parse(char *location, struct hostspec *h) { v6 = 0; if (fill_netmask_array - (mask, v6, &(h->address.ip.mask[0]), IPV6_LEN) + (mask, v6, &(h->address.ip.mask[0])) < 0) goto err;