packagecom.vmware.horizon;importcom.google.common.annotations.VisibleForTesting;importcom.tricipher.saas.action.api.GlobalConfigService;importcom.vmware.horizon.common.utils.HorizonPropertyHolder;importcom.vmware.horizon.common.utils.system.ApplianceNetworkDetails;importcom.vmware.horizon.common.utils.system.ApplianceUtil;importjava.io.IOException;importjava.util.Optional;importjavax.servlet.Filter;importjavax.servlet.FilterChain;importjavax.servlet.FilterConfig;importjavax.servlet.ServletException;importjavax.servlet.ServletRequest;importjavax.servlet.ServletResponse;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.apache.commons.lang3.StringUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;@Component("HostHeaderFilter")publicclassHostHeaderFilterimplementsFilter{privatestaticfinalLoggerlog=LoggerFactory.getLogger(HostHeaderFilter.class);privatestaticfinalStringLOCALHOST="localhost";privatestaticfinalStringLOCALHOST_IP_ADDRESS="127.0.0.1";privatestaticfinalintINVALID_HOST_NAME_STATUS_CODE=444;@AutowiredprivateHorizonPropertyHolderhorizonPropertyHolder;@AutowiredprivateApplianceUtilapplianceUtil;@AutowiredprivateGlobalConfigServiceglobalConfigService;privateApplianceNetworkDetailsapplianceNetworkDetails=null;privateBooleanisOnPremise;privateBooleanisSingleTenant;publicHostHeaderFilter(){this.isOnPremise=Boolean.FALSE;this.isSingleTenant=Boolean.FALSE;}publicvoidinit(FilterConfigfilterConfig)throwsServletException{}publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainfilterChain)throwsIOException,ServletException{this.isOnPremise=this.globalConfigService.isServiceOnPrem();this.isSingleTenant=this.globalConfigService.isServiceSingleTenant();if(this.applianceNetworkDetails==null){this.applianceNetworkDetails=(ApplianceNetworkDetails)Optional.ofNullable(this.applianceUtil.getApplianceNetworkDetails()).orElse(newApplianceNetworkDetails());}if(request!=null&&requestinstanceofHttpServletRequest){HttpServletRequesthttpServletRequest=(HttpServletRequest)request;StringserverName=httpServletRequest.getServerName();if(StringUtils.isNotBlank(httpServletRequest.getHeader("Host"))&&StringUtils.isNotBlank(serverName)){serverName=serverName.trim();StringgatewayHostName=StringUtils.isNotBlank(this.horizonPropertyHolder.getGatewayHostName())?this.horizonPropertyHolder.getGatewayHostName().trim():"";booleanisValidServerName=this.isServerNameAmongTheValidList(serverName,gatewayHostName);if(!isValidServerName){isValidServerName=this.isServerNameValidForMultiTenantOnPremOrCloudCase(serverName,gatewayHostName);}if(!isValidServerName){log.error("Rejecting request since host header value does not match configured gateway.hostname or localhost or appliance hostname/IP address: {} ",serverName);if(responseinstanceofHttpServletResponse){((HttpServletResponse)response).setStatus(444);}return;}}}filterChain.doFilter(request,response);}publicvoiddestroy(){}privatebooleanisServerNameAmongTheValidList(StringserverName,StringgatewayHostName){returnserverName.equalsIgnoreCase(gatewayHostName)||serverName.equalsIgnoreCase(this.applianceNetworkDetails.getHostname())||serverName.equalsIgnoreCase(this.applianceNetworkDetails.getIpV4Address())||serverName.equalsIgnoreCase(this.applianceNetworkDetails.getIpV6Address())||serverName.equalsIgnoreCase("localhost")||serverName.equalsIgnoreCase("127.0.0.1");}privatebooleanisServerNameValidForMultiTenantOnPremOrCloudCase(StringserverName,StringgatewayHostName){if(!this.isSingleTenant||!this.isOnPremise){StringgatewayDomainName=this.getDomainFromHostname(gatewayHostName);if(StringUtils.isNotBlank(gatewayDomainName)&&serverName.toLowerCase().endsWith(gatewayDomainName.toLowerCase())){returnBoolean.TRUE;}}returnBoolean.FALSE;}@VisibleForTestingStringgetDomainFromHostname(Stringhostname){returnStringUtils.isNotBlank(hostname)&&hostname.indexOf(46)>0?StringUtils.substring(hostname,hostname.indexOf(".")+1).trim():"";}}