* [MOD] Improved client info data retrieving through reverse proxy.

This commit is contained in:
nuxsmin
2017-09-18 10:50:20 +02:00
parent be3599f855
commit c20568581a
10 changed files with 122 additions and 53 deletions

View File

@@ -29,6 +29,7 @@ defined('APP_ROOT') || die();
use SP\Core\Exceptions\SPException;
use SP\DataModel\TrackData;
use SP\Mgmt\Tracks\Track;
use SP\Util\HttpUtil;
use SP\Util\Util;
/**
@@ -48,7 +49,7 @@ class ApiUtil
try {
$TrackData = new TrackData();
$TrackData->setTrackSource('API');
$TrackData->setTrackIp(Util::getClientAddress());
$TrackData->setTrackIp(HttpUtil::getClientAddress());
Track::getItem($TrackData)->add();
} catch (SPException $e) {

View File

@@ -59,6 +59,7 @@ use SP\Mgmt\Users\UserPassRecover;
use SP\Mgmt\Users\UserPreferences;
use SP\Mgmt\Users\UserUtil;
use SP\Util\Checks;
use SP\Util\HttpUtil;
use SP\Util\Json;
use SP\Util\Util;
@@ -191,7 +192,7 @@ class LoginController
try {
$TrackData = new TrackData();
$TrackData->setTrackSource('Login');
$TrackData->setTrackIp(Util::getClientAddress());
$TrackData->setTrackIp(HttpUtil::getClientAddress());
$attempts = count(Track::getItem($TrackData)->getTracksForClientFromTime(time() - self::TIME_TRACKING));
} catch (SPException $e) {
@@ -222,7 +223,7 @@ class LoginController
try {
$TrackData = new TrackData();
$TrackData->setTrackSource('Login');
$TrackData->setTrackIp(Util::getClientAddress());
$TrackData->setTrackIp(HttpUtil::getClientAddress());
Track::getItem($TrackData)->add();
} catch (SPException $e) {

View File

@@ -54,6 +54,7 @@ use SP\Mgmt\Notices\Notice;
use SP\Mgmt\PublicLinks\PublicLink;
use SP\Mgmt\Users\User;
use SP\Util\Checks;
use SP\Util\HttpUtil;
use SP\Util\Util;
/**
@@ -606,7 +607,7 @@ class MainController extends ControllerBase implements ActionsInterface
$Message = new NoticeMessage();
$Message->setTitle(__('Enlace visualizado'));
$Message->addDescription(sprintf('%s : %s', __('Cuenta'), $PublicLink->getItemId()));
$Message->addDescription(sprintf('%s : %s', __('Origen'), Checks::demoIsEnabled() ? '*.*.*.*' : Util::getClientAddress(true)));
$Message->addDescription(sprintf('%s : %s', __('Origen'), Checks::demoIsEnabled() ? '*.*.*.*' : HttpUtil::getClientAddress(true)));
$Message->addDescription(sprintf('%s : %s', __('Agente'), Request::getRequestHeaders('HTTP_USER_AGENT')));
$Message->addDescription(sprintf('HTTPS : %s', Checks::httpsEnabled() ? 'ON' : 'OFF'));

View File

@@ -28,6 +28,7 @@ use Defuse\Crypto\Exception\CryptoException;
use Defuse\Crypto\Key;
use SP\Core\Init;
use SP\Http\Request;
use SP\Util\HttpUtil;
use SP\Util\Util;
/**
@@ -99,7 +100,7 @@ class SecureKeyCookie extends Cookie
*/
public function getCypher()
{
return md5(Request::getRequestHeaders('User-Agent') . Util::getClientAddress());
return md5(Request::getRequestHeaders('User-Agent') . HttpUtil::getClientAddress());
}
/**

View File

@@ -33,6 +33,7 @@ use SP\Core\Messages\NoticeMessage;
use SP\Core\Session;
use SP\Html\Html;
use SP\Util\Checks;
use SP\Util\HttpUtil;
use SP\Util\Util;
/**
@@ -61,7 +62,7 @@ class Email
if ($isEvent === true) {
$performer = Session::getUserData()->getUserLogin() ?: __('N/D');
$body[] = sprintf('%s: %s', Html::strongText(__('Acción')), $LogMessage->getAction(true));
$body[] = sprintf('%s: %s (%s)', Html::strongText(__('Realizado por')), $performer, Util::getClientAddress(true));
$body[] = sprintf('%s: %s (%s)', Html::strongText(__('Realizado por')), $performer, HttpUtil::getClientAddress(true));
$Mail->addCC(Config::getConfig()->getMailFrom());
}

View File

@@ -32,6 +32,7 @@ use SP\Core\Session;
use SP\Storage\DB;
use SP\Storage\QueryData;
use SP\Util\Checks;
use SP\Util\HttpUtil;
use SP\Util\Util;
defined('APP_ROOT') || die();
@@ -178,7 +179,7 @@ class Log extends ActionLog
$Data->setQuery($query);
$Data->addParam(Session::getUserData()->getUserLogin());
$Data->addParam(Session::getUserData()->getUserId());
$Data->addParam(Util::getClientAddress(true));
$Data->addParam(HttpUtil::getClientAddress(true));
$Data->addParam(utf8_encode($this->LogMessage->getAction(true)));
$Data->addParam($this->getLogLevel());
$Data->addParam(utf8_encode($description));
@@ -217,7 +218,7 @@ class Log extends ActionLog
$msg .= $this->LogMessage->getAction(true) . '|';
$msg .= $description . '|';
$msg .= '0|';
$msg .= sprintf('ip_addr="%s" user_name="%s"', Util::getClientAddress(), Session::getUserData()->getUserLogin());
$msg .= sprintf('ip_addr="%s" user_name="%s"', HttpUtil::getClientAddress(), Session::getUserData()->getUserLogin());
$Syslog = new Syslog();
$Syslog->setIsRemote(Checks::remoteSyslogIsEnabled());

View File

@@ -38,6 +38,7 @@ use SP\Mgmt\ItemTrait;
use SP\Mgmt\Users\UserUtil;
use SP\Storage\DB;
use SP\Storage\QueryData;
use SP\Util\HttpUtil;
use SP\Util\Util;
defined('APP_ROOT') || die();
@@ -67,7 +68,7 @@ class PublicLink extends PublicLinkBase implements ItemInterface
public function addLinkView()
{
$this->itemData->addCountViews();
$this->updateUseInfo(Util::getClientAddress(true));
$this->updateUseInfo(HttpUtil::getClientAddress(true));
$Log = new Log();
$LogMessage = $Log->getLogMessage();

View File

@@ -24,6 +24,8 @@
namespace SP\Util;
use SP\Http\Request;
/**
* Class HttpUtil
*
@@ -52,33 +54,18 @@ class HttpUtil
*/
public static function getHttpHost()
{
// Check in style of RFC 7239
if (isset($_SERVER['HTTP_FORWARDED'])
&& preg_match('/proto=(\w+);/i', $_SERVER['HTTP_FORWARDED'], $matchesProto)
&& preg_match('/host=(\w+);/i', $_SERVER['HTTP_FORWARDED'], $matchesHost)
) {
// Removes possible `"`-chars
$protocol = strtolower($matchesProto[0]);
$host = strtolower($matchesHost[0]);
$forwarded = self::getForwardedData();
// Check if prtocol and host are not empty
if (strlen($protocol) > 0 && strlen($host) > 0) {
return $protocol . '://' . $host;
}
// Check in style of RFC 7239
if (null !== $forwarded) {
return strtolower($forwarded['proto'] . '://' . $forwarded['host']);
}
$xForward = self::getXForwardedData();
// Check (deprecated) de facto standard
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'], $_SERVER['HTTP_X_FORWARDED_PROTO'])) {
// This only could be http or https
$protocol = str_replace('"', '', trim($_SERVER['HTTP_X_FORWARDED_PROTO']));
// This may be example.com or sub.example.com/syspass
$host = str_replace('"', '', trim($_SERVER['HTTP_X_FORWARDED_HOST']));
// Check if protocol and host are not empty
if (strlen($protocol) > 0 && strlen($host) > 0) {
return $protocol . '://' . $host;
}
if (null !== $xForward) {
return strtolower($xForward['proto'] . '://' . $xForward['host']);
}
// We got called directly
@@ -88,4 +75,98 @@ class HttpUtil
return 'http://' . $_SERVER['HTTP_HOST'];
}
/**
* Devolver datos de forward RFC 7239
*
* @see https://tools.ietf.org/html/rfc7239#section-7.5
* @return array|null
*/
public static function getForwardedData()
{
$forwarded = Request::getRequestHeaders('HTTP_FORWARDED');
// Check in style of RFC 7239
if ($forwarded !== ''
&& preg_match('/proto=(\w+);/i', $forwarded, $matchesProto)
&& preg_match('/host=(\w+);/i', $forwarded, $matchesHost)
) {
$data = [
'host ' => $matchesHost[0],
'proto' => $matchesProto[0],
'for' => self::getForwardedFor()
];
// Check if protocol and host are not empty
if (!empty($data['proto']) && !empty($data['host'])) {
return $data;
}
}
return null;
}
/**
* Devolver la dirección IP del cliente a través de proxy o directo
*
* @return array|string
*/
public static function getForwardedFor()
{
if (preg_match_all('/for=([0-9\.]+)[,;]+/i',
Request::getRequestHeaders('HTTP_FORWARDED'), $matchesFor)) {
return $matchesFor[1];
}
if (preg_match_all('/([\w.:]+)(,|$)/',
Request::getRequestHeaders('HTTP_X_FORWARDED_FOR'), $matchesFor)) {
return $matchesFor[1];
}
return $_SERVER['REMOTE_ADDR'];
}
/**
* Devolver datos de x-forward
*
* @return array|null
*/
public static function getXForwardedData()
{
$forwardedHost = Request::getRequestHeaders('HTTP_X_FORWARDED_HOST');
$forwardedProto = Request::getRequestHeaders('HTTP_X_FORWARDED_PROTO');
// Check (deprecated) de facto standard
if (!empty($forwardedHost) && !empty($forwardedProto)) {
$data = [
'host' => trim(str_replace('"', '', $forwardedHost)),
'proto' => trim(str_replace('"', '', $forwardedProto)),
'for' => self::getForwardedFor()
];
// Check if protocol and host are not empty
if (!empty($data['host']) && !empty($data['proto'])) {
return $data;
}
}
return null;
}
/**
* Devolver la dirección IP del cliente
*
* @param bool $fullForwarded Devolver la cadena de forward completa
* @return string|array
*/
public static function getClientAddress($fullForwarded = false)
{
$forwarded = self::getForwardedFor();
if (is_array($forwarded)) {
return $fullForwarded ? implode(',', $forwarded) : $forwarded[0];
}
return $forwarded;
}
}

