From e4b0f5b3ed3deb89f1194eaa27c7a236f0b4ff00 Mon Sep 17 00:00:00 2001 From: Jerome Jutteau Date: Wed, 20 May 2015 11:52:34 +0200 Subject: [PATCH] add support for http_X_forwarded_for header, refs #36 Signed-off-by: Jerome Jutteau --- lib/functions.php | 59 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/lib/functions.php b/lib/functions.php index 0f42e21..2c799f2 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -1108,31 +1108,64 @@ function jirafeau_challenge_upload_ip ($cfg, $ip) return false; } +/** Tell if we have some HTTP headers generated by a proxy */ +function has_http_forwarded() +{ + if (!empty ($_SERVER['HTTP_X_FORWARDED_FOR'])) + return true; + if (!empty ($_SERVER['http_X_forwarded_for'])) + return true; + return false; +} + +/** + * Generate IP list from HTTP headers generated by a proxy + * return array of IP strings + */ +function get_ip_list_http_forwarded() +{ + $ip_list = array(); + if (!empty ($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + $l = explode (',', $_SERVER['HTTP_X_FORWARDED_FOR']); + foreach ($l as $ip) + array_push ($ip_list, preg_replace ('/\s+/', '', $ip)); + } + if (!empty ($_SERVER['http_X_forwarded_for'])) + { + $l = explode (',', $_SERVER['http_X_forwarded_for']); + foreach ($l as $ip) + { + // Separate IP from port + $ip = explode (':', $ip)[0]; + array_push ($ip_list, preg_replace ('/\s+/', '', $ip)); + } + } + return $ip_list; +} + /** * Get the ip address of the client from REMOTE_ADDR * or from HTTP_X_FORWARDED_FOR if behind a proxy * @returns an the client ip address */ function get_ip_address($cfg) { - if (count ($cfg['proxy_ip']) == 0 || - empty ($_SERVER['HTTP_X_FORWARDED_FOR'])) - return $_SERVER['REMOTE_ADDR']; + $remote = $_SERVER['REMOTE_ADDR']; + if (count ($cfg['proxy_ip']) == 0 || !has_http_forwarded ()) + return $remote; - $iplist = explode (',', $_SERVER['HTTP_X_FORWARDED_FOR']); - if (count ($iplist) == 0) - return $_SERVER['REMOTE_ADDR']; + $ip_list = get_ip_list_http_forwarded (); + if (count ($ip_list) == 0) + return $remote; foreach ($cfg['proxy_ip'] as $proxy_ip) { - if ($_SERVER['REMOTE_ADDR'] != $proxy_ip) + if ($remote != $proxy_ip) continue; - - // Take the last IP (the one which has been set by our proxy). - $ip = end($iplist); - $ip = preg_replace ('/\s+/', '', $ip); - return $ip; + // Take the last IP (the one which has been set by the defined proxy). + return end ($ip_list); } - return $_SERVER['REMOTE_ADDR']; + return $remote; } /** -- 2.34.1