package net.sourceforge.fenixedu.util; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import net.sourceforge.fenixedu._development.LogLevel; import net.sourceforge.fenixedu._development.PropertiesManager; import org.apache.log4j.Logger; import pt.ist.fenixWebFramework.servlets.filters.PathAccessControlFilter; public class HostAccessControl { private static final Logger logger = Logger.getLogger(PathAccessControlFilter.class); private static final String HOST_CONTROL_PROPERTIES = "/.pathAccessControl.properties"; private static final String HOST_CONTROL_NAME_PREFIX = "host.control.name."; private static HostAccessControl intance = new HostAccessControl(); public static HostAccessControl getInstance() { return HostAccessControl.intance; } private Map> configuration; public HostAccessControl() { super(); setupConfiguration(); } private void setupConfiguration() { this.configuration = new HashMap>(); try { Properties properties = new Properties(); PropertiesManager.loadProperties(properties, HOST_CONTROL_PROPERTIES); for (Object key : properties.keySet()) { String keyName = (String) key; if (keyName.startsWith(HOST_CONTROL_NAME_PREFIX)) { String name = keyName.substring(HOST_CONTROL_NAME_PREFIX.length()); String[] hostList = properties.get(key).toString().split(","); for (int i = 0; i < hostList.length; i++) { String host = hostList[i].trim(); if (host.length() > 0) { addEntry(name, host); } } // just for a cleaner message if (LogLevel.DEBUG) { logger.debug("access for '" + name + "' limited to " + this.configuration.get(name)); } } } } catch (IOException e) { throw new RuntimeException("failed to read the host access control properties '" + HOST_CONTROL_PROPERTIES + "'", e); } } private void addEntry(String name, String host) { List hostList = this.configuration.get(name); if (hostList == null) { hostList = new ArrayList(); this.configuration.put(name, hostList); } try { InetAddress[] addresses = InetAddress.getAllByName(host); for (int i = 0; i < addresses.length; i++) { hostList.add(addresses[i]); } } catch (UnknownHostException e) { if (LogLevel.WARN) { logger.warn("could not find host '" + host + "', host ignored."); } } } public static boolean isAllowed(String name, ServletRequest request) { return getInstance().isAllowed(name, getRemoteAddress(request)); } public static boolean isAllowed(Class type, ServletRequest request) { return isAllowed(type.getName(), request); } public static boolean isAllowed(Object object, ServletRequest request) { return isAllowed(object.getClass(), request); } private boolean isAllowed(String name, String address) { try { InetAddress remoteAddress = InetAddress.getByName(address); List hostList = this.configuration.get(name); if (hostList == null) { if (LogLevel.WARN) { logger.warn(name + " denied[" + remoteAddress + "]: allowed hosts not defined"); } return false; } for (InetAddress allowedHost : hostList) { if (remoteAddress.equals(allowedHost)) { if (LogLevel.DEBUG) { logger.debug(name + " allowed[" + remoteAddress + "]: matches group " + hostList); } return true; } } if (LogLevel.WARN) { logger.warn(name + " denied[" + remoteAddress + "]: is not member of " + hostList); } } catch (UnknownHostException e) { if (LogLevel.WARN) { logger.warn(name + " denied[" + address + "]: could not find host"); } } return false; } public static String getRemoteAddress(ServletRequest request) { if (request instanceof HttpServletRequest) { final HttpServletRequest httpServletRequest = (HttpServletRequest) request; final String xForwardFor = httpServletRequest.getHeader("x-forwarded-for"); if (xForwardFor != null && xForwardFor.length() > 0) { return xForwardFor; } } return request.getRemoteAddr(); } }