UNOMI-96 improved ip check to allow ipv6 and avoid local or network address
Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/84a99295 Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/84a99295 Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/84a99295 Branch: refs/heads/feature-UNOMI-5-KARAF4 Commit: 84a992951a69faf5d3030997cbb635e1b6401cb0 Parents: c559ecd Author: dgaillard <dgaill...@jahia.com> Authored: Thu May 11 18:10:35 2017 +0200 Committer: dgaillard <dgaill...@jahia.com> Committed: Thu May 11 18:10:57 2017 +0200 ---------------------------------------------------------------------- .../actions/SetRemoteHostInfoAction.java | 51 ++++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/84a99295/plugins/request/src/main/java/org/apache/unomi/plugins/request/actions/SetRemoteHostInfoAction.java ---------------------------------------------------------------------- diff --git a/plugins/request/src/main/java/org/apache/unomi/plugins/request/actions/SetRemoteHostInfoAction.java b/plugins/request/src/main/java/org/apache/unomi/plugins/request/actions/SetRemoteHostInfoAction.java index f8f70e3..f0d29a2 100644 --- a/plugins/request/src/main/java/org/apache/unomi/plugins/request/actions/SetRemoteHostInfoAction.java +++ b/plugins/request/src/main/java/org/apache/unomi/plugins/request/actions/SetRemoteHostInfoAction.java @@ -23,6 +23,7 @@ import com.maxmind.geoip2.model.CityResponse; import net.sf.uadetector.ReadableUserAgent; import net.sf.uadetector.UserAgentStringParser; import net.sf.uadetector.service.UADetectorServiceFactory; +import org.apache.http.conn.util.InetAddressUtils; import org.apache.unomi.api.Event; import org.apache.unomi.api.Session; import org.apache.unomi.api.actions.Action; @@ -36,13 +37,15 @@ import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; -import java.util.regex.Pattern; public class SetRemoteHostInfoAction implements ActionExecutor { - public static final Pattern IPV4 = Pattern.compile("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"); private static final Logger logger = LoggerFactory.getLogger(SetRemoteHostInfoAction.class.getName()); + private DatabaseReader databaseReader; private String pathToGeoLocationDatabase; @@ -117,8 +120,8 @@ public class SetRemoteHostInfoAction implements ActionExecutor { session.setProperty("remoteAddr", remoteAddr); session.setProperty("remoteHost", httpServletRequest.getRemoteHost()); try { - if (!remoteAddr.equals("127.0.0.1") && IPV4.matcher(remoteAddr).matches()) { - ipLookup(remoteAddr, session); + if (isAValidIPAddress(remoteAddr)) { + ipLookupInDatabase(remoteAddr, session); } else { session.setProperty("sessionCountryCode", defaultSessionCountryCode); session.setProperty("sessionCountryName", defaultSessionCountryName); @@ -149,13 +152,6 @@ public class SetRemoteHostInfoAction implements ActionExecutor { return EventService.SESSION_UPDATED; } - private boolean ipLookup(String remoteAddr, Session session) { - if (databaseReader != null) { - return ipLookupInDatabase(remoteAddr, session); - } - return false; - } - @PostConstruct public void postConstruct() { // A File object pointing to your GeoIP2 or GeoLite2 database @@ -177,16 +173,15 @@ public class SetRemoteHostInfoAction implements ActionExecutor { } - public boolean ipLookupInDatabase(String remoteAddr, Session session) { + private boolean ipLookupInDatabase(String remoteAddr, Session session) { if (databaseReader == null) { return false; } - // Replace "city" with the appropriate method for your database, e.g., - // "country". - CityResponse cityResponse = null; try { - cityResponse = databaseReader.city(InetAddress.getByName(remoteAddr)); + // Replace "city" with the appropriate method for your database, e.g., + // "country". + CityResponse cityResponse = databaseReader.city(InetAddress.getByName(remoteAddr)); if (cityResponse.getCountry().getName() != null) { session.setProperty("sessionCountryCode", cityResponse.getCountry().getIsoCode()); @@ -220,4 +215,28 @@ public class SetRemoteHostInfoAction implements ActionExecutor { } return false; } + + private static boolean isAValidIPAddress(String remoteAddr) { + if (InetAddressUtils.isIPv4Address(remoteAddr) || InetAddressUtils.isIPv6Address(remoteAddr)) { + InetAddress addr; + try { + addr = InetAddress.getByName(remoteAddr); + } catch (UnknownHostException e) { + logger.debug("Cannot resolve IP", e); + return false; + } + // Check if the address is a valid special local or loop back + if (addr.isAnyLocalAddress() || addr.isLoopbackAddress()) { + return false; + } + + // Check if the address is not defined on any interface + try { + return NetworkInterface.getByInetAddress(addr) == null; + } catch (SocketException e) { + return false; + } + } + return false; + } }