From 915f83d7b40670fa97f08351b3f92cec37542da5 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Mon, 12 Mar 2007 21:37:46 +0000 Subject: [PATCH] *IPv6 sanitizing, avoid use of native hex functions, enlarge ip box for blockip a bit --- includes/Block.php | 5 +++-- includes/IP.php | 33 +++++++++++++++++++++------------ includes/SpecialBlockip.php | 8 ++++---- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/includes/Block.php b/includes/Block.php index 4d7325e175..e35ead82d1 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -27,7 +27,7 @@ class Block { $this->mId = 0; # Expand valid IPv6 addresses - $address = IP::expandIP( $address ); + $address = IP::sanitizeIP( $address ); $this->mAddress = $address; $this->mUser = $user; $this->mBy = $by; @@ -176,7 +176,8 @@ class Block /** * Fill in member variables from a result wrapper */ - function loadFromResult( ResultWrapper $res, $killExpired = true ) { + function loadFromResult( ResultWrapper $res, $killExpired = true ) + { $ret = false; if ( 0 != $res->numRows() ) { # Get first block diff --git a/includes/IP.php b/includes/IP.php index 540096eb77..9a1d7bf024 100644 --- a/includes/IP.php +++ b/includes/IP.php @@ -82,7 +82,7 @@ class IP { */ public function toUnsigned6( $ip ) { if ( !$ip ) return null; - $ip = explode(':', self::expandIP( $ip ) ); + $ip = explode(':', self::sanitizeIP( $ip ) ); $r_ip = ''; foreach ($ip as $v) { $r_ip .= wfBaseConvert( $v, 16, 2, 16); @@ -95,10 +95,12 @@ class IP { * @param $ip octet ipv6 IP address. * @return string */ - public function expandIP( $ip ) { + public function sanitizeIP( $ip ) { if ( !$ip ) return null; // Only IPv6 addresses can be expanded if ( !self::isIPv6( $ip ) ) return $ip; + // Convert to upper case + $ip = strtoupper( $ip ); // Expand zero abbreviations if ( substr_count($ip, '::') ) { $ip = str_replace('::', str_repeat(':0000', 8 - substr_count($ip, ':')) . ':', $ip); @@ -112,14 +114,13 @@ class IP { * @return string */ public function toOctet( $ip_int ) { - $ip_int = strval($ip_int); // Convert integer to binary $ip_int = wfBaseConvert($ip_int, 10, 2, 128); // Seperate into 8 octets - $ip_oct = base_convert( substr( $ip_int, 0, 16 ), 2, 16 ); + $ip_oct = wfBaseConvert( substr( $ip_int, 0, 16 ), 2, 16, 1, false ); for ($n=1; $n < 8; $n++) { // Convert to hex, and add ":" marks - $ip_oct .= ':' . base_convert( substr($ip_int, 16*$n, 16), 2, 16 ); + $ip_oct .= ':' . wfBaseConvert( substr($ip_int, 16*$n, 16), 2, 16, 1, false ); } return $ip_oct; } @@ -129,7 +130,8 @@ class IP { * @return array(string, int) */ public static function parseCIDR6( $range ) { - $parts = explode( '/', $range, 2 ); + # Expand any IPv6 IP + $parts = explode( '/', IP::sanitizeIP( $range ), 2 ); if ( count( $parts ) != 2 ) { return array( false, false ); } @@ -166,14 +168,21 @@ class IP { * @return array(string, int) */ public static function parseRange6( $range ) { + # Expand any IPv6 IP + $range = IP::sanitizeIP( $range ); if ( strpos( $range, '/' ) !== false ) { # CIDR list( $network, $bits ) = self::parseCIDR6( $range ); if ( $network === false ) { $start = $end = false; } else { - $start = sprintf( '%08X', $network ); - $end = sprintf( '%08X', $network + pow( 2, (128 - $bits) ) - 1 ); + $start = wfBaseConvert( $network, 10, 16, 1, false ); + # Turn network to binary (again) + $end = wfBaseConvert( $network, 10, 2, 128 ); + # Truncate the last (128-$bits) bits and replace them with ones + $end = str_pad( substr( $end, 0, $bits ), 128, 1, STR_PAD_RIGHT ); + # Convert to hex + $end = wfBaseConvert( $end, 2, 16, 1, false ); } } elseif ( strpos( $range, '-' ) !== false ) { # Explicit range @@ -182,8 +191,8 @@ class IP { if ( $start > $end ) { $start = $end = false; } else { - $start = sprintf( '%08X', $start ); - $end = sprintf( '%08X', $end ); + $start = wfBaseConvert( $start, 10, 16, 1, false ); + $end = wfBaseConvert( $end, 10, 16, 1, false ); } } else { # Single IP @@ -191,7 +200,7 @@ class IP { } if ( $start === false || $end === false ) { return array( false, false ); - } else { + } else { return array( $start, $end ); } } @@ -283,7 +292,7 @@ class IP { // Use IPv6 functions if needed $n = ( self::isIPv6($ip) ) ? self::toUnsigned6( $ip ) : self::toUnsigned( $ip ); if ( $n !== false ) { - $n = sprintf( '%08X', $n ); + $n = wfBaseConvert( $n, 10, 16, 1, false ); } return $n; } diff --git a/includes/SpecialBlockip.php b/includes/SpecialBlockip.php index 41a0f5d7b1..12cf287a66 100644 --- a/includes/SpecialBlockip.php +++ b/includes/SpecialBlockip.php @@ -113,7 +113,7 @@ class IPBlockForm { {$mIpaddress}: - " . Xml::input( 'wpBlockAddress', 40, $this->BlockAddress, + " . Xml::input( 'wpBlockAddress', 45, $this->BlockAddress, array( 'tabindex' => '1', 'id' => 'mw-bi-target', @@ -136,14 +136,14 @@ class IPBlockForm { {$mIpbother}: - " . Xml::input( 'wpBlockOther', 40, $this->BlockOther, + " . Xml::input( 'wpBlockOther', 45, $this->BlockOther, array( 'tabindex' => '3', 'id' => 'mw-bi-other' ) ) . " {$mIpbreason}: - " . Xml::input( 'wpBlockReason', 40, $this->BlockReason, + " . Xml::input( 'wpBlockReason', 45, $this->BlockReason, array( 'tabindex' => '3', 'id' => 'mw-bi-reason' ) ) . " @@ -200,7 +200,7 @@ class IPBlockForm { $userId = 0; $this->BlockAddress = trim( $this->BlockAddress ); # Expand valid IPv6 addresses, usernames are left as is - $this->BlockAddress = IP::expandIP( $this->BlockAddress ); + $this->BlockAddress = IP::sanitizeIP( $this->BlockAddress ); # isIPv4() and IPv6() are used for final validation $rxIP4 = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'; $rxIP6 = '\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}:\w{1,4}'; -- 2.20.1