From: Timo Sirainen Date: Sat, 21 Jun 2008 06:54:26 +0000 (+0300) Subject: Created net_parse_range() from auth code. X-Git-Tag: 1.2.alpha1~242 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ddd9e8f975f6d7dbfed1e3837da9842288c2585a;p=thirdparty%2Fdovecot%2Fcore.git Created net_parse_range() from auth code. --HG-- branch : HEAD --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 747fc2e5bb..efa2b5fd6b 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -868,38 +868,12 @@ bool auth_request_set_login_username(struct auth_request *request, return request->requested_login_user != NULL; } -static int is_ip_in_network(const char *network, const struct ip_addr *ip) -{ - struct ip_addr src_ip, net_ip; - const char *p; - unsigned int max_bits, bits; - - if (net_ipv6_mapped_ipv4_convert(ip, &src_ip) == 0) - ip = &src_ip; - - max_bits = IPADDR_IS_V4(ip) ? 32 : 128; - p = strchr(network, '/'); - if (p == NULL) { - /* full IP address must match */ - bits = max_bits; - } else { - /* get the network mask */ - network = t_strdup_until(network, p); - bits = strtoul(p+1, NULL, 10); - if (bits > max_bits) - bits = max_bits; - } - - if (net_addr2ip(network, &net_ip) < 0) - return -1; - - return net_is_in_network(ip, &net_ip, bits); -} - static void auth_request_validate_networks(struct auth_request *request, const char *networks) { const char *const *net; + struct ip_addr net_ip; + unsigned int bits; bool found = FALSE; if (request->remote_ip.family == 0) { @@ -913,15 +887,14 @@ static void auth_request_validate_networks(struct auth_request *request, for (net = t_strsplit_spaces(networks, ", "); *net != NULL; net++) { auth_request_log_debug(request, "auth", "allow_nets: Matching for network %s", *net); - switch (is_ip_in_network(*net, &request->remote_ip)) { - case 1: - found = TRUE; - break; - case -1: + + if (net_parse_range(*net, &net_ip, &bits) < 0) { auth_request_log_info(request, "passdb", "allow_nets: Invalid network '%s'", *net); - break; - default: + } + + if (net_is_in_network(&request->remote_ip, &net_ip, bits)) { + found = TRUE; break; } } diff --git a/src/lib/network.c b/src/lib/network.c index 857f4d703c..33617e9a49 100644 --- a/src/lib/network.c +++ b/src/lib/network.c @@ -5,6 +5,7 @@ #include "fd-set-nonblock.h" #include "network.h" +#include #include #include #include @@ -704,13 +705,46 @@ bool is_ipv6_address(const char *addr) return TRUE; } +int net_parse_range(const char *network, struct ip_addr *ip_r, + unsigned int *bits_r) +{ + const char *p; + int bits, max_bits; + + p = strchr(network, '/'); + if (p != NULL) + network = t_strdup_until(network, p++); + + if (net_addr2ip(network, ip_r) < 0) + return -1; + + max_bits = IPADDR_IS_V4(ip_r) ? 32 : 128; + if (p == NULL) { + /* full IP address must match */ + bits = max_bits; + } else { + /* get the network mask */ + bits = atoi(p); + if (bits < 0 || bits > max_bits) + return -1; + } + *bits_r = bits; + return 0; +} + bool net_is_in_network(const struct ip_addr *ip, const struct ip_addr *net_ip, unsigned int bits) { + struct ip_addr tmp_ip; const uint32_t *ip1, *ip2; uint32_t mask, i1, i2; unsigned int pos, i; + if (net_ipv6_mapped_ipv4_convert(ip, &tmp_ip) == 0) { + /* IPv4 address mapped disguised as IPv6 address */ + ip = &tmp_ip; + } + if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) { /* one is IPv6 and one is IPv4 */ return FALSE; diff --git a/src/lib/network.h b/src/lib/network.h index 5011443be7..a72a685a50 100644 --- a/src/lib/network.h +++ b/src/lib/network.h @@ -110,7 +110,11 @@ const char *net_getservbyport(unsigned short port) ATTR_CONST; bool is_ipv4_address(const char *addr) ATTR_PURE; bool is_ipv6_address(const char *addr) ATTR_PURE; -/* Returns TRUE if ip is in net_ip/bits network. */ +/* Parse network as ip/bits. Returns 0 if successful, -1 if invalid input. */ +int net_parse_range(const char *network, struct ip_addr *ip_r, + unsigned int *bits_r); +/* Returns TRUE if ip is in net_ip/bits network. IPv6 mapped IPv4 addresses + are converted to plain IPv4 addresses before matching. */ bool net_is_in_network(const struct ip_addr *ip, const struct ip_addr *net_ip, unsigned int bits) ATTR_PURE;