From 98a334ad27d193fa3707789d2f7ab67f9d8136c4 Mon Sep 17 00:00:00 2001 From: Andrew Garrett Date: Wed, 22 Nov 2006 11:51:49 +0000 Subject: [PATCH] * (bug 7883) Added autoblock whitelisting feature, using which specific ranges can be protected from autoblocking. These ranges are specified, in list format, in the autoblock_whitelist system message. --- RELEASE-NOTES | 4 ++- includes/Block.php | 54 +++++++++++++++++++++++-------- includes/GlobalFunctions.php | 33 +++++++++++++++++-- languages/messages/MessagesEn.php | 4 +++ 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 564e2f571c..c4b1e78e79 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -208,7 +208,9 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN big! * (bug 7554) The correct MIME type for SVG images is now displayed on the image page (image/svg+xml, not image/svg). - +* (bug 7883) Added autoblock whitelisting feature, using which specific ranges + can be protected from autoblocking. These ranges are specified, in list format, + in the autoblock_whitelist system message. == Languages updated == diff --git a/includes/Block.php b/includes/Block.php index 93458b8ce2..b6e36d85aa 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -241,14 +241,10 @@ class Block /** * Determine if a given integer IPv4 address is in a given CIDR network + * @deprecated Use wfIsAddressInRange */ function isAddressInRange( $addr, $range ) { - list( $network, $bits ) = wfParseCIDR( $range ); - if ( $network !== false && $addr >> ( 32 - $bits ) == $network >> ( 32 - $bits ) ) { - return true; - } else { - return false; - } + return wfIsAddressInRange( $addr, $range ); } function initFromRow( $row ) @@ -277,12 +273,11 @@ class Block { $this->mRangeStart = ''; $this->mRangeEnd = ''; + if ( $this->mUser == 0 ) { - list( $network, $bits ) = wfParseCIDR( $this->mAddress ); - if ( $network !== false ) { - $this->mRangeStart = sprintf( '%08X', $network ); - $this->mRangeEnd = sprintf( '%08X', $network + (1 << (32 - $bits)) - 1 ); - } + $startend = wfRangeStartEnd($this->mAddress); + $this->mRangeStart = $startend[0]; + $this->mRangeEnd = $startend[1]; } } @@ -378,7 +373,7 @@ class Block # Don't collide with expired blocks Block::purgeExpired(); - + $ipb_id = $dbw->nextSequenceValue('ipblocks_ipb_id_val'); $dbw->insert( 'ipblocks', array( @@ -435,18 +430,49 @@ class Block /** * Autoblocks the given IP, referring to this Block. - *@param $autoblockip The IP to autoblock. - *@return Whether or not an autoblock was inserted. + * @param $autoblockip The IP to autoblock. + * @return bool Whether or not an autoblock was inserted. */ function doAutoblock( $autoblockip ) { # Check if this IP address is already blocked $dbw =& wfGetDb( DB_MASTER ); $dbw->begin(); + # If autoblocks are disabled, go away. if ( !$this->mEnableAutoblock ) { return; } + # Check for presence on the autoblock whitelist + # TODO cache this? + $lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) ); + + $ip = wfGetIp(); + + wfDebug("Checking the autoblock whitelist..\n"); + + foreach( $lines as $line ) { + # List items only + if ( substr( $line, 0, 1 ) !== '*' ) { + continue; + } + + $wlEntry = substr($line, 1); + $wlEntry = trim($wlEntry); + + wfDebug("Checking $wlEntry\n"); + + # Is the IP in this range? + if (wfIsAddressInRange( $ip, $wlEntry )) { + wfDebug("IP $ip matches $wlEntry, not autoblocking\n"); + #$autoblockip = null; # Don't autoblock a whitelisted IP. + return; #This /SHOULD/ introduce a dummy block - but + # I don't know a safe way to do so. -werdna + } + } + + # It's okay to autoblock. Go ahead and create/insert the block. + $ipblock = Block::newFromDB( $autoblockip ); if ( $ipblock ) { # If the user is already blocked. Then check if the autoblock would diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 663273585f..14e49ea593 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2037,6 +2037,37 @@ function wfWikiID() { } } +/** + * Get the start and end of a range. + * @param $range The range to get the start and end for. + * @return array An array with the first element as the start of the range, as a long, and the second element as the end of the range, also as a long. + * + */ +function wfRangeStartEnd( $range ) { + list( $network, $bits ) = wfParseCIDR( $range ); + if ( $network !== false ) { + $start = sprintf( '%08X', $network ); + $end = sprintf( '%08X', $network + (1 << (32 - $bits)) - 1 ); + return array($start, $end); + } + return false; +} + +/** + * Determine if a given integer IPv4 address is in a given CIDR network + * @param $addr The address to check against the given range. + * @param $range The range to check the given address against. + * @return bool Whether or not the given address is in the given range. + */ +function wfIsAddressInRange( $addr, $range ) { + $unsignedIP = IP::toUnsigned($addr); + $startend = wfRangeStartEnd($range); + $start = $startend[0]; + $end = $startend[1]; + + return (($unsignedIP >= $start) && ($unsignedip <= $end)); +} + /* * Get a Database object * @param integer $db Index of the connection to get. May be DB_MASTER for the @@ -2051,6 +2082,4 @@ function &wfGetDB( $db = DB_LAST, $groups = array() ) { $ret =& $wgLoadBalancer->getConnection( $db, true, $groups ); return $ret; } - - ?> diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index dc280c9eb7..8f56e12f6f 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -2601,6 +2601,10 @@ Please confirm that really want to recreate this page.', 'autosumm-replace' => 'Replacing page with \'$1\'', 'autoredircomment' => 'Redirecting to [[$1]]', # This should be changed to the new naming convention, but existed beforehand. 'autosumm-shortnew' => 'New page: $1', + +# Autoblock whitelist +'autoblock_whitelist' => '', + ); ?> -- 2.20.1