/** * Get blocking information * @param bool $bFromSlave Whether to check the slave database first. * To improve performance, non-critical checks are done against slaves. * Check when actually saving should be done against master. */ private function getBlockedStatus($bFromSlave = true) { global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff; if (-1 != $this->mBlockedby) { return; } wfDebug(__METHOD__ . ": checking...\n"); // Initialize data... // Otherwise something ends up stomping on $this->mBlockedby when // things get lazy-loaded later, causing false positive block hits // due to -1 !== 0. Probably session-related... Nothing should be // overwriting mBlockedby, surely? $this->load(); # We only need to worry about passing the IP address to the Block generator if the # user is not immune to autoblocks/hardblocks, and they are the current user so we # know which IP address they're actually coming from if (!$this->isAllowed('ipblock-exempt') && $this->equals($wgUser)) { $ip = $this->getRequest()->getIP(); } else { $ip = null; } // User/IP blocking $block = Block::newFromTarget($this, $ip, !$bFromSlave); // Proxy blocking if (!$block instanceof Block && $ip !== null && !$this->isAllowed('proxyunbannable') && !in_array($ip, $wgProxyWhitelist)) { // Local list if (self::isLocallyBlockedProxy($ip)) { $block = new Block(); $block->setBlocker(wfMessage('proxyblocker')->text()); $block->mReason = wfMessage('proxyblockreason')->text(); $block->setTarget($ip); } elseif ($this->isAnon() && $this->isDnsBlacklisted($ip)) { $block = new Block(); $block->setBlocker(wfMessage('sorbs')->text()); $block->mReason = wfMessage('sorbsreason')->text(); $block->setTarget($ip); } } // (bug 23343) Apply IP blocks to the contents of XFF headers, if enabled if (!$block instanceof Block && $wgApplyIpBlocksToXff && $ip !== null && !$this->isAllowed('proxyunbannable') && !in_array($ip, $wgProxyWhitelist)) { $xff = $this->getRequest()->getHeader('X-Forwarded-For'); $xff = array_map('trim', explode(',', $xff)); $xff = array_diff($xff, array($ip)); $xffblocks = Block::getBlocksForIPList($xff, $this->isAnon(), !$bFromSlave); $block = Block::chooseBlock($xffblocks, $xff); if ($block instanceof Block) { # Mangle the reason to alert the user that the block # originated from matching the X-Forwarded-For header. $block->mReason = wfMessage('xffblockreason', $block->mReason)->text(); } } if ($block instanceof Block) { wfDebug(__METHOD__ . ": Found block.\n"); $this->mBlock = $block; $this->mBlockedby = $block->getByName(); $this->mBlockreason = $block->mReason; $this->mHideName = $block->mHideName; $this->mAllowUsertalk = !$block->prevents('editownusertalk'); } else { $this->mBlockedby = ''; $this->mHideName = 0; $this->mAllowUsertalk = false; } // Extensions Hooks::run('GetBlockedStatus', array(&$this)); }
/** * @dataProvider providerXff * @covers Block::getBlocksForIPList * @covers Block::chooseBlock */ public function testBlocksOnXff($xff, $exCount, $exResult) { $list = array_map('trim', explode(',', $xff)); $xffblocks = Block::getBlocksForIPList($list, true); $this->assertEquals($exCount, count($xffblocks), 'Number of blocks for ' . $xff); $block = Block::chooseBlock($xffblocks, $list); $this->assertEquals($exResult, $block->mReason, 'Correct block type for XFF header ' . $xff); }