Skip to content

Commit 5962ae9

Browse files
author
Marius Burkard
committed
Merge branch 'feature/admin_ip_whitelist_ipv6' into 'develop'
Add IPv6 support for admin IP whitelist feature. See merge request ispconfig/ispconfig3!1557
2 parents c8c0fc4 + f0527d1 commit 5962ae9

File tree

1 file changed

+43
-8
lines changed

1 file changed

+43
-8
lines changed

interface/web/login/index.php

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,32 +190,67 @@ function is_admin_ip_whitelisted($ip, $conf)
190190
// exclude empty lines and comments
191191
if ($line === '' || $line[0] === '#') return false;
192192

193-
return ip_matches_cidr($ip, $line);
193+
return ipv6_matches_cidr($ip, $line) || ipv4_matches_cidr($ip, $line);
194194
});
195195

196196
return count($matches) > 0;
197197
}
198198

199199
// based on https://www.php.net/manual/en/ref.network.php (comments)
200200
/**
201-
* Checks if the given IP address matches the given CIDR.
202-
* @param $ip
203-
* @param $cidr
204-
201+
* Checks if the given IPv4 address matches the given CIDR.
202+
* @param string $ip The IPv4 address.
203+
* @param string $cidr The CIDR in the IPv4 format.
205204
* @return bool
206205
*/
207-
function ip_matches_cidr ($ip, $cidr) {
206+
function ipv4_matches_cidr ($ip, $cidr)
207+
{
208+
if (strpos($ip, '.') === false) return false;
209+
208210
list ($net, $mask) = explode ('/', $cidr);
209211
if (!$mask) $mask = 32;
210212

211213
$ip_net = ip2long ($net);
212-
$ip_mask = ~((1 << (32 - $mask)) - 1);
213-
214214
$ip_ip = ip2long ($ip);
215+
$ip_mask = ~((1 << (32 - $mask)) - 1);
215216

216217
return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask));
217218
}
218219

220+
// based on https://stackoverflow.com/a/7951507/2428861
221+
/**
222+
* Checks if the given IPv6 address matches the given CIDR.
223+
* @param string $ip The IPv6 address.
224+
* @param string $cidr The CIDR in the IPv6 format.
225+
* @return bool
226+
*/
227+
function ipv6_matches_cidr($ip, $cidr)
228+
{
229+
if (strpos($ip, ':') === false) return false;
230+
231+
list ($net, $mask) = explode('/', $cidr);
232+
if (!$mask) $mask = 128;
233+
234+
$ip_net = in_addr_to_bitstring(inet_pton($net));
235+
$ip_ip = in_addr_to_bitstring(inet_pton($ip));
236+
237+
return substr($ip_ip, 0, $mask) === substr($ip_net, 0, $mask);
238+
}
239+
240+
/**
241+
* Converts the output of {@see inet_pton()} to string of bits.
242+
* @param string $in_addr The in_addr representation of the IP address.
243+
* @return string String of bits representing given in_addr representation of the IP address.
244+
*/
245+
function in_addr_to_bitstring($in_addr)
246+
{
247+
$result = '';
248+
foreach (str_split($in_addr) as $c) {
249+
$result .= str_pad(decbin(ord($c)), 8, '0', STR_PAD_LEFT);
250+
}
251+
return $result;
252+
}
253+
219254
/**
220255
* Validates user credentials and fetches the user if validation succeeded
221256
* @param app $app

0 commit comments

Comments
 (0)