diff options
Diffstat (limited to 'includes/ProxyTools.php')
-rw-r--r-- | includes/ProxyTools.php | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/includes/ProxyTools.php b/includes/ProxyTools.php index 7974c882..22ea4947 100644 --- a/includes/ProxyTools.php +++ b/includes/ProxyTools.php @@ -23,7 +23,7 @@ function wfGetForwardedFor() { /** Work out the IP address based on various globals */ function wfGetIP() { - global $wgSquidServers, $wgSquidServersNoPurge, $wgIP; + global $wgIP; # Return cached result if ( !empty( $wgIP ) ) { @@ -33,34 +33,31 @@ function wfGetIP() { /* collect the originating ips */ # Client connecting to this webserver if ( isset( $_SERVER['REMOTE_ADDR'] ) ) { - $ipchain = array( $_SERVER['REMOTE_ADDR'] ); + $ipchain = array( IP::canonicalize( $_SERVER['REMOTE_ADDR'] ) ); } else { # Running on CLI? $ipchain = array( '127.0.0.1' ); } $ip = $ipchain[0]; - # Get list of trusted proxies - # Flipped for quicker access - $trustedProxies = array_flip( array_merge( $wgSquidServers, $wgSquidServersNoPurge ) ); - if ( count( $trustedProxies ) ) { - # Append XFF on to $ipchain - $forwardedFor = wfGetForwardedFor(); - if ( isset( $forwardedFor ) ) { - $xff = array_map( 'trim', explode( ',', $forwardedFor ) ); - $xff = array_reverse( $xff ); - $ipchain = array_merge( $ipchain, $xff ); - } - # Step through XFF list and find the last address in the list which is a trusted server - # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private) - foreach ( $ipchain as $i => $curIP ) { - if ( array_key_exists( $curIP, $trustedProxies ) ) { - if ( isset( $ipchain[$i + 1] ) && IP::isPublic( $ipchain[$i + 1] ) ) { - $ip = $ipchain[$i + 1]; - } - } else { - break; + # Append XFF on to $ipchain + $forwardedFor = wfGetForwardedFor(); + if ( isset( $forwardedFor ) ) { + $xff = array_map( 'trim', explode( ',', $forwardedFor ) ); + $xff = array_reverse( $xff ); + $ipchain = array_merge( $ipchain, $xff ); + } + + # Step through XFF list and find the last address in the list which is a trusted server + # Set $ip to the IP address given by that trusted server, unless the address is not sensible (e.g. private) + foreach ( $ipchain as $i => $curIP ) { + $curIP = IP::canonicalize( $curIP ); + if ( wfIsTrustedProxy( $curIP ) ) { + if ( isset( $ipchain[$i + 1] ) && IP::isPublic( $ipchain[$i + 1] ) ) { + $ip = $ipchain[$i + 1]; } + } else { + break; } } @@ -69,6 +66,21 @@ function wfGetIP() { return $ip; } +function wfIsTrustedProxy( $ip ) { + global $wgSquidServers, $wgSquidServersNoPurge; + + if ( in_array( $ip, $wgSquidServers ) || + in_array( $ip, $wgSquidServersNoPurge ) || + wfIsAOLProxy( $ip ) + ) { + $trusted = true; + } else { + $trusted = false; + } + wfRunHooks( 'IsTrustedProxy', array( &$ip, &$trusted ) ); + return $trusted; +} + /** * Forks processes to scan the originating IP for an open proxy server * MemCached can be used to skip IPs that have already been scanned @@ -96,7 +108,7 @@ function wfProxyCheck() { # Fork the processes if ( !$skip ) { - $title = Title::makeTitle( NS_SPECIAL, 'Blockme' ); + $title = SpecialPage::getTitleFor( 'Blockme' ); $iphash = md5( $ip . $wgProxyKey ); $url = $title->getFullURL( 'ip='.$iphash ); @@ -154,6 +166,51 @@ function wfIsLocallyBlockedProxy( $ip ) { return $ret; } +/** + * TODO: move this list to the database in a global IP info table incorporating + * trusted ISP proxies, blocked IP addresses and open proxies. + */ +function wfIsAOLProxy( $ip ) { + $ranges = array( + '64.12.96.0/19', + '149.174.160.0/20', + '152.163.240.0/21', + '152.163.248.0/22', + '152.163.252.0/23', + '152.163.96.0/22', + '152.163.100.0/23', + '195.93.32.0/22', + '195.93.48.0/22', + '195.93.64.0/19', + '195.93.96.0/19', + '195.93.16.0/20', + '198.81.0.0/22', + '198.81.16.0/20', + '198.81.8.0/23', + '202.67.64.128/25', + '205.188.192.0/20', + '205.188.208.0/23', + '205.188.112.0/20', + '205.188.146.144/30', + '207.200.112.0/21', + ); + + static $parsedRanges; + if ( is_null( $parsedRanges ) ) { + $parsedRanges = array(); + foreach ( $ranges as $range ) { + $parsedRanges[] = IP::parseRange( $range ); + } + } + + $hex = IP::toHex( $ip ); + foreach ( $parsedRanges as $range ) { + if ( $hex >= $range[0] && $hex <= $range[1] ) { + return true; + } + } + return false; +} |