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
}
/**
- * 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;
}
$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
*/
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;
}
* @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;
}
$network = false;
$bits = false;
}
-
return array( $network, $bits );
}
$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
$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 );
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.
/**
* 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 ) {
*/
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));
}
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, '_', ' ' );
$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 ) {
</td>
");
}
+
$wgOut->addHTML("
</tr>
<tr id='wpBlockOther'>
<tr id='wpAnonOnlyRow'>
<td> </td>
<td align=\"left\">
- " . wfCheckLabel( wfMsg( 'ipbanononly' ),
+ " . wfCheckLabel( wfMsgHtml( 'ipbanononly' ),
'wpAnonOnly', 'wpAnonOnly', $this->BlockAnonOnly,
- array( 'tabindex' => 4 ) ) . "
+ array( 'tabindex' => '4' ) ) . "
</td>
</tr>
<tr id='wpCreateAccountRow'>
<td> </td>
<td align=\"left\">
- " . wfCheckLabel( wfMsg( 'ipbcreateaccount' ),
+ " . wfCheckLabel( wfMsgHtml( 'ipbcreateaccount' ),
'wpCreateAccount', 'wpCreateAccount', $this->BlockCreateAccount,
- array( 'tabindex' => 5 ) ) . "
+ array( 'tabindex' => '5' ) ) . "
</td>
</tr>
<tr id='wpEnableAutoblockRow'>
<td> </td>
<td align=\"left\">
- " . wfCheckLabel( wfMsg( 'ipbenableautoblock' ),
+ " . wfCheckLabel( wfMsgHtml( 'ipbenableautoblock' ),
'wpEnableAutoblock', 'wpEnableAutoblock', $this->BlockEnableAutoblock,
- array( 'tabindex' => 6 ) ) . "
+ array( 'tabindex' => '6' ) ) . "
</td>
</tr>
+ ");
+ // Allow some users to hide name from block log, blocklist and listusers
+ if ( $wgUser->isAllowed( 'hideuser' ) ) {
+ $wgOut->addHTML("
+ <tr>
+ <td> </td>
+ <td align=\"left\">
+ " . wfCheckLabel( wfMsgHtml( 'ipbhidename' ),
+ 'wpHideName', 'wpHideName', $this->BlockHideName,
+ array( 'tabindex' => '6' ) ) . "
+ </td>
+ </tr>
+ ");
+ }
+ $wgOut->addHTML("
<tr>
<td style='padding-top: 1em'> </td>
<td style='padding-top: 1em' align=\"left\">
- " . Xml::submitButton( wfMsg( 'ipbsubmit' ),
+ " . Xml::submitButton( wfMsgHtml( 'ipbsubmit' ),
array( 'name' => 'wpBlock', 'tabindex' => '7' ) ) . "
</td>
</tr>
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;
}
} 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' ) );
$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))) {
$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 );