Bug #14299 » t3lib_div_ipv6.patch
class.t3lib_div.php 1 Mar 2006 22:41:45 -0000 | ||
---|---|---|
}
|
||
return implode($implChar,$lines);
|
||
}
|
||
|
||
/**
|
||
* Match IP number with list of numbers with wildcard
|
||
* Dispatcher method for switching into specialised IPv4 and IPv6 methods.
|
||
* Usage: 10
|
||
*
|
||
* @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR
|
||
* @return boolean True if an IP-mask from $list matches $baseIP
|
||
*/
|
||
function cmpIP($baseIP, $list) {
|
||
if(t3lib_div::validIPv6($baseIP)) {
|
||
return t3lib_div::cmpIPv6($baseIP, $list);
|
||
} else {
|
||
return t3lib_div::cmpIPv4($baseIP, $list);
|
||
}
|
||
}
|
||
/**
|
||
* Match IP number with list of numbers with wildcard
|
||
... | ... | |
* @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168)
|
||
* @return boolean True if an IP-mask from $list matches $baseIP
|
||
*/
|
||
function cmpIP($baseIP, $list) {
|
||
function cmpIPv4($baseIP, $list) {
|
||
$IPpartsReq = explode('.',$baseIP);
|
||
if (count($IPpartsReq)==4) {
|
||
$values = t3lib_div::trimExplode(',',$list,1);
|
||
... | ... | |
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Match IPv6 address with a list of IPv6 prefixes
|
||
*
|
||
* @param string $baseIP is the current remote IP address for instance
|
||
* @param string $list is a comma-list of IPv6 prefixes, could also contain IPv4 addresses
|
||
* @return boolean True if an baseIP matches any prefix
|
||
*/
|
||
function cmpIPv6($baseIP, $list) {
|
||
// Policy default: Deny connection
|
||
$success = false;
|
||
$baseIP = t3lib_div::normalizeIPv6($baseIP);
|
||
|
||
$values = t3lib_div::trimExplode(',',$list,1);
|
||
foreach($values as $test) {
|
||
list($test,$mask) = explode('/',$test);
|
||
if(t3lib_div::validIPv6($test)) {
|
||
$test = t3lib_div::normalizeIPv6($test);
|
||
if(intval($mask)) {
|
||
// test on /48 /64
|
||
switch ($mask) {
|
||
case '48':
|
||
$testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 48);
|
||
$baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 48);
|
||
$compare = strcmp($testBin, $baseIPBin);
|
||
$success = ($compare == 0) ? true : false;
|
||
break;
|
||
case '64':
|
||
$testBin = substr(t3lib_div::IPv6Hex2Bin($test), 0, 64);
|
||
$baseIPBin = substr(t3lib_div::IPv6Hex2Bin($baseIP), 0, 64);
|
||
$compare = strcmp($testBin, $baseIPBin);
|
||
$success = ($compare == 0) ? true : false;
|
||
break;
|
||
default:
|
||
$success = false;
|
||
}
|
||
} else {
|
||
// test on full ip address 128 bits
|
||
if(t3lib_div::validIPv6($test)) {
|
||
$testBin = t3lib_div::IPv6Hex2Bin($test);
|
||
$baseIPBin = t3lib_div::IPv6Hex2Bin($baseIP);
|
||
$compare = strcmp($testBin, $baseIPBin);
|
||
$success = ($compare == 0) ? true : false;
|
||
}
|
||
}
|
||
}
|
||
if ($success == true) return $success;
|
||
}
|
||
return $success;
|
||
}
|
||
|
||
/**
|
||
* Converts a IPv6 address from hex format to binary format.
|
||
*
|
||
* @param string $hex IPv6 address hex format
|
||
* @return string IPv6 address binary format
|
||
*/
|
||
function IPv6Hex2Bin ($hex) {
|
||
$bin = '';
|
||
// first replace colon to nothing
|
||
$hex = preg_replace('/:/', '', $hex);
|
||
for($i = 0; $i < strlen($hex); $i = $i+2) {
|
||
$bin .= chr(hexdec(substr($hex, $i, 2)));
|
||
}
|
||
return $bin;
|
||
}
|
||
|
||
/**
|
||
* Normalizes a given IPv6 address to full length
|
||
*
|
||
* @param string Given IPv6 address
|
||
* @return string Normalized address
|
||
*/
|
||
function normalizeIPv6($address) {
|
||
$normalizedAddress = '';
|
||
$stageOneAddress = '';
|
||
/* check if address has hidden zero blocks */
|
||
/* if so, count is 2 */
|
||
$chunks = explode('::', $address);
|
||
if(count($chunks) == 2) {
|
||
$chunksLeft = explode(':', $chunks[0]);
|
||
$chunksRight = explode(':', $chunks[1]);
|
||
$left = count($chunksLeft);
|
||
$right = count($chunksRight);
|
||
/* specialcase: leading zero-only blocks count to 1, should be 0 */
|
||
if(($left == 1) && (strlen($chunksLeft[0]) == 0)) { $left = 0; }
|
||
$hiddenBlocks = 8 - ($left + $right);
|
||
$hiddenPart = '';
|
||
$h = 0;
|
||
while($h < $hiddenBlocks) {
|
||
$hiddenPart .= '0000:';
|
||
$h++;
|
||
}
|
||
if($left == 0) { $stageOneAddress = $hiddenPart . $chunks[1]; }
|
||
else { $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1]; }
|
||
} else { $stageOneAddress = $address; }
|
||
/* now normalize the blocks */
|
||
$blocks = explode(':', $stageOneAddress);
|
||
$divCounter = 0;
|
||
foreach($blocks as $block) {
|
||
$tmpBlock = '';
|
||
$i = 0;
|
||
$hiddenZeros = 4 - strlen($block);
|
||
while($i < $hiddenZeros) {
|
||
$tmpBlock .= '0';
|
||
$i++;
|
||
}
|
||
$normalizedAddress .= $tmpBlock . $block;
|
||
if($divCounter < 7) {
|
||
$normalizedAddress .= ':';
|
||
$divCounter++;
|
||
}
|
||
}
|
||
return $normalizedAddress;
|
||
}
|
||
|
||
/**
|
||
* Validate a given ip address to the IPv6 address format.
|
||
*
|
||
* @param string The given ip address.
|
||
* @return boolean True if the given address is an IPv6 format.
|
||
*/
|
||
function validIPv6($ip) {
|
||
/* e.g. possible formats
|
||
* 43FB::BB3F:A0A0:0 | ::1
|
||
*/
|
||
$valid = false;
|
||
$uppercaseIP = strtoupper($ip);
|
||
$regex = "/^(";
|
||
$regex .= "(([\dA-F]{1,4}:){7}[\dA-F]{1,4})|";
|
||
$regex .= "(([\dA-F]{1,4}){1}::([\dA-F]{1,4}:){1,5}[\dA-F]{1,4})|";
|
||
$regex .= "(([\dA-F]{1,4}:){2}:([\dA-F]{1,4}:){1,4}[\dA-F]{1,4})|";
|
||
$regex .= "(([\dA-F]{1,4}:){3}:([\dA-F]{1,4}:){1,3}[\dA-F]{1,4})|";
|
||
$regex .= "(([\dA-F]{1,4}:){4}:([\dA-F]{1,4}:){1,2}[\dA-F]{1,4})|";
|
||
$regex .= "(([\dA-F]{1,4}:){5}:([\dA-F]{1,4}:){0,1}[\dA-F]{1,4})|";
|
||
$regex .= "(::([\dA-F]{1,4}:){0,6}[\dA-F]{1,4})";
|
||
$regex .= ")$/";
|
||
if(preg_match($regex, $uppercaseIP)) { $valid = true; }
|
||
return $valid;
|
||
}
|
||
/**
|
||
* Match fully qualified domain name with list of strings with wildcard
|