<?php
/**
* Functions for dealing with proxies
- * @package MediaWiki
*/
+/**
+ * Extracts the XFF string from the request header
+ * Checks first for "X-Forwarded-For", then "Client-ip"
+ * Note: headers are spoofable
+ * @return string
+ */
function wfGetForwardedFor() {
if( function_exists( 'apache_request_headers' ) ) {
// More reliable than $_SERVER due to case and -/_ folding
$set = apache_request_headers();
$index = 'X-Forwarded-For';
+ $index2 = 'Client-ip';
} else {
// Subject to spoofing with headers like X_Forwarded_For
$set = $_SERVER;
$index = 'HTTP_X_FORWARDED_FOR';
+ $index2 = 'CLIENT-IP';
}
+ #Try a couple of headers
if( isset( $set[$index] ) ) {
return $set[$index];
+ } else if( isset( $set[$index2] ) ) {
+ return $set[$index2];
} else {
return null;
}
}
-/** Work out the IP address based on various globals */
+/**
+ * Returns the browser/OS data from the request header
+ * Note: headers are spoofable
+ * @return string
+ */
+function wfGetAgent() {
+ if( function_exists( 'apache_request_headers' ) ) {
+ // More reliable than $_SERVER due to case and -/_ folding
+ $set = apache_request_headers();
+ $index = 'User-Agent';
+ } else {
+ // Subject to spoofing with headers like X_Forwarded_For
+ $set = $_SERVER;
+ $index = 'HTTP_USER_AGENT';
+ }
+ if( isset( $set[$index] ) ) {
+ return $set[$index];
+ } else {
+ return '';
+ }
+}
+
+/**
+ * Work out the IP address based on various globals
+ * For trusted proxies, use the XFF client IP (first of the chain)
+ * @return string
+ */
function wfGetIP() {
global $wgIP;
/* 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' );
$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];
return $ip;
}
+/**
+ * Checks if an IP is a trusted proxy providor
+ * Useful to tell if X-Fowarded-For data is possibly bogus
+ * Squid cache servers for the site and AOL are whitelisted
+ * @param string $ip
+ * @return bool
+ */
function wfIsTrustedProxy( $ip ) {
global $wgSquidServers, $wgSquidServersNoPurge;
/**
* Convert a network specification in CIDR notation to an integer network and a number of bits
+ * @return array(string, int)
*/
function wfParseCIDR( $range ) {
return IP::parseCIDR( $range );
/**
* Check if an IP address is in the local proxy list
+ * @return bool
*/
function wfIsLocallyBlockedProxy( $ip ) {
global $wgProxyList;
/**
* TODO: move this list to the database in a global IP info table incorporating
* trusted ISP proxies, blocked IP addresses and open proxies.
+ * @return bool
*/
function wfIsAOLProxy( $ip ) {
$ranges = array(
-?>
+