/* CloudTrail Viewer, is a Java desktop application for reading AWS CloudTrail logs files. Copyright (C) 2017 Mark P. Haskins This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package io.haskins.java.cloudtrailviewer.service; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.exception.GeoIp2Exception; import com.maxmind.geoip2.model.CityResponse; import com.maxmind.geoip2.record.Location; import io.haskins.java.cloudtrailviewer.model.event.Event; import org.springframework.stereotype.Service; import java.io.IOException; import java.net.InetAddress; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Service that handles Geo resolving of IP addresses to City / Country / Continent / Long and Lat * * Created by markhaskins on 05/01/2017. */ @Service class GeoService { private final static Logger LOGGER = Logger.getLogger("CloudTrail"); private static final String GEO_FILE = "geodata/GeoLite2-City.mmdb"; private static final Pattern REGEX_PATTERN = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); private DatabaseReader reader = null; public GeoService() { try { ClassLoader classLoader = this.getClass().getClassLoader(); reader = new DatabaseReader.Builder(classLoader.getResourceAsStream(GEO_FILE)).build(); } catch (Exception ex) { LOGGER.log(Level.WARNING, "Failed to load GeoIp Database", ex); } } void populateGeoData(Event event) { if (reader != null && isIp(event.getSourceIPAddress())) { try { InetAddress ipAddress = InetAddress.getByName(event.getSourceIPAddress()); CityResponse response = getCityResponse(ipAddress); event.setContinent(getContinent(response)); event.setCountry(getCountry(response)); String city = getCity(response); if (city == null) { city = ipAddress.getHostAddress(); } event.setCity(city); String latLng = getLatLong(response.getLocation()); event.setLatLng(latLng); } catch (IOException | GeoIp2Exception ex) { LOGGER.log(Level.WARNING, "Failed to convert SourceIpAddress to Geo data", ex); } } } CityResponse getCityResponse(InetAddress ipAddress) throws GeoIp2Exception, IOException { return reader.city(ipAddress); } String getCity(CityResponse cityResponse) { return cityResponse.getCity().getName(); } String getCountry(CityResponse cityResponse) { return cityResponse.getCountry().getName(); } String getContinent(CityResponse cityResponse) { return cityResponse.getContinent().getName(); } private String getLatLong(Location location) { return location.getLatitude() + "," + location.getLongitude(); } private boolean isIp(String eventSource) { Matcher m = REGEX_PATTERN.matcher(eventSource); return m.find(); } }