예제 #1
0
 /**
  * Find the wikis with revisions for the specified users
  *
  * @param array $identifiers
  * @return array of wikiId => array of users with revisions on that wiki
  */
 protected function getAffectedWikis(array $identifiers)
 {
     global $wgStatsDB, $wgStatsDBEnabled, $wgDevelEnvironment;
     $wikiIds = [];
     if (!$wgStatsDBEnabled) {
         // requires stats database to function
         // TODO log this?
         return $wikiIds;
     }
     // on devbox we have to fall back to static list
     // because we have no active read-write statsdb there
     if (!empty($wgDevelEnvironment)) {
         global $wgCityId;
         return array($wgCityId => $identifiers);
     }
     $sdb = wfGetDB(DB_SLAVE, [], $wgStatsDB);
     foreach ($identifiers as $identifier) {
         list($userId, $ip) = $this->getUserByIdentifier($identifier);
         $affectedWikis = (new WikiaSQL())->DISTINCT('wiki_id')->FROM('events')->WHERE('user_id')->EQUAL_TO($userId);
         if ($userId == 0 && isset($ip)) {
             $affectedWikis->AND_('ip')->EQUAL_TO(IP::toUnsigned($identifier));
         }
         // TODO can userId be 0 and the identifier not be an IP?
         $wikis = $affectedWikis->runLoop($sdb, function ($_, $row) use(&$wikiIds, $identifier) {
             if (empty($wikiIds[$row->wiki_id])) {
                 $wikiIds[$row->wiki_id] = [];
             }
             $wikiIds[$row->wiki_id][] = $identifier;
         });
     }
     return $wikiIds;
 }
예제 #2
0
 protected function findWikis($users)
 {
     global $wgStatsDB, $wgStatsDBEnabled, $wgDevelEnvironment;
     if (!$wgStatsDBEnabled) {
         return false;
     }
     // on devbox we have to fall back to static list
     // because we have no active read-write statsdb there
     if (!empty($wgDevelEnvironment)) {
         return array(165);
     }
     $dbr = wfGetDB(DB_SLAVE, array(), $wgStatsDB);
     $wikiIds = array();
     foreach ($users as $user) {
         if ($user['id'] != 0) {
             // regular user
             $where = array('user_id' => intval($user['id']));
         } else {
             // ip - anons
             $where = array('user_id' => 0, 'ip' => IP::toUnsigned($user['ip']));
         }
         $res = $dbr->select('events', 'wiki_id', $where, __METHOD__, array('DISTINCT'));
         $userWikiIds = array();
         while ($row = $dbr->fetchObject($res)) {
             $wikiIds[$row->wiki_id] = true;
             $userWikiIds[] = $row->wiki_id;
         }
         $this->log("User \"" . $user['canonical'] . "\": found " . count($userWikiIds) . " wikis: " . implode(', ', $userWikiIds));
     }
     $wikiIds = array_keys($wikiIds);
     sort($wikiIds);
     return $wikiIds;
 }
예제 #3
0
 public function execute()
 {
     $dbw = wfGetDB(DB_MASTER);
     // Perform this in a transaction so an failed load doesn't erase current data.
     $dbw->begin();
     // Clear existing GeoIP data.
     try {
         $dbw->delete('geoip', '*', __METHOD__);
     } catch (DBQueryError $e) {
         $this->error('ERROR: Could not delete existing geographic data. Is the GeoIP schema loaded?', true);
     }
     // Load fresh data from the first (and only) argument.
     $filename = $this->getArg(0);
     $lines = exec('wc -l ' . $filename);
     $handle = fopen($filename, 'r');
     $count = 0;
     while (($data = fgetcsv($handle, 256, ',')) !== false) {
         // Output a nice progress bar.
         if ($count % 1000 == 0) {
             $progress = ceil($count / $lines * 50);
             $this->output('[' . str_repeat('=', $progress) . str_repeat(' ', 50 - $progress) . '] ' . ceil($count / $lines * 100) . '%' . "\r");
         }
         ++$count;
         $record = array('begin_ip_long' => IP::toUnsigned($data[0]), 'end_ip_long' => IP::toUnsigned($data[1]), 'country_code' => $data[4]);
         $dbw->insert('geoip', $record, __METHOD__);
     }
     $this->output("\n");
     $dbw->commit();
     $this->output('Successfully loaded ' . $count . ' geographic IP ranges.' . "\n");
 }
예제 #4
0
function fnGetGeoIP($ip_address = null)
{
    if (!isset($ip_address)) {
        $ip_address = IP::sanitizeIP(wfGetIP());
    }
    if (isset($_GET['ip'])) {
        $ip_address = IP::sanitizeIP($_GET['ip']);
    }
    if (!IP::isIPv4($ip_address)) {
        throw new UnsupportedGeoIP('Only IPv4 addresses are supported.');
    }
    $dbr = wfGetDB(DB_SLAVE);
    $long_ip = IP::toUnsigned($ip_address);
    $conditions = array('begin_ip_long <= ' . $long_ip, $long_ip . ' <= end_ip_long');
    $country_code = $dbr->selectField('geoip', 'country_code', $conditions, __METHOD__);
    if (!$country_code) {
        throw new NotFoundGeoIP('Could not identify the country for the provided IP address.');
    }
    return $country_code;
}
예제 #5
0
파일: IP.php 프로젝트: puring0815/OpenKore
 /**
  * Determine if an IP address really is an IP address, and if it is public,
  * i.e. not RFC 1918 or similar
  * Comes from ProxyTools.php
  */
 public static function isPublic($ip)
 {
     $n = IP::toUnsigned($ip);
     if (!$n) {
         return false;
     }
     // ip2long accepts incomplete addresses, as well as some addresses
     // followed by garbage characters. Check that it's really valid.
     if ($ip != long2ip($n)) {
         return false;
     }
     static $privateRanges = false;
     if (!$privateRanges) {
         $privateRanges = array(array('10.0.0.0', '10.255.255.255'), array('172.16.0.0', '172.31.255.255'), array('192.168.0.0', '192.168.255.255'), array('0.0.0.0', '0.255.255.255'), array('127.0.0.0', '127.255.255.255'));
     }
     foreach ($privateRanges as $r) {
         $start = IP::toUnsigned($r[0]);
         $end = IP::toUnsigned($r[1]);
         if ($n >= $start && $n <= $end) {
             return false;
         }
     }
     return true;
 }
