From: Aaron Schulz Date: Wed, 28 Mar 2007 05:39:06 +0000 (+0000) Subject: *Fix isInRange(), remove cruft, add "ipv-6" prefix to toHex() and parseRange6(),... X-Git-Tag: 1.31.0-rc.0~53570 X-Git-Url: https://git.cyclocoop.org/%242?a=commitdiff_plain;h=17b53cedd4779b5fd2111b4162f05c374492f2c1;p=lhc%2Fweb%2Fwiklou.git *Fix isInRange(), remove cruft, add "ipv-6" prefix to toHex() and parseRange6(), actually show hidename option for blocks --- diff --git a/includes/Block.php b/includes/Block.php index ee75fb1785..d1f96e646a 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -23,7 +23,8 @@ class Block const EB_RANGE_ONLY = 4; function __construct( $address = '', $user = 0, $by = 0, $reason = '', - $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0, $hideName = 0 ) + $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0, + $hideName = 0 ) { $this->mId = 0; # Expand valid IPv6 addresses @@ -640,39 +641,34 @@ class Block } /** - * Gets rid of uneeded numbers in quad-dotted IP strings + * Gets rid of uneeded numbers in quad-dotted/octet IP strings * For example, 127.111.113.151/24 -> 127.111.113.0/24 */ static function normaliseRange( $range ) { - // Use IPv6 functions if needed - if ( IP::isIPv6($range) ) return self::normaliseRange6( $range ); $parts = explode( '/', $range ); if ( count( $parts ) == 2 ) { - $shift = 32 - $parts[1]; - $ipint = IP::toUnsigned( $parts[0] ); - $ipint = $ipint >> $shift << $shift; - $newip = long2ip( $ipint ); - $range = "$newip/{$parts[1]}"; - } - return $range; - } - - // For IPv6 - static function normaliseRange6( $range ) { - $parts = explode( '/', $range ); - if ( count( $parts ) == 2 ) { - $bits = $parts[1]; - $ipint = IP::toUnsigned6( $parts[0] ); - # Native 32 bit functions WONT work here!!! - # Convert to a padded binary number - $network = wfBaseConvert( $ipint, 10, 2, 128 ); - # Truncate the last (128-$bits) bits and replace them with zeros - $network = str_pad( substr( $network, 0, $bits ), 128, 0, STR_PAD_RIGHT ); - # Convert back to an integer - $network = wfBaseConvert( $network, 2, 10 ); - # Reform octet address - $newip = IP::toOctet( $network ); - $range = "$newip/{$parts[1]}"; + // IPv6 + if ( IP::isIPv6($range) && $parts[1] >= 64 && $parts[1] <= 128 ) { + $bits = $parts[1]; + $ipint = IP::toUnsigned6( $parts[0] ); + # Native 32 bit functions WONT work here!!! + # Convert to a padded binary number + $network = wfBaseConvert( $ipint, 10, 2, 128 ); + # Truncate the last (128-$bits) bits and replace them with zeros + $network = str_pad( substr( $network, 0, $bits ), 128, 0, STR_PAD_RIGHT ); + # Convert back to an integer + $network = wfBaseConvert( $network, 2, 10 ); + # Reform octet address + $newip = IP::toOctet( $network ); + $range = "$newip/{$parts[1]}"; + } // IPv4 + else if ( IP::isIPv4($range) && $parts[1] >= 16 && $parts[1] <= 32 ) { + $shift = 32 - $parts[1]; + $ipint = IP::toUnsigned( $parts[0] ); + $ipint = $ipint >> $shift << $shift; + $newip = long2ip( $ipint ); + $range = "$newip/{$parts[1]}"; + } } return $range; } diff --git a/includes/IP.php b/includes/IP.php index 9567f1effa..748a1f0b15 100644 --- a/includes/IP.php +++ b/includes/IP.php @@ -89,13 +89,15 @@ class IP { $ip = explode(':', self::sanitizeIP( $ip ) ); $r_ip = ''; foreach ($ip as $v) { - $r_ip .= wfBaseConvert( $v, 16, 2, 16); + $r_ip .= str_pad( $v, 4, 0, STR_PAD_LEFT ); } - return wfBaseConvert($r_ip, 2, 10); + $r_ip = wfBaseConvert( $r_ip, 16, 10 ); + return $r_ip; } /** * Given an IPv6 address in octet notation, returns the expanded octet. + * IPv4 IPs will be trimmed, thats it... * @param $ip octet ipv6 IP address. * @return string */ @@ -107,18 +109,14 @@ class IP { if ( !self::isIPv6($ip) ) return $ip; // Remove any whitespaces, convert to upper case $ip = strtoupper( trim($ip) ); - // Expand zero abbreviations - if ( substr_count($ip, '::') ) { + // Expand zero abbreviations + if ( strpos( $ip, '::' ) !== false ) { $ip = str_replace('::', str_repeat(':0', 8 - substr_count($ip, ':')) . ':', $ip); } // For IPs that start with "::", correct the final IP so that it starts with '0' and not ':' - if ( strpos( $ip, ':' ) === 0 ) $ip = "0$ip"; + if ( $ip[0] == ':' ) $ip = "0$ip"; // Remove leading zereos from each bloc as needed - $ip = explode( ':', $ip ); - for ( $n=0; $n < count($ip); $n++ ) { - $ip[$n] = preg_replace( '/^0+' . RE_IPV6_WORD . '/', '$1', $ip[$n] ); - } - $ip = implode( ':', $ip ); + $ip = preg_replace( '/(^|:)0+' . RE_IPV6_WORD . '/', '$1$2', $ip ); return $ip; } @@ -128,14 +126,15 @@ class IP { * @return string */ public static function toOctet( $ip_int ) { - // Convert integer to binary - $ip_int = wfBaseConvert($ip_int, 10, 2, 128); + // Convert to padded uppercase hex + $ip_hex = wfBaseConvert($ip_int, 10, 16, 32, false); // Seperate into 8 octets - $ip_oct = wfBaseConvert( substr( $ip_int, 0, 16 ), 2, 16, 1, false ); + $ip_oct = substr( $ip_hex, 0, 4 ); for ($n=1; $n < 8; $n++) { - // Convert to uppercase hex, and add ":" marks, with NO leading zeroes - $ip_oct .= ':' . wfBaseConvert( substr($ip_int, 16*$n, 16), 2, 16, 1, false ); + $ip_oct .= ':' . substr($ip_hex, 4*$n, 4); } + // NO leading zeroes + $ip_oct = preg_replace( '/(^|:)0+' . RE_IPV6_WORD . '/', '$1$2', $ip_oct ); return $ip_oct; } @@ -167,7 +166,6 @@ class IP { $network = false; $bits = false; } - return array( $network, $bits ); } @@ -197,6 +195,8 @@ class IP { $end = str_pad( substr( $end, 0, $bits ), 128, 1, STR_PAD_RIGHT ); # Convert to hex $end = wfBaseConvert( $end, 2, 16, 32, false ); + # see toHex() comment + $start = "ipv6-$start"; $end = "ipv6-$end"; } } elseif ( strpos( $range, '-' ) !== false ) { # Explicit range @@ -208,6 +208,8 @@ class IP { $start = wfBaseConvert( $start, 10, 16, 32, false ); $end = wfBaseConvert( $end, 10, 16, 32, false ); } + # see toHex() comment + $start = "ipv6-$start"; $end = "ipv6-$end"; } else { # Single IP $start = $end = self::toHex( $range ); @@ -305,13 +307,13 @@ class IP { public static function toHex( $ip ) { $n = self::toUnsigned( $ip ); if ( $n !== false ) { - $n = ( self::isIPv6($ip) ) ? wfBaseConvert( $n, 10, 16, 32, false ) : wfBaseConvert( $n, 10, 16, 8, false ); + $n = ( self::isIPv6($ip) ) ? "v6-" . wfBaseConvert( $n, 10, 16, 32, false ) : wfBaseConvert( $n, 10, 16, 8, false ); } return $n; } /** - * Given an IP address in dotted-quad notation, returns an unsigned integer. + * Given an IP address in dotted-quad/octet notation, returns an unsigned integer. * Like ip2long() except that it actually works and has a consistent error return value. * Comes from ProxyTools.php * @param $ip Quad dotted IP address. @@ -382,12 +384,16 @@ class IP { /** * Given a string range in a number of formats, return the start and end of - * the range in hexadecimal. For IPv4. + * the range in hexadecimal. * * Formats are: * 1.2.3.4/24 CIDR * 1.2.3.4 - 1.2.3.5 Explicit range * 1.2.3.4 Single IP + * + * 2001:0db8:85a3::7344/96 CIDR + * 2001:0db8:85a3::7344 - 2001:0db8:85a3::7344 Explicit range + * 2001:0db8:85a3::7344/96 Single IP * @return array(string, int) */ public static function parseRange( $range ) { @@ -433,8 +439,8 @@ class IP { */ public static function isInRange( $addr, $range ) { // Convert to IPv6 if needed - $unsignedIP = self::toUnsigned( $addr ); - list( $start, $end ) = self::parseRange($range ); + $unsignedIP = self::toHex( $addr ); + list( $start, $end ) = self::parseRange( $range ); return (($unsignedIP >= $start) && ($unsignedIP <= $end)); } diff --git a/includes/SpecialBlockip.php b/includes/SpecialBlockip.php index 27729f2b82..602f6db426 100644 --- a/includes/SpecialBlockip.php +++ b/includes/SpecialBlockip.php @@ -45,7 +45,7 @@ class IPBlockForm { var $BlockAddress, $BlockExpiry, $BlockReason; function IPBlockForm( $par ) { - global $wgRequest; + global $wgRequest, $wgUser; $this->BlockAddress = $wgRequest->getVal( 'wpBlockAddress', $wgRequest->getVal( 'ip', $par ) ); $this->BlockAddress = strtr( $this->BlockAddress, '_', ' ' ); @@ -59,6 +59,8 @@ class IPBlockForm { $this->BlockAnonOnly = $wgRequest->getBool( 'wpAnonOnly', $byDefault ); $this->BlockCreateAccount = $wgRequest->getBool( 'wpCreateAccount', $byDefault ); $this->BlockEnableAutoblock = $wgRequest->getBool( 'wpEnableAutoblock', $byDefault ); + # Re-check user's rights to hide names, very serious, defaults to 0 + $this->BlockHideName = $wgRequest->getBool( 'wpHideName', 0 ) && $wgUser->isAllowed( 'hideuser' ); } function showForm( $err ) { @@ -131,6 +133,7 @@ class IPBlockForm { "); } + $wgOut->addHTML(" @@ -150,31 +153,46 @@ class IPBlockForm {   - " . wfCheckLabel( wfMsg( 'ipbanononly' ), + " . wfCheckLabel( wfMsgHtml( 'ipbanononly' ), 'wpAnonOnly', 'wpAnonOnly', $this->BlockAnonOnly, - array( 'tabindex' => 4 ) ) . " + array( 'tabindex' => '4' ) ) . "   - " . wfCheckLabel( wfMsg( 'ipbcreateaccount' ), + " . wfCheckLabel( wfMsgHtml( 'ipbcreateaccount' ), 'wpCreateAccount', 'wpCreateAccount', $this->BlockCreateAccount, - array( 'tabindex' => 5 ) ) . " + array( 'tabindex' => '5' ) ) . "   - " . wfCheckLabel( wfMsg( 'ipbenableautoblock' ), + " . wfCheckLabel( wfMsgHtml( 'ipbenableautoblock' ), 'wpEnableAutoblock', 'wpEnableAutoblock', $this->BlockEnableAutoblock, - array( 'tabindex' => 6 ) ) . " + array( 'tabindex' => '6' ) ) . " + "); + // Allow some users to hide name from block log, blocklist and listusers + if ( $wgUser->isAllowed( 'hideuser' ) ) { + $wgOut->addHTML(" + +   + + " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ), + 'wpHideName', 'wpHideName', $this->BlockHideName, + array( 'tabindex' => '6' ) ) . " + + + "); + } + $wgOut->addHTML("   - " . Xml::submitButton( wfMsg( 'ipbsubmit' ), + " . Xml::submitButton( wfMsgHtml( 'ipbsubmit' ), array( 'name' => 'wpBlock', 'tabindex' => '7' ) ) . " @@ -213,7 +231,7 @@ class IPBlockForm { if ( preg_match( "/^($rxIP4)\\/(\\d{1,2})$/", $this->BlockAddress, $matches ) ) { # IPv4 if ( $wgSysopRangeBans ) { - if ( !IP::isIPv4( $this->BlockAddress ) || $matches[2] > 31 || $matches[2] < 16 ) { + if ( !IP::isIPv4( $this->BlockAddress ) || $matches[2] < 16 || $matches[2] > 32 ) { $this->showForm( wfMsg( 'ip_range_invalid' ) ); return; } @@ -226,11 +244,11 @@ class IPBlockForm { } else if ( preg_match( "/^($rxIP6)\\/(\\d{1,3})$/", $this->BlockAddress, $matches ) ) { # IPv6 if ( $wgSysopRangeBans ) { - if ( !IP::isIPv6( $this->BlockAddress ) || $matches[2] > 127 || $matches[2] < 64 ) { + if ( !IP::isIPv6( $this->BlockAddress ) || $matches[2] < 64 || $matches[2] > 128 ) { $this->showForm( wfMsg( 'ip_range_invalid' ) ); return; } - $this->BlockAddress = Block::normaliseRange6( $this->BlockAddress ); + $this->BlockAddress = Block::normaliseRange( $this->BlockAddress ); } else { # Range block illegal $this->showForm( wfMsg( 'range_block_disabled' ) ); @@ -283,7 +301,7 @@ class IPBlockForm { $block = new Block( $this->BlockAddress, $userId, $wgUser->getID(), $this->BlockReason, wfTimestampNow(), 0, $expiry, $this->BlockAnonOnly, - $this->BlockCreateAccount, $this->BlockEnableAutoblock ); + $this->BlockCreateAccount, $this->BlockEnableAutoblock, $this->BlockHideName); if (wfRunHooks('BlockIp', array(&$block, &$wgUser))) { @@ -300,8 +318,9 @@ class IPBlockForm { $logParams[] = $expirestr; $logParams[] = $this->blockLogFlags(); - # Make log entry - $log = new LogPage( 'block' ); + # Make log entry, if the name is hidden, put it in the oversight log + $log_type = ($this->BlockHideName) ? 'oversight' : 'block'; + $log = new LogPage( $log_type ); $log->addEntry( 'block', Title::makeTitle( NS_USER, $this->BlockAddress ), $this->BlockReason, $logParams );