View File

@@ -386,7 +386,7 @@ class Util
*/
public static function getVersion($retBuild = false, $normalized = false)
{
$build = 17091801;
$build = 17091802;
$version = [2, 1, 15];
if ($normalized === true) {
@@ -659,23 +659,4 @@ class Util
return [0, 0];
}
/**
* Devolver la dirección IP del cliente
*
* @param bool $fullForwarded Devolver la cadena de forward completa
* @return string
*/
public static function getClientAddress($fullForwarded = false)
{
$forwarded = Request::getRequestHeaders('X-Forwarded-For');
if ($forwarded !== '') {
if (preg_match_all('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $forwarded, $matches)) {
return $fullForwarded ? implode(',', $matches[0]) : $matches[0][0];
}
}
return $_SERVER['REMOTE_ADDR'];
}
}

View File

@@ -1,5 +1,5 @@
var $jscomp={scope:{},findInternal:function(a,e,c){a instanceof String&&(a=String(a));for(var g=a.length,k=0;k<g;k++){var l=a[k];if(e.call(c,l,k,a))return{i:k,v:l}}return{i:-1,v:void 0}}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,e,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[e]=c.value)};
$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(a,e,c,g){if(e){c=$jscomp.global;a=a.split(".");for(g=0;g<a.length-1;g++){var k=a[g];k in c||(c[k]={});c=c[k]}a=a[a.length-1];g=c[a];e=e(g);e!=g&&null!=e&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:e})}};
$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(a,e,c,g){if(e){c=$jscomp.global;a=a.split(".");for(g=0;g<a.length-1;g++){var k=a[g];k in c||(c[k]={});c=c[k]}a=a[a.length-1];g=c[a];e=e(g);e!=g&&null!=e&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:e})}};
$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,c){return $jscomp.findInternal(this,a,c).v}},"es6-impl","es3");
sysPass.Theme=function(a){var e=a.log,c={elems:{$wrap:$("#wrap-loading"),$loading:$("#loading")},show:function(a){void 0!==a&&!0===a&&c.elems.$wrap.addClass("overlay-full");c.elems.$wrap.show();c.elems.$loading.addClass("is-active")},hide:function(){c.elems.$wrap.removeClass("overlay-full").hide();c.elems.$loading.removeClass("is-active")},upgradeFull:function(){c.elems.$wrap.addClass("overlay-full")}},g=function(b){var f=0,d="",h="";a.passwordData.complexity.symbols&&(d+="!\"\\\u00b7@|#$~%&/()=?'\u00bf\u00a1^*[]\u00b7;,_-{}<>");
a.passwordData.complexity.numbers&&(d+="1234567890");a.passwordData.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",a.passwordData.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;f++<a.passwordData.complexity.numlength;)h+=d.charAt(Math.floor(Math.random()*(d.length-1)+0));$("#viewPass").attr("title",h);var c=zxcvbn(h);a.passwordData.passLength=h.length;b?(f=b.parent(),d=$("#"+b.attr("id")+"R"),a.outputResult(c,b),b=new MaterialTextfield,f.find("input:password").val(h),f.addClass(b.CssClasses_.IS_DIRTY).removeClass(b.CssClasses_.IS_INVALID),