예제 #6
0
 /**
  * test wrapper around ip2long which might return -1 or false depending on PHP version
  * @covers IP::toUnsigned
  */
 public function testip2longWrapper()
 {
     // @todo FIXME: Add more tests ?
     $this->assertEquals(pow(2, 32) - 1, IP::toUnsigned('255.255.255.255'));
     $i = 'IN.VA.LI.D';
     $this->assertFalse(IP::toUnSigned($i));
 }
예제 #7
0
 /**
  * @covers IP::toUnsigned
  * @dataProvider provideToUnsigned
  */
 public function testToUnsigned($expected, $input)
 {
     $result = IP::toUnsigned($input);
     $this->assertTrue($result === false || is_string($result) || is_int($result));
     $this->assertEquals($expected, $result);
 }
예제 #8
0
 function showList($msg)
 {
     global $wgOut;
     $wgOut->setPagetitle(wfMsg("ipblocklist"));
     if ("" != $msg) {
         $wgOut->setSubtitle($msg);
     }
     // Purge expired entries on one in every 10 queries
     if (!mt_rand(0, 10)) {
         Block::purgeExpired();
     }
     $conds = array();
     if ($this->ip == '') {
         // No extra conditions
     } elseif (substr($this->ip, 0, 1) == '#') {
         $conds['ipb_id'] = substr($this->ip, 1);
     } elseif (IP::toUnsigned($this->ip) !== false) {
         $conds['ipb_address'] = $this->ip;
         $conds['ipb_auto'] = 0;
     } elseif (preg_match("/^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\/(\\d{1,2})\$/", $this->ip, $matches)) {
         $conds['ipb_address'] = Block::normaliseRange($this->ip);
         $conds['ipb_auto'] = 0;
     } else {
         $user = User::newFromName($this->ip);
         if ($user && ($id = $user->getID()) != 0) {
             $conds['ipb_user'] = $id;
         } else {
             // Uh...?
             $conds['ipb_address'] = $this->ip;
             $conds['ipb_auto'] = 0;
         }
     }
     $pager = new IPBlocklistPager($this, $conds);
     $s = $pager->getNavigationBar() . $this->searchForm();
     if ($pager->getNumRows()) {
         $s .= "<ul>" . $pager->getBody() . "</ul>";
     } else {
         $s .= '<p>' . wfMsgHTML('ipblocklistempty') . '</p>';
     }
     $s .= $pager->getNavigationBar();
     $wgOut->addHTML($s);
 }
예제 #9
0
 /** 
  * 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)
 {
     $parts = explode('/', $range);
     if (count($parts) == 2) {
         // 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]}";
         } 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;
 }
 function showList($msg)
 {
     global $wgOut, $wgUser;
     $wgOut->setPagetitle(wfMsg("ipblocklist"));
     if ("" != $msg) {
         $wgOut->setSubtitle($msg);
     }
     // Purge expired entries on one in every 10 queries
     if (!mt_rand(0, 10)) {
         Block::purgeExpired();
     }
     $conds = array();
     $matches = array();
     // Is user allowed to see all the blocks?
     if (!$wgUser->isAllowed('oversight')) {
         $conds['ipb_deleted'] = 0;
     }
     if ($this->ip == '') {
         // No extra conditions
     } elseif (substr($this->ip, 0, 1) == '#') {
         $conds['ipb_id'] = substr($this->ip, 1);
     } elseif (IP::toUnsigned($this->ip) !== false) {
         $conds['ipb_address'] = $this->ip;
         $conds['ipb_auto'] = 0;
     } elseif (preg_match('/^(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\/(\\d{1,2})$/', $this->ip, $matches)) {
         $conds['ipb_address'] = Block::normaliseRange($this->ip);
         $conds['ipb_auto'] = 0;
     } else {
         $user = User::newFromName($this->ip);
         if ($user && ($id = $user->getID()) != 0) {
             $conds['ipb_user'] = $id;
         } else {
             // Uh...?
             $conds['ipb_address'] = $this->ip;
             $conds['ipb_auto'] = 0;
         }
     }
     $pager = new IPBlocklistPager($this, $conds);
     if ($pager->getNumRows()) {
         $wgOut->addHTML($this->searchForm() . $pager->getNavigationBar() . Xml::tags('ul', null, $pager->getBody()) . $pager->getNavigationBar());
     } elseif ($this->ip != '') {
         $wgOut->addHTML($this->searchForm());
         $wgOut->addWikiText(wfMsg('ipblocklist-no-results'));
     } else {
         $wgOut->addWikiText(wfMsg('ipblocklist-empty'));
     }
 }
예제 #11
0
 static function normaliseRange($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;
 }
예제 #12
0
파일: IP.php 프로젝트: negabaro/alfresco
 /**
  * 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.
  */
 public static function isInRange($addr, $range)
 {
     $unsignedIP = IP::toUnsigned($addr);
     list($start, $end) = IP::parseRange($range);
     $start = hexdec($start);
     $end = hexdec($end);
     return $unsignedIP >= $start && $unsignedIP <= $end;
 }