# HG changeset patch # User Timo Sirainen # Date 1214031266 -10800 # Node ID 423b8e3fedbb34091c618e449c9c85ae79a267f1 # Parent b1784b48821de1d65ab43979f52c5fb09a069ed0 Created net_parse_range() from auth code. diff -r b1784b48821d -r 423b8e3fedbb src/auth/auth-request.c --- a/src/auth/auth-request.c Sat Jun 21 09:52:26 2008 +0300 +++ b/src/auth/auth-request.c Sat Jun 21 09:54:26 2008 +0300 @@ -868,38 +868,12 @@ 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 @@ 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 -r b1784b48821d -r 423b8e3fedbb src/lib/network.c --- a/src/lib/network.c Sat Jun 21 09:52:26 2008 +0300 +++ b/src/lib/network.c Sat Jun 21 09:54:26 2008 +0300 @@ -5,6 +5,7 @@ #include "fd-set-nonblock.h" #include "network.h" +#include #include #include #include @@ -704,13 +705,46 @@ 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 -r b1784b48821d -r 423b8e3fedbb src/lib/network.h --- a/src/lib/network.h Sat Jun 21 09:52:26 2008 +0300 +++ b/src/lib/network.h Sat Jun 21 09:54:26 2008 +0300 @@ -110,7 +110,11 @@ 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;