Browse Source

FIX Remote ip detection was wrong with proxy (example: cloudflare)

Laurent Destailleur 6 years ago
parent
commit
b6dac7da20

+ 2 - 2
htdocs/admin/geoipmaxmind.php

@@ -152,7 +152,7 @@ if ($geoip)
 	else print $langs->trans("Error");
 	*/
 	//var_dump($_SERVER);
-	$ip = $_SERVER['REMOTE_ADDR']?$_SERVER['REMOTE_ADDR']:(($_SERVER['HTTP_X_FORWARDED_FOR']?$_SERVER['HTTP_X_FORWARDED_FOR']:$_SERVER['HTTP_CLIENT_IP']));
+	$ip = getUserRemoteIP();
 	//$ip='91.161.249.43';
 	$isip=is_ip($ip);
 	if ($isip == 1)
@@ -162,7 +162,7 @@ if ($geoip)
 		if ($result) print $result;
 		else print $langs->trans("Error");
 	}
-	elseif ($isip == 2)
+	else
 	{
 		print '<br>'.$ip.' -> ';
 		$result=dol_print_ip($ip,1);

+ 3 - 2
htdocs/core/class/events.class.php

@@ -137,6 +137,7 @@ class Events // extends CommonObject
 
 		// Clean parameters
 		$this->description=trim($this->description);
+		if (empty($this->user_agent) && !empty($_SERVER['HTTP_USER_AGENT'])) $this->user_agent=$_SERVER['HTTP_USER_AGENT'];
 
 		// Check parameters
 		if (empty($this->description)) { $this->error='ErrorBadValueForParameterCreateEventDesc'; return -1; }
@@ -153,8 +154,8 @@ class Events // extends CommonObject
 		$sql.= ") VALUES (";
 		$sql.= " '".$this->db->escape($this->type)."',";
 		$sql.= " ".$conf->entity.",";
-		$sql.= " '".$this->db->escape($_SERVER['REMOTE_ADDR'])."',";
-		$sql.= " ".($_SERVER['HTTP_USER_AGENT']?"'".$this->db->escape(dol_trunc($_SERVER['HTTP_USER_AGENT'],250))."'":'NULL').",";
+		$sql.= " '".$this->db->escape(getUserRemoteIP())."',";
+		$sql.= " ".($this->user_agent ? "'".$this->db->escape(dol_trunc($this->user_agent,250))."'" : 'NULL').",";
 		$sql.= " '".$this->db->idate($this->dateevent)."',";
 		$sql.= " ".($user->id?"'".$this->db->escape($user->id)."'":'NULL').",";
 		$sql.= " '".$this->db->escape(dol_trunc($this->description,250))."'";

+ 262 - 2
htdocs/core/lib/functions.lib.php

@@ -2665,6 +2665,20 @@ function dol_print_ip($ip,$mode=0)
 	return $ret;
 }
 
