mirror of
https://github.com/phpbb/phpbb.git
synced 2025-02-24 20:13:22 +01:00
Merge branch 'ticket/bantu/9746' into develop
This commit is contained in:
commit
da4617b14b
@ -56,7 +56,7 @@ class acp_users
|
||||
$this->page_title = 'WHOIS';
|
||||
$this->tpl_name = 'simple_body';
|
||||
|
||||
$user_ip = request_var('user_ip', '');
|
||||
$user_ip = phpbb_ip_normalise(request_var('user_ip', ''));
|
||||
$domain = gethostbyaddr($user_ip);
|
||||
$ipwhois = user_ipwhois($user_ip);
|
||||
|
||||
|
@ -3280,6 +3280,188 @@ function short_ipv6($ip, $length)
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalises an internet protocol address,
|
||||
* also checks whether the specified address is valid.
|
||||
*
|
||||
* IPv4 addresses are returned 'as is'.
|
||||
*
|
||||
* IPv6 addresses are normalised according to
|
||||
* A Recommendation for IPv6 Address Text Representation
|
||||
* http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07
|
||||
*
|
||||
* @param string $address IP address
|
||||
*
|
||||
* @return mixed false if specified address is not valid,
|
||||
* string otherwise
|
||||
*
|
||||
* @author bantu
|
||||
*/
|
||||
function phpbb_ip_normalise($address)
|
||||
{
|
||||
$address = trim($address);
|
||||
|
||||
if (empty($address) || !is_string($address))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match(get_preg_expression('ipv4'), $address))
|
||||
{
|
||||
return $address;
|
||||
}
|
||||
|
||||
return phpbb_inet_ntop(phpbb_inet_pton($address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for inet_ntop()
|
||||
*
|
||||
* Converts a packed internet address to a human readable representation
|
||||
* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
|
||||
*
|
||||
* @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
|
||||
*
|
||||
* @return mixed false on failure,
|
||||
* string otherwise
|
||||
*
|
||||
* @author APTX
|
||||
*/
|
||||
function phpbb_inet_ntop($in_addr)
|
||||
{
|
||||
$in_addr = bin2hex($in_addr);
|
||||
|
||||
switch (strlen($in_addr))
|
||||
{
|
||||
case 8:
|
||||
return implode('.', array_map('hexdec', str_split($in_addr, 2)));
|
||||
|
||||
case 32:
|
||||
if (substr($in_addr, 0, 24) === '00000000000000000000ffff')
|
||||
{
|
||||
return phpbb_inet_ntop(pack('H*', substr($in_addr, 24)));
|
||||
}
|
||||
|
||||
$parts = str_split($in_addr, 4);
|
||||
$parts = preg_replace('/^0+(?!$)/', '', $parts);
|
||||
$ret = implode(':', $parts);
|
||||
|
||||
$matches = array();
|
||||
preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE);
|
||||
$matches = $matches[0];
|
||||
|
||||
if (empty($matches))
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$longest_match = '';
|
||||
$longest_match_offset = 0;
|
||||
foreach ($matches as $match)
|
||||
{
|
||||
if (strlen($match[0]) > strlen($longest_match))
|
||||
{
|
||||
$longest_match = $match[0];
|
||||
$longest_match_offset = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
$ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match));
|
||||
|
||||
if ($longest_match_offset == strlen($ret))
|
||||
{
|
||||
$ret .= ':';
|
||||
}
|
||||
|
||||
if ($longest_match_offset == 0)
|
||||
{
|
||||
$ret = ':' . $ret;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for inet_pton()
|
||||
*
|
||||
* Converts a human readable IP address to its packed in_addr representation
|
||||
* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
|
||||
*
|
||||
* @param string $address A human readable IPv4 or IPv6 address.
|
||||
*
|
||||
* @return mixed false if address is invalid,
|
||||
* in_addr representation of the given address otherwise (string)
|
||||
*
|
||||
* @author APTX
|
||||
*/
|
||||
function phpbb_inet_pton($address)
|
||||
{
|
||||
$ret = '';
|
||||
if (preg_match(get_preg_expression('ipv4'), $address))
|
||||
{
|
||||
foreach (explode('.', $address) as $part)
|
||||
{
|
||||
$ret .= ($part <= 0xF ? '0' : '') . dechex($part);
|
||||
}
|
||||
|
||||
return pack('H*', $ret);
|
||||
}
|
||||
|
||||
if (preg_match(get_preg_expression('ipv6'), $address))
|
||||
{
|
||||
$parts = explode(':', $address);
|
||||
$missing_parts = 8 - sizeof($parts) + 1;
|
||||
|
||||
if (substr($address, 0, 2) === '::')
|
||||
{
|
||||
++$missing_parts;
|
||||
}
|
||||
|
||||
if (substr($address, -2) === '::')
|
||||
{
|
||||
++$missing_parts;
|
||||
}
|
||||
|
||||
$embedded_ipv4 = false;
|
||||
$last_part = end($parts);
|
||||
|
||||
if (preg_match(get_preg_expression('ipv4'), $last_part))
|
||||
{
|
||||
$parts[sizeof($parts) - 1] = '';
|
||||
$last_part = phpbb_inet_pton($last_part);
|
||||
$embedded_ipv4 = true;
|
||||
--$missing_parts;
|
||||
}
|
||||
|
||||
foreach ($parts as $i => $part)
|
||||
{
|
||||
if (strlen($part))
|
||||
{
|
||||
$ret .= str_pad($part, 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
else if ($i && $i < sizeof($parts) - 1)
|
||||
{
|
||||
$ret .= str_repeat('0000', $missing_parts);
|
||||
}
|
||||
}
|
||||
|
||||
$ret = pack('H*', $ret);
|
||||
|
||||
if ($embedded_ipv4)
|
||||
{
|
||||
$ret .= $last_part;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for php's checkdnsrr function.
|
||||
*
|
||||
|
@ -279,6 +279,24 @@ class session
|
||||
|
||||
foreach ($ips as $ip)
|
||||
{
|
||||
if (function_exists('phpbb_ip_normalise'))
|
||||
{
|
||||
// Normalise IP address
|
||||
$ip = phpbb_ip_normalise($ip);
|
||||
|
||||
if (empty($ip))
|
||||
{
|
||||
// IP address is invalid.
|
||||
break;
|
||||
}
|
||||
|
||||
// IP address is valid.
|
||||
$this->ip = $ip;
|
||||
|
||||
// Skip legacy code.
|
||||
continue;
|
||||
}
|
||||
|
||||
// check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
|
||||
if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
|
||||
{
|
||||
|
@ -127,8 +127,11 @@ $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
|
||||
// We do not need this any longer, unset for safety purposes
|
||||
unset($dbpasswd);
|
||||
|
||||
$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
|
||||
$user->ip = (stripos($user->ip, '::ffff:') === 0) ? substr($user->ip, 7) : $user->ip;
|
||||
$user->ip = '';
|
||||
if (!empty($_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$user->ip = (function_exists('phpbb_ip_normalise')) ? phpbb_ip_normalise($_SERVER['REMOTE_ADDR']) : htmlspecialchars($_SERVER['REMOTE_ADDR']);
|
||||
}
|
||||
|
||||
$sql = "SELECT config_value
|
||||
FROM " . CONFIG_TABLE . "
|
||||
|
@ -1235,8 +1235,7 @@ class install_install extends module
|
||||
|
||||
$current_time = time();
|
||||
|
||||
$user_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
|
||||
$user_ip = (stripos($user_ip, '::ffff:') === 0) ? substr($user_ip, 7) : $user_ip;
|
||||
$user_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? phpbb_ip_normalise($_SERVER['REMOTE_ADDR']) : '';
|
||||
|
||||
if ($data['script_path'] !== '/')
|
||||
{
|
||||
|
@ -16,6 +16,8 @@ require_once 'test_framework/framework.php';
|
||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||
|
||||
require_once 'network/checkdnsrr.php';
|
||||
require_once 'network/inet_ntop_pton.php';
|
||||
require_once 'network/ip_normalise.php';
|
||||
|
||||
class phpbb_network_all_tests
|
||||
{
|
||||
@ -29,6 +31,8 @@ class phpbb_network_all_tests
|
||||
$suite = new PHPUnit_Framework_TestSuite('phpBB Network Functions');
|
||||
|
||||
$suite->addTestSuite('phpbb_network_checkdnsrr_test');
|
||||
$suite->addTestSuite('phpbb_network_inet_ntop_pton_test');
|
||||
$suite->addTestSuite('phpbb_network_ip_normalise_test');
|
||||
|
||||
return $suite;
|
||||
}
|
||||
|
55
tests/network/inet_ntop_pton.php
Normal file
55
tests/network/inet_ntop_pton.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @package testing
|
||||
* @copyright (c) 2010 phpBB Group
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
*
|
||||
*/
|
||||
|
||||
require_once 'test_framework/framework.php';
|
||||
require_once '../phpBB/includes/functions.php';
|
||||
|
||||
class phpbb_network_inet_ntop_pton_test extends phpbb_test_case
|
||||
{
|
||||
public function data_provider()
|
||||
{
|
||||
return array(
|
||||
array('127.0.0.1', '7f000001'),
|
||||
array('192.232.131.223', 'c0e883df'),
|
||||
array('13.1.68.3', '0d014403'),
|
||||
array('129.144.52.38', '81903426'),
|
||||
|
||||
array('2001:280:0:10::5', '20010280000000100000000000000005'),
|
||||
array('fe80::200:4cff:fefe:172f', 'fe8000000000000002004cfffefe172f'),
|
||||
|
||||
array('::', '00000000000000000000000000000000'),
|
||||
array('::1', '00000000000000000000000000000001'),
|
||||
array('1::', '00010000000000000000000000000000'),
|
||||
|
||||
array('1:1:0:0:1::', '00010001000000000001000000000000'),
|
||||
|
||||
array('0:2:3:4:5:6:7:8', '00000002000300040005000600070008'),
|
||||
array('1:2:0:4:5:6:7:8', '00010002000000040005000600070008'),
|
||||
array('1:2:3:4:5:6:7:0', '00010002000300040005000600070000'),
|
||||
|
||||
array('2001:0:0:1::1', '20010000000000010000000000000001'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_provider
|
||||
*/
|
||||
public function test_inet_ntop($address, $hex)
|
||||
{
|
||||
$this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_provider
|
||||
*/
|
||||
public function test_inet_pton($address, $hex)
|
||||
{
|
||||
$this->assertEquals($hex, bin2hex(phpbb_inet_pton($address)));
|
||||
}
|
||||
}
|
65
tests/network/ip_normalise.php
Normal file
65
tests/network/ip_normalise.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @package testing
|
||||
* @copyright (c) 2010 phpBB Group
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
*
|
||||
*/
|
||||
|
||||
require_once 'test_framework/framework.php';
|
||||
require_once '../phpBB/includes/functions.php';
|
||||
|
||||
class phpbb_network_ip_normalise_test extends phpbb_test_case
|
||||
{
|
||||
public function data_provider()
|
||||
{
|
||||
return array(
|
||||
// From: A Recommendation for IPv6 Address Text Representation
|
||||
// http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07
|
||||
|
||||
// Section 4: A Recommendation for IPv6 Text Representation
|
||||
// Section 4.1: Handling Leading Zeros in a 16 Bit Field
|
||||
array('2001:0db8::0001', '2001:db8::1'),
|
||||
|
||||
// Section 4.2: "::" Usage
|
||||
// Section 4.2.1: Shorten As Much As Possible
|
||||
array('2001:db8::0:1', '2001:db8::1'),
|
||||
|
||||
// Section 4.2.2: Handling One 16 Bit 0 Field
|
||||
array('2001:db8::1:1:1:1:1', '2001:db8:0:1:1:1:1:1'),
|
||||
|
||||
// Section 4.2.3: Choice in Placement of "::"
|
||||
array('2001:db8:0:0:1:0:0:1', '2001:db8::1:0:0:1'),
|
||||
|
||||
// Section 4.3: Lower Case
|
||||
array('2001:DB8::1', '2001:db8::1'),
|
||||
|
||||
// Section 5: Text Representation of Special Addresses
|
||||
// We want to show IPv4-mapped addresses as plain IPv4 addresses, though.
|
||||
array('::ffff:192.168.0.1', '192.168.0.1'),
|
||||
array('0000::0000:ffff:c000:0280', '192.0.2.128'),
|
||||
|
||||
// IPv6 addresses with the last 32-bit written in dotted-quad notation
|
||||
// should be converted to hex-only IPv6 addresses.
|
||||
array('2001:db8::192.0.2.128', '2001:db8::c000:280'),
|
||||
|
||||
// Any string not passing the IPv4 or IPv6 regular expression
|
||||
// is supposed to result in false being returned.
|
||||
// Valid and invalid IP addresses are tested in
|
||||
// tests/regex/ipv4.php and tests/regex/ipv6.php.
|
||||
array('', false),
|
||||
array('192.168.1.256', false),
|
||||
array('::ffff:192.168.255.256', false),
|
||||
array('::1111:2222:3333:4444:5555:6666::', false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider data_provider
|
||||
*/
|
||||
public function test_ip_normalise($ip_address, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, phpbb_ip_normalise($ip_address));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user