+/**
+ * Return the IP of remote user.
+ * Take HTTP_X_FORWARDED_FOR (defined when using proxy)
+ * Then HTTP_CLIENT_IP if defined (rare)
+ * Then REMOTE_ADDR (not way to be modified by user but may be wrong if using proxy)
+ *
+ * @return	string		Ip of remote user.
+ */
+function getUserRemoteIP()
+{
+	$ip = $_SERVER['HTTP_X_FORWARDED_FOR']?$_SERVER['HTTP_X_FORWARDED_FOR']:(($_SERVER['HTTP_CLIENT_IP']?$_SERVER['HTTP_CLIENT_IP']:$_SERVER['REMOTE_ADDR']));
+	return $ip;
+}
+
 /**
  * 	Return a country code from IP. Empty string if not found.
  *
@@ -2708,7 +2722,7 @@ function dol_user_country()
 	$ret='';
 	if (! empty($conf->geoipmaxmind->enabled))
 	{
-		$ip=$_SERVER["REMOTE_ADDR"];
+		$ip=getUserRemoteIP();
 		$datafile=$conf->global->GEOIPMAXMIND_COUNTRY_DATAFILE;
 		//$ip='24.24.24.24';
 		//$datafile='E:\Mes Sites\Web\Admin1\awstats\maxmind\GeoIP.dat';
@@ -5783,7 +5797,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
 		'__USER_FIRSTNAME__' => (string) $user->firstname,
 		'__USER_FULLNAME__' => (string) $user->getFullName($outputlangs),
 		'__USER_SUPERVISOR_ID__' => (string) ($user->fk_user ? $user->fk_user : '0'),
-		'__USER_REMOTE_IP__' => (string) $_SERVER['REMOTE_ADDR']
+		'__USER_REMOTE_IP__' => (string) getUserRemoteIP()
 		)
 			);
 	}
@@ -6770,6 +6784,252 @@ function picto_from_langcode($codelang, $moreatt = '')
 	return img_picto_common($codelang, 'flags/'.strtolower($flagImage).'.png', $moreatt);
 }
 
+/**
+ * Return default language from country code
+ *
+ * @param 	string 	$countrycode	Country code like 'US', 'FR', 'CA', ...
+ * @return	string					Value of locale like 'en_US', 'fr_FR', ...
+ */
+function getLanguageCodeFromCountryCode($countrycode)
+{
+	$countrycodetolanguage = array(
+		'SA' => 'ar_AR',
+		'DK' => 'da_DA',
+		'CA' => 'en_CA',
+		'SE' => 'sv_SV'
+	);
+	if (! empty($countrycodetolanguage[$countrycode])) return $countrycodetolanguage[$countrycode];
+
+	// Locale list taken from:
+	// http://stackoverflow.com/questions/3191664/
+	// list-of-all-locales-and-their-short-codes
+	$locales = array(
+		'af-ZA',
+		'am-ET',
+		'ar-AE',
+		'ar-BH',
+		'ar-DZ',
+		'ar-EG',
+		'ar-IQ',
+		'ar-JO',
+		'ar-KW',
+		'ar-LB',
+		'ar-LY',
+		'ar-MA',
+		'arn-CL',
+		'ar-OM',
+		'ar-QA',
+		'ar-SA',
+		'ar-SY',
+		'ar-TN',
+		'ar-YE',
+		'as-IN',
+		'az-Cyrl-AZ',
+		'az-Latn-AZ',
+		'ba-RU',
+		'be-BY',
+		'bg-BG',
+		'bn-BD',
+		'bn-IN',
+		'bo-CN',
+		'br-FR',
+		'bs-Cyrl-BA',
+		'bs-Latn-BA',
+		'ca-ES',
+		'co-FR',
+		'cs-CZ',
+		'cy-GB',
+		'da-DK',
+		'de-AT',
+		'de-CH',
+		'de-DE',
+		'de-LI',
+		'de-LU',
+		'dsb-DE',
+		'dv-MV',
+		'el-GR',
+		'en-029',
+		'en-AU',
+		'en-BZ',
+		'en-CA',
+		'en-GB',
+		'en-IE',
+		'en-IN',
+		'en-JM',
+		'en-MY',
+		'en-NZ',
+		'en-PH',
+		'en-SG',
+		'en-TT',
+		'en-US',
+		'en-ZA',
+		'en-ZW',
+		'es-AR',
+		'es-BO',
+		'es-CL',
+		'es-CO',
+		'es-CR',
+		'es-DO',
+		'es-EC',
+		'es-ES',
+		'es-GT',
+		'es-HN',
+		'es-MX',
+		'es-NI',
+		'es-PA',
+		'es-PE',
+		'es-PR',
+		'es-PY',
+		'es-SV',
+		'es-US',
+		'es-UY',
+		'es-VE',
+		'et-EE',
+		'eu-ES',
+		'fa-IR',
+		'fi-FI',
+		'fil-PH',
+		'fo-FO',
+		'fr-BE',
+		'fr-CA',
+		'fr-CH',
+		'fr-FR',
+		'fr-LU',
+		'fr-MC',
+		'fy-NL',
+		'ga-IE',
+		'gd-GB',
+		'gl-ES',
+		'gsw-FR',
+		'gu-IN',
+		'ha-Latn-NG',
+		'he-IL',
+		'hi-IN',
+		'hr-BA',
+		'hr-HR',
+		'hsb-DE',
+		'hu-HU',
+		'hy-AM',
+		'id-ID',
+		'ig-NG',
+		'ii-CN',
+		'is-IS',
+		'it-CH',
+		'it-IT',
+		'iu-Cans-CA',
+		'iu-Latn-CA',
+		'ja-JP',
+		'ka-GE',
+		'kk-KZ',
+		'kl-GL',
+		'km-KH',
+		'kn-IN',
+		'kok-IN',
+		'ko-KR',
+		'ky-KG',
+		'lb-LU',
+		'lo-LA',
+		'lt-LT',
+		'lv-LV',
+		'mi-NZ',
+		'mk-MK',
+		'ml-IN',
+		'mn-MN',
+		'mn-Mong-CN',
+		'moh-CA',
+		'mr-IN',
+		'ms-BN',
+		'ms-MY',
+		'mt-MT',
+		'nb-NO',
+		'ne-NP',
+		'nl-BE',
+		'nl-NL',
+		'nn-NO',
+		'nso-ZA',
+		'oc-FR',
+		'or-IN',
+		'pa-IN',
+		'pl-PL',
+		'prs-AF',
+		'ps-AF',
+		'pt-BR',
+		'pt-PT',
+		'qut-GT',
+		'quz-BO',
+		'quz-EC',
+		'quz-PE',
+		'rm-CH',
+		'ro-RO',
+		'ru-RU',
+		'rw-RW',
+		'sah-RU',
+		'sa-IN',
+		'se-FI',
+		'se-NO',
+		'se-SE',
+		'si-LK',
+		'sk-SK',
+		'sl-SI',
+		'sma-NO',
+		'sma-SE',
+		'smj-NO',
+		'smj-SE',
+		'smn-FI',
+		'sms-FI',
+		'sq-AL',
+		'sr-Cyrl-BA',
+		'sr-Cyrl-CS',
+		'sr-Cyrl-ME',
+		'sr-Cyrl-RS',
+		'sr-Latn-BA',
+		'sr-Latn-CS',
+		'sr-Latn-ME',
+		'sr-Latn-RS',
+		'sv-FI',
+		'sv-SE',
+		'sw-KE',
+		'syr-SY',
+		'ta-IN',
+		'te-IN',
+		'tg-Cyrl-TJ',
+		'th-TH',
+		'tk-TM',
+		'tn-ZA',
+		'tr-TR',
+		'tt-RU',
+		'tzm-Latn-DZ',
+		'ug-CN',
+		'uk-UA',
+		'ur-PK',
+		'uz-Cyrl-UZ',
+		'uz-Latn-UZ',
+		'vi-VN',
+		'wo-SN',
+		'xh-ZA',
+		'yo-NG',
+		'zh-CN',
+		'zh-HK',
+		'zh-MO',
+		'zh-SG',
+		'zh-TW',
+		'zu-ZA',
+	);
+
+	foreach ($locales as $locale)
+	{
+		$locale_region = locale_get_region($locale);
+		$locale_language = locale_get_primary_language($locale);
+		$locale_array = array('language' => $locale_language, 'region' => $locale_region);
+		if (strtoupper($countrycode) == $locale_region)
+		{
+			return locale_compose($locale_array);
+		}
+	}
+
+	return null;
+}
+
 /**
  *  Complete or removed entries into a head array (used to build tabs).
  *  For example, with value added by external modules. Such values are declared into $conf->modules_parts['tab'].