From 2542c75d743a77bdaffe56b8165690a8aff5c555 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 6 Feb 2020 16:54:59 -0500 Subject: [PATCH 01/36] Added support for TSK_GEO_WAYPOINTS attribute in TSK_GPS_ROUTE --- .../autopsy/geolocation/MapPanel.java | 3 - .../datamodel/Bundle.properties-MERGED | 1 + .../autopsy/geolocation/datamodel/Route.java | 127 ++++++++++++++---- .../geolocation/datamodel/Waypoint.java | 16 ++- .../datamodel/WaypointBuilder.java | 60 ++++----- .../android/googlemaplocation.py | 45 +++---- 6 files changed, 165 insertions(+), 87 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java index 4d286467b8..aa528f77de 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java @@ -35,7 +35,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -58,7 +57,6 @@ import org.jxmapviewer.viewer.DefaultTileFactory; import org.jxmapviewer.viewer.GeoPosition; import org.jxmapviewer.viewer.TileFactory; import org.jxmapviewer.viewer.TileFactoryInfo; -import org.jxmapviewer.viewer.Waypoint; import org.jxmapviewer.viewer.WaypointPainter; import org.jxmapviewer.viewer.WaypointRenderer; import org.openide.util.NbBundle.Messages; @@ -69,7 +67,6 @@ import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException; import org.sleuthkit.datamodel.TskCoreException; import javax.imageio.ImageIO; import javax.swing.SwingUtilities; -import org.jxmapviewer.viewer.DefaultWaypointRenderer; /** * The map panel. This panel contains the jxmapviewer MapViewer diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED index a3ed4a8ad3..93f9329d9a 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED @@ -3,6 +3,7 @@ GEOTrack_point_label_header=Trackpoint for track: {0} LastKnownWaypoint_Label=Last Known Location Route_End_Label=End Route_Label=As-the-crow-flies Route +Route_point_label=Route point Route_Start_Label=Start SearchWaypoint_DisplayLabel=GPS Search TrackpointWaypoint_DisplayLabel=GPS Trackpoint diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index c08d2637ba..4181d96d14 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -25,14 +25,18 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.GeoWaypoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint; /** * A Route represents a TSK_GPS_ROUTE artifact which has a start and end point - * however the class was written with the assumption that routes may have - * more that two points. + * however the class was written with the assumption that routes may have more + * that two points. * */ -public class Route extends GeoPath{ +public class Route extends GeoPath { + private final Long timestamp; // This list is not expected to change after construction so the @@ -51,12 +55,11 @@ public class Route extends GeoPath{ }) Route(BlackboardArtifact artifact) throws GeoLocationDataException { super(artifact, Bundle.Route_Label()); - + Map attributeMap = Waypoint.getAttributesFromArtifactAsMap(artifact); - - addToPath(getRouteStartPoint(artifact, attributeMap)); - addToPath(getRouteEndPoint(artifact, attributeMap)); - + + createRoute(artifact, attributeMap); + BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); timestamp = attribute != null ? attribute.getValueLong() : null; @@ -82,19 +85,62 @@ public class Route extends GeoPath{ return Collections.unmodifiableList(propertiesList); } + /** + * Returns the route timestamp. + * + * @return Route timestamp + */ public Long getTimestamp() { return timestamp; } - + + /** + * Gets the route waypoint attributes from the map and creates the list of + * route waypoints. + * + * @param artifact Route artifact + * @param attributeMap Map of artifact attributes + * + * @throws GeoLocationDataException + */ + @Messages({ + "Route_point_label=Route point for route" + }) + private void createRoute(BlackboardArtifact artifact, Map attributeMap) throws GeoLocationDataException { + BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS); + + String label = getLabel(); + if (label == null || label.isEmpty()) { + label = Bundle.Route_point_label(); + } else { + label = String.format("%s: %s", Bundle.Route_point_label(), label); + } + + if (attribute != null) { + String value = attribute.getValueString(); + List waypointList = GeoWaypoints.deserializePoints(value); + + for (GeoWaypoint waypoint : waypointList) { + addToPath(new Waypoint(artifact, label, null, waypoint.getLatitude(), waypoint.getLongitude(), waypoint.getAltitude(), null, attributeMap, this)); + } + } else { + Waypoint start = getRouteStartPoint(artifact, attributeMap); + Waypoint end = getRouteEndPoint(artifact, attributeMap); + + addToPath(start); + addToPath(end); + } + } + /** * Get the route start point. * * @param artifact * @param attributeMap Map of artifact attributes for this waypoint. - * + * * An exception will be thrown if longitude or latitude is null. * - * @return Start waypoint + * @return Start waypoint * * @throws GeoLocationDataException. */ @@ -106,16 +152,14 @@ public class Route extends GeoPath{ BlackboardAttribute latitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START); BlackboardAttribute longitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START); BlackboardAttribute altitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE); - BlackboardAttribute pointTimestamp = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); if (latitude != null && longitude != null) { - return new Waypoint(artifact, - Bundle.Route_Start_Label(), - pointTimestamp != null ? pointTimestamp.getValueLong() : null, - latitude.getValueDouble(), + return new RoutePoint(artifact, + Bundle.Route_Start_Label(), + latitude.getValueDouble(), longitude.getValueDouble(), altitude != null ? altitude.getValueDouble() : null, - null, attributeMap, this); + attributeMap); } else { throw new GeoLocationDataException("Unable to create route start point, invalid longitude and/or latitude"); } @@ -123,8 +167,8 @@ public class Route extends GeoPath{ /** * Get the route End point. - * - * An exception will be thrown if longitude or latitude is null. + * + * An exception will be thrown if longitude or latitude is null. * * @param attributeMap Map of artifact attributes for this waypoint * @@ -139,19 +183,52 @@ public class Route extends GeoPath{ BlackboardAttribute latitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END); BlackboardAttribute longitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END); BlackboardAttribute altitude = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE); - BlackboardAttribute pointTimestamp = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); if (latitude != null && longitude != null) { - return new Waypoint(artifact, - Bundle.Route_End_Label(), - pointTimestamp != null ? pointTimestamp.getValueLong() : null, - latitude.getValueDouble(), + return new RoutePoint(artifact, + Bundle.Route_End_Label(), + latitude.getValueDouble(), longitude.getValueDouble(), altitude != null ? altitude.getValueDouble() : null, - null, attributeMap, this); + attributeMap); } else { throw new GeoLocationDataException("Unable to create route end point, invalid longitude and/or latitude"); } } + + /** + * Route waypoint specific implementation of Waypoint. + */ + private class RoutePoint extends Waypoint { + + /** + * Construct a RoutePoint + * + * @param artifact BlackboardArtifact for this waypoint + * @param label String waypoint label + * @param latitude Double waypoint latitude + * @param longitude Double waypoint longitude + * + * @param attributeMap A Map of attributes for the given artifact + * + * @throws GeoLocationDataException + */ + RoutePoint(BlackboardArtifact artifact, String label, Double latitude, Double longitude, Double altitude, Map attributeMap) throws GeoLocationDataException { + super(artifact, + label, + null, + latitude, + longitude, + altitude, + null, + attributeMap, + Route.this); + } + + @Override + public Long getTimestamp() { + return ((Route) getParentGeoPath()).getTimestamp(); + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Waypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Waypoint.java index acc9e89352..f0ec1e50d3 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Waypoint.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Waypoint.java @@ -43,7 +43,7 @@ public class Waypoint { final private String label; final private AbstractFile image; final private BlackboardArtifact artifact; - final private GeoPath path; + final private GeoPath parentGeoPath; final private List propertiesList; @@ -78,7 +78,7 @@ public class Waypoint { * @throws GeoLocationDataException Exception will be thrown if artifact did * not have a valid longitude and latitude. */ - Waypoint(BlackboardArtifact artifact, String label, Long timestamp, Double latitude, Double longitude, Double altitude, AbstractFile image, Map attributeMap, GeoPath path) throws GeoLocationDataException { + Waypoint(BlackboardArtifact artifact, String label, Long timestamp, Double latitude, Double longitude, Double altitude, AbstractFile image, Map attributeMap, GeoPath parentGeoPath) throws GeoLocationDataException { if (longitude == null || latitude == null) { throw new GeoLocationDataException("Invalid waypoint, null value passed for longitude or latitude"); } @@ -90,7 +90,7 @@ public class Waypoint { this.longitude = longitude; this.latitude = latitude; this.altitude = altitude; - this.path = path; + this.parentGeoPath = parentGeoPath; propertiesList = createGeolocationProperties(attributeMap); } @@ -173,13 +173,13 @@ public class Waypoint { } /** - * Returns the route that this waypoint is apart of . + * Returns the GeoPath that this waypoint is apart of . * * @return The waypoint route or null if the waypoint is not apart of a * route. */ - public GeoPath getPath() { - return path; + public GeoPath getParentGeoPath() { + return parentGeoPath; } /** @@ -231,6 +231,10 @@ public class Waypoint { } for (BlackboardAttribute.ATTRIBUTE_TYPE type : keys) { + // Don't add JSON properties to this list. + if (type.getValueType() == BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON) { + continue; + } String key = type.getDisplayName(); String value = attributeMap.get(type).getDisplayString(); diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java index 708b3a4803..12ca055a1c 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java @@ -39,39 +39,49 @@ import org.sleuthkit.datamodel.DataSource; public final class WaypointBuilder { private static final Logger logger = Logger.getLogger(WaypointBuilder.class.getName()); + + private final static String TIME_TYPE_IDS = String.format("%d, %d", + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()); + + private final static String GEO_ATTRIBUTE_TYPE_IDS = String.format("%d, %d, %d", + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(), + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS.getTypeID()); - // SELECT statement for getting a list of waypoints. - final static String GEO_ARTIFACT_QUERY + // SELECT statement for getting a list of waypoints where %s is a comma separated list + // of attribute type ids. + private final static String GEO_ARTIFACT_QUERY = "SELECT artifact_id, artifact_type_id " + "FROM blackboard_attributes " - + "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS + + "WHERE attribute_type_id IN (%s) "; //NON-NLS // SELECT statement to get only artifact_ids - final static String GEO_ARTIFACT_QUERY_ID_ONLY + private final static String GEO_ARTIFACT_QUERY_ID_ONLY = "SELECT artifact_id " + "FROM blackboard_attributes " - + "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS + + "WHERE attribute_type_id IN (%s) "; //NON-NLS // This Query will return a list of waypoint artifacts - final static String GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY + private final static String GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY = "SELECT blackboard_attributes.artifact_id " + "FROM blackboard_attributes, blackboard_artifacts " + "WHERE blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id " - + "AND blackboard_attributes.attribute_type_id IN(%d, %d) " + + "AND blackboard_attributes.attribute_type_id IN(%s) " + "AND data_source_obj_id IN (%s)"; //NON-NLS // Select will return the "most recent" timestamp from all waypoings - final static String MOST_RECENT_TIME + private final static String MOST_RECENT_TIME = "SELECT MAX(value_int64) - (%d * 86400)" //86400 is the number of seconds in a day. + "FROM blackboard_attributes " - + "WHERE attribute_type_id IN(%d, %d) " + + "WHERE attribute_type_id IN(%s) " + "AND artifact_id " + "IN ( " + "%s" //GEO_ARTIFACT with or without data source + " )"; // Returns a list of artifacts with no time stamp - final static String SELECT_WO_TIMESTAMP + private final static String SELECT_WO_TIMESTAMP = "SELECT DISTINCT artifact_id, artifact_type_id " + "FROM blackboard_attributes " + "WHERE artifact_id NOT IN (%s) " @@ -132,7 +142,7 @@ public final class WaypointBuilder { public static List getRoutes(List waypoints) { List routeList = new ArrayList<>(); for (Waypoint point : waypoints) { - GeoPath path = point.getPath(); + GeoPath path = point.getParentGeoPath(); if (path instanceof Route) { Route route = (Route) path; if (!routeList.contains(route)) { @@ -154,7 +164,7 @@ public final class WaypointBuilder { public static List getTracks(List waypoints) { List trackList = new ArrayList<>(); for (Waypoint point : waypoints) { - GeoPath path = point.getPath(); + GeoPath path = point.getParentGeoPath(); if (path instanceof Track) { Track route = (Track) path; if (!trackList.contains(route)) { @@ -506,9 +516,7 @@ public final class WaypointBuilder { // FROM blackboard_attributes // WHERE attribute_type_id IN (%d, %d) return String.format(SELECT_WO_TIMESTAMP, - String.format(GEO_ARTIFACT_QUERY_ID_ONLY, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()), + String.format(GEO_ARTIFACT_QUERY_ID_ONLY,TIME_TYPE_IDS), getWaypointListQuery(dataSources)); } @@ -541,15 +549,13 @@ public final class WaypointBuilder { // MOST_RECENT_TIME // SELECT MAX(value_int64) - (%d * 86400) // FROM blackboard_attributes -// WHERE attribute_type_id IN(%d, %d) +// WHERE attribute_type_id IN(%s) // AND artifact_id // IN ( %s ) // mostRecentQuery = String.format("AND value_int64 > (%s)", //NON-NLS String.format(MOST_RECENT_TIME, - cntDaysFromRecent, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(), + cntDaysFromRecent, TIME_TYPE_IDS, getWaypointListQuery(dataSources) )); } @@ -557,10 +563,8 @@ public final class WaypointBuilder { // GEO_ARTIFACT_QUERY // SELECT artifact_id, artifact_type_id // FROM blackboard_attributes -// WHERE attribute_type_id IN (%d, %d) - String query = String.format(GEO_ARTIFACT_QUERY, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()); +// WHERE attribute_type_id IN (%s) + String query = String.format(GEO_ARTIFACT_QUERY, TIME_TYPE_IDS); // That are in the list of artifacts for the given data Sources query += String.format("AND artifact_id IN(%s)", getWaypointListQuery(dataSources)); //NON-NLS @@ -591,10 +595,8 @@ public final class WaypointBuilder { // GEO_ARTIFACT_QUERY // SELECT artifact_id, artifact_type_id // FROM blackboard_attributes -// WHERE attribute_type_id IN (%d, %d) - return String.format(GEO_ARTIFACT_QUERY, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID()); +// WHERE attribute_type_id IN (%s) + return String.format(GEO_ARTIFACT_QUERY, GEO_ATTRIBUTE_TYPE_IDS); } String dataSourceList = ""; @@ -607,9 +609,7 @@ public final class WaypointBuilder { dataSourceList = dataSourceList.substring(0, dataSourceList.length() - 1); } - return String.format(GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY, - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), - BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(), + return String.format(GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY, GEO_ATTRIBUTE_TYPE_IDS, dataSourceList); } diff --git a/InternalPythonModules/android/googlemaplocation.py b/InternalPythonModules/android/googlemaplocation.py index d17162fb65..17522c576c 100644 --- a/InternalPythonModules/android/googlemaplocation.py +++ b/InternalPythonModules/android/googlemaplocation.py @@ -41,6 +41,7 @@ from org.sleuthkit.datamodel import BlackboardArtifact from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper import traceback import general @@ -52,15 +53,25 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): def __init__(self): self._logger = Logger.getLogger(self.__class__.__name__) + self.current_case = None + self.PROGRAM_NAME = "Google Maps History" + self.CAT_DESTINATION = "Destination" def analyze(self, dataSource, fileManager, context): + try: + self.current_case = Case.getCurrentCaseThrows() + except NoCurrentCaseException as ex: + self._logger.log(Level.WARNING, "No case currently open.", ex) + self._logger.log(Level.WARNING, traceback.format_exc()) + return + try: absFiles = fileManager.findFiles(dataSource, "da_destination_history") if absFiles.isEmpty(): return for abstractFile in absFiles: try: - jFile = File(Case.getCurrentCase().getTempDirectory(), str(abstractFile.getId()) + abstractFile.getName()) + jFile = File(self.current_case.getTempDirectory(), str(abstractFile.getId()) + abstractFile.getName()) ContentUtils.writeToFile(abstractFile, jFile, context.dataSourceIngestIsCancelled) self.__findGeoLocationsInDB(jFile.toString(), abstractFile) except Exception as ex: @@ -75,6 +86,8 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): return try: + artifactHelper = GeoArtifactsHelper(self.current_case.getSleuthkitCase(), + general.MODULE_NAME, abstractFile) Class.forName("org.sqlite.JDBC") # load JDBC driver connection = DriverManager.getConnection("jdbc:sqlite:" + databasePath) statement = connection.createStatement() @@ -100,32 +113,18 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): dest_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("dest_lng")) source_lat = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lat")) source_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lng")) - - attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, general.MODULE_NAME, "Destination")) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, time)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END, general.MODULE_NAME, dest_lat)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END, general.MODULE_NAME, dest_lng)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START, general.MODULE_NAME, source_lat)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_START, general.MODULE_NAME, source_lng)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, general.MODULE_NAME, dest_title)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION, general.MODULE_NAME, dest_address)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, general.MODULE_NAME, "Google Maps History")) - - artifact.addAttributes(attributes) - try: - # index the artifact for keyword search - blackboard = Case.getCurrentCase().getSleuthkitCase().getBlackboard() - blackboard.postArtifact(artifact, general.MODULE_NAME) - except Blackboard.BlackboardException as ex: - self._logger.log(Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) - self._logger.log(Level.SEVERE, traceback.format_exc()) - MessageNotifyUtil.Notify.error("Failed to index GPS route artifact for keyword search.", artifact.getDisplayName()) + + artifactHelper.addRoute(dest_title, time, dest_address, self.PROGRAM_NAME, self.CAT_DESTINATION, source_lat, source_lng, dest_lat, dest_lng) except SQLException as ex: # Unable to execute Google map locations SQL query against database. pass + except TskCoreException as ex: + self._logger.log(Level.SEVERE, "Failed to add route artifacts.", ex) + self._logger.log(Level.SEVERE, traceback.format_exc()) + except BlackboardException as ex: + self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) + self._logger.log(Level.WARNING, traceback.format_exc()) except Exception as ex: self._logger.log(Level.SEVERE, "Error processing google maps history.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) From e6b01d43e53fde77545feacef90499b61bd11337 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 6 Feb 2020 17:05:16 -0500 Subject: [PATCH 02/36] Remove unused import --- Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index 4181d96d14..e8991005b2 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -25,7 +25,6 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.GeoWaypoints; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint; From e4dac1cb90d83559016338175e39d4481ec8f404 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Fri, 7 Feb 2020 09:48:44 -0500 Subject: [PATCH 03/36] Added geolocation .properties changes --- .../autopsy/geolocation/datamodel/Bundle.properties-MERGED | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED index 93f9329d9a..649f580627 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED @@ -3,7 +3,7 @@ GEOTrack_point_label_header=Trackpoint for track: {0} LastKnownWaypoint_Label=Last Known Location Route_End_Label=End Route_Label=As-the-crow-flies Route -Route_point_label=Route point +Route_point_label=Route point for route Route_Start_Label=Start SearchWaypoint_DisplayLabel=GPS Search TrackpointWaypoint_DisplayLabel=GPS Trackpoint From f67c3cdbe53769aca782089848212ab629b60410 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Fri, 7 Feb 2020 13:06:09 -0500 Subject: [PATCH 04/36] Updated based on review comments --- .../autopsy/geolocation/datamodel/Bundle.properties-MERGED | 2 +- .../org/sleuthkit/autopsy/geolocation/datamodel/Route.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED index 649f580627..18627193b9 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED @@ -3,7 +3,7 @@ GEOTrack_point_label_header=Trackpoint for track: {0} LastKnownWaypoint_Label=Last Known Location Route_End_Label=End Route_Label=As-the-crow-flies Route -Route_point_label=Route point for route +Route_point_label=Waypoints for route Route_Start_Label=Start SearchWaypoint_DisplayLabel=GPS Search TrackpointWaypoint_DisplayLabel=GPS Trackpoint diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index e8991005b2..4e23ffaf14 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -31,7 +31,7 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint; /** * A Route represents a TSK_GPS_ROUTE artifact which has a start and end point * however the class was written with the assumption that routes may have more - * that two points. + * than two points. * */ public class Route extends GeoPath { @@ -103,7 +103,7 @@ public class Route extends GeoPath { * @throws GeoLocationDataException */ @Messages({ - "Route_point_label=Route point for route" + "Route_point_label=Waypoints for route" }) private void createRoute(BlackboardArtifact artifact, Map attributeMap) throws GeoLocationDataException { BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS); From 5f9eccc1b28ad6792ee1016bef4fe28a1f54cf29 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 11 Feb 2020 18:19:47 -0500 Subject: [PATCH 05/36] Update guava version in KWS project.xml --- KeywordSearch/nbproject/project.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 25e05e30fa..2de991d105 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -276,8 +276,8 @@ release/modules/ext/icu4j-3.8.jar - ext/guava-17.0.jar - release/modules/ext/guava-17.0.jar + ext/guava-19.0.jar + release/modules/ext/guava-19.0.jar ext/language-detector-0.6.jar From 7dcaa72f7842dadc2adc4dbd42bb12a4055fe70a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Thu, 13 Feb 2020 12:14:52 -0500 Subject: [PATCH 06/36] updated default for flag previous devices --- .../centralrepository/ingestmodule/CentralRepoIngestModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java index ec00dffe88..e561aeeff6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/ingestmodule/CentralRepoIngestModule.java @@ -67,7 +67,7 @@ final class CentralRepoIngestModule implements FileIngestModule { private static final String MODULE_NAME = CentralRepoIngestModuleFactory.getModuleName(); static final boolean DEFAULT_FLAG_TAGGED_NOTABLE_ITEMS = true; - static final boolean DEFAULT_FLAG_PREVIOUS_DEVICES = true; + static final boolean DEFAULT_FLAG_PREVIOUS_DEVICES = false; static final boolean DEFAULT_CREATE_CR_PROPERTIES = true; private final static Logger logger = Logger.getLogger(CentralRepoIngestModule.class.getName()); From 79fda8405055115823a515d4e9e4c7e40b8c5d82 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Thu, 13 Feb 2020 17:37:55 -0500 Subject: [PATCH 07/36] refactoring in EamDbSettingsDialog --- .../datamodel/CentralRepoDbUtil.java | 6 +- .../optionspanel/CentralRepoDbManager.java | 351 ++++++++++++++++++ .../optionspanel/EamDbSettingsDialog.form | 4 +- .../optionspanel/EamDbSettingsDialog.java | 281 ++------------ 4 files changed, 399 insertions(+), 243 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 4ba8ac579e..4cf0d8af67 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Coordinatio import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo.SOFTWARE_CR_DB_SCHEMA_VERSION; +import org.sleuthkit.autopsy.centralrepository.optionspanel.EamDbSettingsDialog; /** * @@ -177,8 +178,11 @@ public class CentralRepoDbUtil { "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) public static void upgradeDatabase() throws CentralRepoException { if (!CentralRepository.isEnabled()) { - return; + EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + dialog. + promptUserForSetup(); } + CentralRepository db = null; CoordinationService.Lock lock = null; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java new file mode 100755 index 0000000000..bd1d52b1f0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java @@ -0,0 +1,351 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +import java.awt.Cursor; +import java.io.File; +import java.util.logging.Level; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import org.openide.util.NbBundle; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; +import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; +import org.sleuthkit.autopsy.centralrepository.optionspanel.DatabaseTestResult; +import org.sleuthkit.autopsy.coreutils.Logger; + + +public class CentralRepoDbManager { + private static final String CENTRAL_REPO_DB_NAME = "central_repository"; + private static final String CENTRAL_REPO_SQLITE_EXT = ".db"; + + private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); + + private DatabaseTestResult testingStatus; + private CentralRepoPlatforms selectedPlatform; + + private PostgresCentralRepoSettings dbSettingsPostgres; + private SqliteCentralRepoSettings dbSettingsSqlite; + + private boolean configurationChanged = false; + + + public CentralRepoDbManager() { + dbSettingsPostgres = new PostgresCentralRepoSettings(); + dbSettingsSqlite = new SqliteCentralRepoSettings(); + selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + if (selectedPlatform == null || selectedPlatform.equals(CentralRepoPlatforms.DISABLED)) { + selectedPlatform = CentralRepoPlatforms.POSTGRESQL; + } + } + + /** + * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) + * @param warnDoesNotExist whether or not to prompt the user should the database not exist (otherwise silently create the db) + * @return whether or not the ultimate status after prompts is okay to continue + */ + @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", + "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", + "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", + "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again."}) + private boolean promptTestStatusWarnings(boolean warnDoesNotExist) { + if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) { + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), + JOptionPane.WARNING_MESSAGE); + } else if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) { + // There's an existing database or file, but it's not in our format. + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), + JOptionPane.WARNING_MESSAGE); + } else if (testingStatus == DatabaseTestResult.DB_DOES_NOT_EXIST) { + //database doesn't exist do you want to create + boolean createDb = (!warnDoesNotExist || + JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), + JOptionPane.YES_NO_OPTION)); + + if (createDb) + createDb(); + } + + return (testingStatus == DatabaseTestResult.TESTEDOK); + } + + + + + + + @NbBundle.Messages({"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database", + "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", + "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again."}) + private boolean createDb() { + boolean result = false; + boolean dbCreated = true; + switch (selectedPlatform) { + case POSTGRESQL: + if (!dbSettingsPostgres.verifyDatabaseExists()) { + dbCreated = dbSettingsPostgres.createDatabase(); + } + if (dbCreated) { + result = dbSettingsPostgres.initializeDatabaseSchema() + && dbSettingsPostgres.insertDefaultDatabaseContent(); + } + if (!result) { + // Remove the incomplete database + if (dbCreated) { + dbSettingsPostgres.deleteDatabase(); + } + + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(), + Bundle.EamDbSettingsDialog_okButton_createDbError_title(), + JOptionPane.WARNING_MESSAGE); + logger.severe("Unable to initialize database schema or insert contents into central repository."); + return false; + } + break; + case SQLITE: + if (!dbSettingsSqlite.dbDirectoryExists()) { + dbCreated = dbSettingsSqlite.createDbDirectory(); + } + if (dbCreated) { + result = dbSettingsSqlite.initializeDatabaseSchema() + && dbSettingsSqlite.insertDefaultDatabaseContent(); + } + if (!result) { + if (dbCreated) { + dbSettingsSqlite.deleteDatabase(); + } + + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(), + Bundle.EamDbSettingsDialog_okButton_createDbError_title(), + JOptionPane.WARNING_MESSAGE); + logger.severe("Unable to initialize database schema or insert contents into central repository."); + return false; + } + break; + } + testingStatus = DatabaseTestResult.TESTEDOK; + return true; + } + + + /** + * saves a new central repository based on current settings + */ + @NbBundle.Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.", + "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", + "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) + private void saveNewCentralRepo() { + /** + * We have to shutdown the previous platform's connection pool first; + * assuming it wasn't DISABLED. This will close any existing idle + * connections. + * + * The next use of an EamDb API method will start a new connection pool + * using those new settings. + */ + try { + CentralRepository previousDbManager = CentralRepository.getInstance(); + if (null != previousDbManager) { + // NOTE: do not set/save the seleted platform before calling this. + CentralRepository.getInstance().shutdownConnections(); + } + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Failed to close database connections in previously selected platform.", ex); // NON-NLS + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(this, + Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), + Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), + JOptionPane.WARNING_MESSAGE); + }); + } + + // Even if we fail to close the existing connections, make sure that we + // save the new connection settings, so an Autopsy restart will correctly + // start with the new settings. + CentralRepoPlatforms.setSelectedPlatform(selectedPlatform.name()); + CentralRepoPlatforms.saveSelectedPlatform(); + + switch (selectedPlatform) { + case POSTGRESQL: + // save the new PostgreSQL settings + dbSettingsPostgres.saveSettings(); + // Load those newly saved settings into the postgres db manager instance + // in case we are still using the same instance. + try { + CentralRepository.getInstance().updateSettings(); + configurationChanged = true; + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return; + } + + break; + case SQLITE: + // save the new SQLite settings + dbSettingsSqlite.saveSettings(); + // Load those newly saved settings into the sqlite db manager instance + // in case we are still using the same instance. + try { + CentralRepository.getInstance().updateSettings(); + configurationChanged = true; + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return; + } + break; + case DISABLED: + break; + } + } + + + static class DatabaseSettingsValidResult { + private final String errorMessage; + private final boolean success; + + public DatabaseSettingsValidResult(String errorMessage, boolean success) { + this.errorMessage = errorMessage; + this.success = success; + } + + public String getErrorMessage() { + return errorMessage; + } + + public boolean isSuccess() { + return success; + } + } + + + /** + * Tests whether or not the database settings are valid. + * + * @return True or false. + */ + private DatabaseSettingsValidResult databaseSettingsAreValid( + String tbDbHostname, Integer tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) { + + boolean result = true; + StringBuilder guidanceText = new StringBuilder(); + + switch (selectedPlatform) { + case POSTGRESQL: + try { + dbSettingsPostgres.setHost(tbDbHostname); + } catch (CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + + try { + dbSettingsPostgres.setPort(tbDbPort); + } catch (NumberFormatException | CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + + try { + dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); + } catch (CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + + try { + dbSettingsPostgres.setUserName(tbDbUsername); + } catch (CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + + try { + dbSettingsPostgres.setPassword(jpDbPassword); + } catch (CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + break; + case SQLITE: + try { + File databasePath = new File(tfDatabasePath); + dbSettingsSqlite.setDbName(CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT); + dbSettingsSqlite.setDbDirectory(databasePath.getPath()); + } catch (CentralRepoException ex) { + guidanceText.append(ex.getMessage()); + result = false; + } + break; + } + + return new DatabaseSettingsValidResult(guidanceText.toString(), result); + } + + + private DatabaseTestResult testDbSettings() { + switch (selectedPlatform) { + case POSTGRESQL: + if (dbSettingsPostgres.verifyConnection()) { + if (dbSettingsPostgres.verifyDatabaseExists()) { + if (dbSettingsPostgres.verifyDatabaseSchema()) { + testingStatus = DatabaseTestResult.TESTEDOK; + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; + } + } else { + testingStatus = DatabaseTestResult.CONNECTION_FAILED; + } + break; + case SQLITE: + if (dbSettingsSqlite.dbFileExists()) { + if (dbSettingsSqlite.verifyConnection()) { + if (dbSettingsSqlite.verifyDatabaseSchema()) { + testingStatus = DatabaseTestResult.TESTEDOK; + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; + } + break; + } + + return testingStatus; + } + + + /** + * Returns if changes to the central repository configuration were + * successfully applied + * + * @return true if the database configuration was successfully changed false + * if it was not + */ + boolean wasConfigurationChanged() { + return configurationChanged; + } +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form index 0f39326bec..27eae7629c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.form @@ -133,7 +133,7 @@ - + @@ -410,4 +410,4 @@ - \ No newline at end of file + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 271a8a4f04..4bd17b561e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -45,6 +45,7 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatf import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.centralrepository.optionspanel.DatabaseTestResult; /** * Configuration dialog for Central Repository database settings. @@ -53,17 +54,15 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; public class EamDbSettingsDialog extends JDialog { private static final Logger logger = Logger.getLogger(EamDbSettingsDialog.class.getName()); - private static final String CENTRAL_REPO_DB_NAME = "central_repository"; - private static final String CENTRAL_REPO_SQLITE_EXT = ".db"; + private static final long serialVersionUID = 1L; private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; - private final PostgresCentralRepoSettings dbSettingsPostgres; - private final SqliteCentralRepoSettings dbSettingsSqlite; - private DatabaseTestResult testingStatus; - private CentralRepoPlatforms selectedPlatform; - private boolean configurationChanged = false; + + + + /** * Creates new form EamDbSettingsDialog @@ -80,12 +79,6 @@ public class EamDbSettingsDialog extends JDialog { textBoxes = new ArrayList<>(); textBoxChangedListener = new TextBoxChangedListener(); - dbSettingsPostgres = new PostgresCentralRepoSettings(); - dbSettingsSqlite = new SqliteCentralRepoSettings(); - selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); - if (selectedPlatform == null || selectedPlatform.equals(CentralRepoPlatforms.DISABLED)) { - selectedPlatform = CentralRepoPlatforms.POSTGRESQL; - } initComponents(); fcDatabasePath.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); @@ -398,215 +391,27 @@ public class EamDbSettingsDialog extends JDialog { } }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed - private void testDbSettings() { - switch (selectedPlatform) { - case POSTGRESQL: - if (dbSettingsPostgres.verifyConnection()) { - if (dbSettingsPostgres.verifyDatabaseExists()) { - if (dbSettingsPostgres.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; - } - } else { - testingStatus = DatabaseTestResult.CONNECTION_FAILED; - } - break; - case SQLITE: - if (dbSettingsSqlite.dbFileExists()) { - if (dbSettingsSqlite.verifyConnection()) { - if (dbSettingsSqlite.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; - } - break; - } - valid(); - } - @Messages({"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database", - "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", - "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again."}) - private void createDb() { - boolean result = false; - boolean dbCreated = true; - switch (selectedPlatform) { - case POSTGRESQL: - if (!dbSettingsPostgres.verifyDatabaseExists()) { - dbCreated = dbSettingsPostgres.createDatabase(); - } - if (dbCreated) { - result = dbSettingsPostgres.initializeDatabaseSchema() - && dbSettingsPostgres.insertDefaultDatabaseContent(); - } - if (!result) { - // Remove the incomplete database - if (dbCreated) { - dbSettingsPostgres.deleteDatabase(); - } - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(), - Bundle.EamDbSettingsDialog_okButton_createDbError_title(), - JOptionPane.WARNING_MESSAGE); - logger.severe("Unable to initialize database schema or insert contents into central repository."); - return; - } - break; - case SQLITE: - if (!dbSettingsSqlite.dbDirectoryExists()) { - dbCreated = dbSettingsSqlite.createDbDirectory(); - } - if (dbCreated) { - result = dbSettingsSqlite.initializeDatabaseSchema() - && dbSettingsSqlite.insertDefaultDatabaseContent(); - } - if (!result) { - if (dbCreated) { - dbSettingsSqlite.deleteDatabase(); - } - - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(), - Bundle.EamDbSettingsDialog_okButton_createDbError_title(), - JOptionPane.WARNING_MESSAGE); - logger.severe("Unable to initialize database schema or insert contents into central repository."); - return; - } - break; - } - testingStatus = DatabaseTestResult.TESTEDOK; - valid(); - } - - /** - * Returns if changes to the central repository configuration were - * successfully applied - * - * @return true if the database configuration was successfully changed false - * if it was not - */ - boolean wasConfigurationChanged() { - return configurationChanged; - } - - @Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.", - "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", - "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database.", - "EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", - "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", - "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", - "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again."}) private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); testDbSettings(); - if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) { - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), - JOptionPane.WARNING_MESSAGE); - } else if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) { - // There's an existing database or file, but it's not in our format. - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), - JOptionPane.WARNING_MESSAGE); - } else if (testingStatus == DatabaseTestResult.DB_DOES_NOT_EXIST) { - //database doesn't exist do you want to create - if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), - JOptionPane.YES_NO_OPTION)) { - createDb(); - } - } - if (testingStatus != DatabaseTestResult.TESTEDOK) { + boolean testedOk = promptTestStatusWarnings(true); + if (!testedOk) { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return; } - - /** - * We have to shutdown the previous platform's connection pool first; - * assuming it wasn't DISABLED. This will close any existing idle - * connections. - * - * The next use of an EamDb API method will start a new connection pool - * using those new settings. - */ - try { - CentralRepository previousDbManager = CentralRepository.getInstance(); - if (null != previousDbManager) { - // NOTE: do not set/save the seleted platform before calling this. - CentralRepository.getInstance().shutdownConnections(); - } - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Failed to close database connections in previously selected platform.", ex); // NON-NLS - SwingUtilities.invokeLater(() -> { - JOptionPane.showMessageDialog(this, - Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), - Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), - JOptionPane.WARNING_MESSAGE); - }); - } - - // Even if we fail to close the existing connections, make sure that we - // save the new connection settings, so an Autopsy restart will correctly - // start with the new settings. - CentralRepoPlatforms.setSelectedPlatform(selectedPlatform.name()); - CentralRepoPlatforms.saveSelectedPlatform(); - - switch (selectedPlatform) { - case POSTGRESQL: - // save the new PostgreSQL settings - dbSettingsPostgres.saveSettings(); - // Load those newly saved settings into the postgres db manager instance - // in case we are still using the same instance. - try { - CentralRepository.getInstance().updateSettings(); - configurationChanged = true; - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - return; - } - - break; - case SQLITE: - // save the new SQLite settings - dbSettingsSqlite.saveSettings(); - // Load those newly saved settings into the sqlite db manager instance - // in case we are still using the same instance. - try { - CentralRepository.getInstance().updateSettings(); - configurationChanged = true; - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - return; - } - break; - case DISABLED: - break; - } + + saveNewCentralRepo(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); dispose(); }//GEN-LAST:event_bnOkActionPerformed + + private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed dispose(); }//GEN-LAST:event_bnCancelActionPerformed @@ -757,6 +562,35 @@ public class EamDbSettingsDialog extends JDialog { && databaseSettingsAreValid(); } + + /** + * Validates that the form is filled out correctly for our usage. + * + * @return true if it's okay, false otherwise. + */ + private boolean valid() { + return enableOkButton(checkFields()); + } + + /** + * Enable the "OK" button if the db test passed. Disabled defaults to db + * test passed. + * + * @return true + */ + @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options. Or select a different database type."}) + private boolean enableOkButton(boolean isValidInput) { + if (isValidInput) { + bnOk.setEnabled(true); + } else { + bnOk.setEnabled(false); + } + return true; + + } + + + /** * Tests whether or not the database settings are valid. * @@ -818,32 +652,6 @@ public class EamDbSettingsDialog extends JDialog { return result; } - /** - * Validates that the form is filled out correctly for our usage. - * - * @return true if it's okay, false otherwise. - */ - private boolean valid() { - return enableOkButton(checkFields()); - } - - /** - * Enable the "OK" button if the db test passed. Disabled defaults to db - * test passed. - * - * @return true - */ - @Messages({"EamDbSettingsDialog.validation.finished=Click OK to save your database settings and return to the Options. Or select a different database type."}) - private boolean enableOkButton(boolean isValidInput) { - if (isValidInput) { - bnOk.setEnabled(true); - } else { - bnOk.setEnabled(false); - } - return true; - - } - /** * Used to listen for changes in text boxes. It lets the panel know things * have been updated and that validation needs to happen. @@ -876,13 +684,6 @@ public class EamDbSettingsDialog extends JDialog { } } - private enum DatabaseTestResult { - UNTESTED, - CONNECTION_FAILED, - SCHEMA_INVALID, - DB_DOES_NOT_EXIST, - TESTEDOK; - } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton bnCancel; From f13160df2e9eb6892bb5afc8d8a6d8cfe8257287 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Thu, 13 Feb 2020 17:39:12 -0500 Subject: [PATCH 08/36] adding DatabaseTestResult --- .../optionspanel/DatabaseTestResult.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java new file mode 100755 index 0000000000..f936e6af55 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java @@ -0,0 +1,15 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +enum DatabaseTestResult { + UNTESTED, + CONNECTION_FAILED, + SCHEMA_INVALID, + DB_DOES_NOT_EXIST, + TESTEDOK; +} + From 5befaf6b21c4387f8491291220c62f7f08e76704 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Fri, 14 Feb 2020 09:14:14 -0500 Subject: [PATCH 09/36] continuing refactor of Central Repo Db Manager --- .../CentralRepoDbManager.java | 131 ++++++++++++------ .../datamodel/CentralRepoDbUtil.java | 81 ----------- .../DatabaseTestResult.java | 4 +- .../eventlisteners/Installer.java | 3 +- .../optionspanel/EamDbSettingsDialog.java | 51 ++++++- .../optionspanel/GlobalSettingsPanel.java | 3 +- 6 files changed, 137 insertions(+), 136 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/{optionspanel => datamodel}/CentralRepoDbManager.java (70%) rename Core/src/org/sleuthkit/autopsy/centralrepository/{optionspanel => datamodel}/DatabaseTestResult.java (75%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java similarity index 70% rename from Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index bd1d52b1f0..9a50b7f209 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -3,21 +3,18 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package org.sleuthkit.autopsy.centralrepository.optionspanel; +package org.sleuthkit.autopsy.centralrepository.datamodel; import java.awt.Cursor; import java.io.File; +import java.sql.SQLException; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; -import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; -import org.sleuthkit.autopsy.centralrepository.optionspanel.DatabaseTestResult; +import org.sleuthkit.autopsy.centralrepository.optionspanel.EamDbSettingsDialog; +import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coreutils.Logger; @@ -26,6 +23,80 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_SQLITE_EXT = ".db"; private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); + + /** + * Upgrade the current Central Reposity schema to the newest version. If the + * upgrade fails, the Central Repository will be disabled and the current + * settings will be cleared. + */ + @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) + public static void upgradeDatabase() throws CentralRepoException { + if (!CentralRepository.isEnabled()) { + EamDbSettingsDialog dialog = new EamDbSettingsDialog(); + dialog.promptUserForSetup(); + } + CentralRepository db = null; + CoordinationService.Lock lock = null; + //get connection + try { + try { + db = CentralRepository.getInstance(); + } catch (CentralRepoException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); + throw new CentralRepoException("Error updating central repository, unable to make connection", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } + //get lock necessary for upgrade + if (db != null) { + try { + // This may return null if locking isn't supported, which is fine. It will + // throw an exception if locking is supported but we can't get the lock + // (meaning the database is in use by another user) + lock = db.getExclusiveMultiUserDbLock(); + //perform upgrade + } catch (CentralRepoException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); + throw new CentralRepoException("Error updating central repository, unable to acquire exclusive lock", Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } + try { + db.upgradeSchema(); + } catch (CentralRepoException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + throw new CentralRepoException("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (SQLException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + throw new CentralRepoException("Error updating central repository", Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (IncompatibleCentralRepoException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + throw new CentralRepoException("Error updating central repository", ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } finally { + if (lock != null) { + try { + lock.release(); + } catch (CoordinationService.CoordinationServiceException ex) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error releasing database lock", ex); + } + } + } + } else { + throw new CentralRepoException("Unable to connect to database", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message()); + } + } catch (CentralRepoException ex) { + // Disable the central repo and clear the current settings. + try { + if (null != CentralRepository.getInstance()) { + CentralRepository.getInstance().shutdownConnections(); + } + } catch (CentralRepoException ex2) { + CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); + } + CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); + CentralRepoPlatforms.saveSelectedPlatform(); + throw ex; + } + } + + + private DatabaseTestResult testingStatus; private CentralRepoPlatforms selectedPlatform; @@ -45,43 +116,7 @@ public class CentralRepoDbManager { } } - /** - * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) - * @param warnDoesNotExist whether or not to prompt the user should the database not exist (otherwise silently create the db) - * @return whether or not the ultimate status after prompts is okay to continue - */ - @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", - "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", - "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", - "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again."}) - private boolean promptTestStatusWarnings(boolean warnDoesNotExist) { - if (testingStatus == DatabaseTestResult.CONNECTION_FAILED) { - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), - JOptionPane.WARNING_MESSAGE); - } else if (testingStatus == DatabaseTestResult.SCHEMA_INVALID) { - // There's an existing database or file, but it's not in our format. - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), - JOptionPane.WARNING_MESSAGE); - } else if (testingStatus == DatabaseTestResult.DB_DOES_NOT_EXIST) { - //database doesn't exist do you want to create - boolean createDb = (!warnDoesNotExist || - JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), - JOptionPane.YES_NO_OPTION)); - - if (createDb) - createDb(); - } - return (testingStatus == DatabaseTestResult.TESTEDOK); - } @@ -91,7 +126,7 @@ public class CentralRepoDbManager { @NbBundle.Messages({"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database", "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again."}) - private boolean createDb() { + public boolean createDb() { boolean result = false; boolean dbCreated = true; switch (selectedPlatform) { @@ -215,6 +250,14 @@ public class CentralRepoDbManager { break; } } + + public DatabaseTestResult getStatus() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + public CentralRepoPlatforms getSelectedPlatform() { + return selectedPlatform; + } static class DatabaseSettingsValidResult { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 4cf0d8af67..60701b44e5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -25,13 +25,9 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.logging.Level; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.coordinationservice.CoordinationService; -import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo.SOFTWARE_CR_DB_SCHEMA_VERSION; -import org.sleuthkit.autopsy.centralrepository.optionspanel.EamDbSettingsDialog; /** * @@ -167,83 +163,6 @@ public class CentralRepoDbUtil { return true; } - /** - * Upgrade the current Central Reposity schema to the newest version. If the - * upgrade fails, the Central Repository will be disabled and the current - * settings will be cleared. - */ - @Messages({"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", - "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", - "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", - "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) - public static void upgradeDatabase() throws CentralRepoException { - if (!CentralRepository.isEnabled()) { - EamDbSettingsDialog dialog = new EamDbSettingsDialog(); - dialog. - promptUserForSetup(); - } - - CentralRepository db = null; - CoordinationService.Lock lock = null; - - //get connection - try { - try { - db = CentralRepository.getInstance(); - } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); - throw new CentralRepoException("Error updating central repository, unable to make connection", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } - //get lock necessary for upgrade - if (db != null) { - try { - // This may return null if locking isn't supported, which is fine. It will - // throw an exception if locking is supported but we can't get the lock - // (meaning the database is in use by another user) - lock = db.getExclusiveMultiUserDbLock(); - //perform upgrade - } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); - throw new CentralRepoException("Error updating central repository, unable to acquire exclusive lock", Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } - - try { - db.upgradeSchema(); - } catch (CentralRepoException ex) { - LOGGER.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (IncompatibleCentralRepoException ex) { - LOGGER.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } finally { - if (lock != null) { - try { - lock.release(); - } catch (CoordinationServiceException ex) { - LOGGER.log(Level.SEVERE, "Error releasing database lock", ex); - } - } - } - } else { - throw new CentralRepoException("Unable to connect to database", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message()); - } - } catch (CentralRepoException ex) { - // Disable the central repo and clear the current settings. - try { - if (null != CentralRepository.getInstance()) { - CentralRepository.getInstance().shutdownConnections(); - } - } catch (CentralRepoException ex2) { - LOGGER.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); - } - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); - CentralRepoPlatforms.saveSelectedPlatform(); - throw ex; - } - } /** * Get the default organization name diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java similarity index 75% rename from Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java index f936e6af55..d7a13b6041 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/DatabaseTestResult.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java @@ -3,9 +3,9 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package org.sleuthkit.autopsy.centralrepository.optionspanel; +package org.sleuthkit.autopsy.centralrepository.datamodel; -enum DatabaseTestResult { +public enum DatabaseTestResult { UNTESTED, CONNECTION_FAILED, SCHEMA_INVALID, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 272a9047bb..73ab88d87c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -23,6 +23,7 @@ import org.openide.modules.ModuleInstall; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.core.RuntimeProperties; @@ -59,7 +60,7 @@ public class Installer extends ModuleInstall { // Perform the database upgrade and inform the user if it fails try { - CentralRepoDbUtil.upgradeDatabase(); + CentralRepoDbManager.upgradeDatabase(); } catch (CentralRepoException ex) { if (RuntimeProperties.runningWithGUI()) { WindowManager.getDefault().invokeWhenUIReady(() -> { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 4bd17b561e..c6518d4b2e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -35,8 +35,10 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; @@ -45,7 +47,7 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatf import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.centralrepository.optionspanel.DatabaseTestResult; +import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; /** * Configuration dialog for Central Repository database settings. @@ -58,10 +60,45 @@ public class EamDbSettingsDialog extends JDialog { private static final long serialVersionUID = 1L; private final Collection textBoxes; private final TextBoxChangedListener textBoxChangedListener; + private final CentralRepoDbManager manager = new CentralRepoDbManager(); + /** + * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) + * @return whether or not the ultimate status after prompts is okay to continue + */ + @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", + "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", + "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", + "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again."}) + private boolean promptTestStatusWarnings() { + if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) { + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), + JOptionPane.WARNING_MESSAGE); + } else if (manager.getStatus() == DatabaseTestResult.SCHEMA_INVALID) { + // There's an existing database or file, but it's not in our format. + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), + JOptionPane.WARNING_MESSAGE); + } else if (manager.getStatus() == DatabaseTestResult.DB_DOES_NOT_EXIST) { + //database doesn't exist do you want to create + boolean createDb = (!warnDoesNotExist || + JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), + JOptionPane.YES_NO_OPTION)); + + if (createDb) + manager.createDb(); + } - + return (manager.getStatus() == DatabaseTestResult.TESTEDOK); + } /** @@ -98,7 +135,7 @@ public class EamDbSettingsDialog extends JDialog { return "Directories and Central Repository databases"; } }); - cbDatabaseType.setSelectedItem(selectedPlatform); + cbDatabaseType.setSelectedItem(manager.getSelectedPlatform()); customizeComponents(); valid(); display(); @@ -351,7 +388,7 @@ public class EamDbSettingsDialog extends JDialog { private void customizeComponents() { setTextPrompts(); setTextBoxListeners(); - switch (selectedPlatform) { + switch (manager.getSelectedPlatform()) { case SQLITE: testingStatus = DatabaseTestResult.UNTESTED; updatePostgresFields(false); @@ -396,15 +433,15 @@ public class EamDbSettingsDialog extends JDialog { private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - testDbSettings(); + manager.testStatus(); - boolean testedOk = promptTestStatusWarnings(true); + boolean testedOk = promptTestStatusWarnings(); if (!testedOk) { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return; } - saveNewCentralRepo(); + manager.saveNewCentralRepo(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); dispose(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index ebd85ba527..ab0ea0401f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -31,6 +31,7 @@ import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.events.AutopsyEvent; @@ -86,7 +87,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { - CentralRepoDbUtil.upgradeDatabase(); + CentralRepoDbManager.upgradeDatabase(); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } catch (CentralRepoException ex) { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); From 5419db1deae1c55c910be02ababd9082ac86c441 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Fri, 14 Feb 2020 12:32:09 -0500 Subject: [PATCH 10/36] working through refactoring of classes --- .../datamodel/CentralRepoDbManager.java | 187 +++++++-------- .../optionspanel/EamDbSettingsDialog.java | 220 +++++++++--------- .../netbeans/core/startup/Bundle.properties | 4 +- .../core/windows/view/ui/Bundle.properties | 6 +- 4 files changed, 188 insertions(+), 229 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 9a50b7f209..5df9b445b9 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -24,6 +24,10 @@ public class CentralRepoDbManager { private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); + public static String getDefaultSqliteDbName() { + return CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT; + } + /** * Upgrade the current Central Reposity schema to the newest version. If the * upgrade fails, the Central Repository will be disabled and the current @@ -32,8 +36,9 @@ public class CentralRepoDbManager { @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) public static void upgradeDatabase() throws CentralRepoException { if (!CentralRepository.isEnabled()) { - EamDbSettingsDialog dialog = new EamDbSettingsDialog(); - dialog.promptUserForSetup(); + // TODO +// EamDbSettingsDialog dialog = new EamDbSettingsDialog(); +// dialog.promptUserForSetup(); } CentralRepository db = null; CoordinationService.Lock lock = null; @@ -42,7 +47,7 @@ public class CentralRepoDbManager { try { db = CentralRepository.getInstance(); } catch (CentralRepoException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); + logger.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); throw new CentralRepoException("Error updating central repository, unable to make connection", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } //get lock necessary for upgrade @@ -54,26 +59,26 @@ public class CentralRepoDbManager { lock = db.getExclusiveMultiUserDbLock(); //perform upgrade } catch (CentralRepoException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); + logger.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); throw new CentralRepoException("Error updating central repository, unable to acquire exclusive lock", Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } try { db.upgradeSchema(); } catch (CentralRepoException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + logger.log(Level.SEVERE, "Error updating central repository", ex); throw new CentralRepoException("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } catch (SQLException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + logger.log(Level.SEVERE, "Error updating central repository", ex); throw new CentralRepoException("Error updating central repository", Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } catch (IncompatibleCentralRepoException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error updating central repository", ex); + logger.log(Level.SEVERE, "Error updating central repository", ex); throw new CentralRepoException("Error updating central repository", ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } finally { if (lock != null) { try { lock.release(); } catch (CoordinationService.CoordinationServiceException ex) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error releasing database lock", ex); + logger.log(Level.SEVERE, "Error releasing database lock", ex); } } } @@ -87,7 +92,7 @@ public class CentralRepoDbManager { CentralRepository.getInstance().shutdownConnections(); } } catch (CentralRepoException ex2) { - CentralRepoDbUtil.LOGGER.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); + logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); } CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); CentralRepoPlatforms.saveSelectedPlatform(); @@ -115,62 +120,76 @@ public class CentralRepoDbManager { selectedPlatform = CentralRepoPlatforms.POSTGRESQL; } } - + public PostgresCentralRepoSettings getDbSettingsPostgres() { + return dbSettingsPostgres; + } + public SqliteCentralRepoSettings getDbSettingsSqlite() { + return dbSettingsSqlite; + } - - - - - @NbBundle.Messages({"EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database", - "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", - "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again."}) - public boolean createDb() { - boolean result = false; + public boolean createDb() throws CentralRepoException { boolean dbCreated = true; switch (selectedPlatform) { case POSTGRESQL: + // if postgres database does not exist, attempt to create it if (!dbSettingsPostgres.verifyDatabaseExists()) { dbCreated = dbSettingsPostgres.createDatabase(); } - if (dbCreated) { - result = dbSettingsPostgres.initializeDatabaseSchema() - && dbSettingsPostgres.insertDefaultDatabaseContent(); + + // if the database still isn't created, we have a problem + if (!dbCreated) { + logger.severe("Unable to create Postgres database for Central Repository at " + + dbSettingsPostgres.getHost() + ":" + dbSettingsPostgres.getPort() + " with db name: " + + dbSettingsPostgres.getDbName() + " and username: " + dbSettingsPostgres.getUserName()); + + throw new CentralRepoException("Unable to create Postgres database for Central Repository."); } + + + boolean result = dbSettingsPostgres.initializeDatabaseSchema() + && dbSettingsPostgres.insertDefaultDatabaseContent(); + + // if unable to initialize the schema, there's a problem as well if (!result) { // Remove the incomplete database if (dbCreated) { dbSettingsPostgres.deleteDatabase(); } - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(), - Bundle.EamDbSettingsDialog_okButton_createDbError_title(), - JOptionPane.WARNING_MESSAGE); - logger.severe("Unable to initialize database schema or insert contents into central repository."); - return false; + String schemaError = "Unable to initialize database schema or insert contents into central repository."; + logger.severe(schemaError); + throw new CentralRepoException(schemaError); } + break; case SQLITE: + + // if sqlite db does not exist, try to creat it if (!dbSettingsSqlite.dbDirectoryExists()) { dbCreated = dbSettingsSqlite.createDbDirectory(); } - if (dbCreated) { - result = dbSettingsSqlite.initializeDatabaseSchema() - && dbSettingsSqlite.insertDefaultDatabaseContent(); + + // if the database still isn't created, we have a problem + if (!dbCreated) { + logger.severe("Unable to create Sqlite database for Central Repository at " + + dbSettingsSqlite.getDbDirectory()); + + throw new CentralRepoException("Unable to create SQLite database for Central Repository."); } + + result = dbSettingsSqlite.initializeDatabaseSchema() + && dbSettingsSqlite.insertDefaultDatabaseContent(); + if (!result) { if (dbCreated) { dbSettingsSqlite.deleteDatabase(); } - - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(), - Bundle.EamDbSettingsDialog_okButton_createDbError_title(), - JOptionPane.WARNING_MESSAGE); - logger.severe("Unable to initialize database schema or insert contents into central repository."); - return false; + + String schemaError = "Unable to initialize database schema or insert contents into central repository."; + logger.severe(schemaError); + throw new CentralRepoException(schemaError); } break; } @@ -182,10 +201,8 @@ public class CentralRepoDbManager { /** * saves a new central repository based on current settings */ - @NbBundle.Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.", - "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", - "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) - private void saveNewCentralRepo() { + @NbBundle.Messages({"CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database."}) + public void saveNewCentralRepo() throws CentralRepoException { /** * We have to shutdown the previous platform's connection pool first; * assuming it wasn't DISABLED. This will close any existing idle @@ -202,12 +219,7 @@ public class CentralRepoDbManager { } } catch (CentralRepoException ex) { logger.log(Level.SEVERE, "Failed to close database connections in previously selected platform.", ex); // NON-NLS - SwingUtilities.invokeLater(() -> { - JOptionPane.showMessageDialog(this, - Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), - Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), - JOptionPane.WARNING_MESSAGE); - }); + throw ex; } // Even if we fail to close the existing connections, make sure that we @@ -226,8 +238,7 @@ public class CentralRepoDbManager { CentralRepository.getInstance().updateSettings(); configurationChanged = true; } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS return; } @@ -241,8 +252,7 @@ public class CentralRepoDbManager { CentralRepository.getInstance().updateSettings(); configurationChanged = true; } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.EamDbSettingsDialog_okButton_connectionErrorMsg_text(), ex); //NON-NLS - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS return; } break; @@ -252,30 +262,22 @@ public class CentralRepoDbManager { } public DatabaseTestResult getStatus() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return testingStatus; } public CentralRepoPlatforms getSelectedPlatform() { return selectedPlatform; } - - - static class DatabaseSettingsValidResult { - private final String errorMessage; - private final boolean success; - public DatabaseSettingsValidResult(String errorMessage, boolean success) { - this.errorMessage = errorMessage; - this.success = success; - } + public void clearStatus() { + testingStatus = DatabaseTestResult.UNTESTED; + } - public String getErrorMessage() { - return errorMessage; - } - public boolean isSuccess() { - return success; - } + + public void setSelectedPlatform(CentralRepoPlatforms newSelected) { + selectedPlatform = newSelected; + testingStatus = DatabaseTestResult.UNTESTED; } @@ -284,66 +286,33 @@ public class CentralRepoDbManager { * * @return True or false. */ - private DatabaseSettingsValidResult databaseSettingsAreValid( - String tbDbHostname, Integer tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) { + public boolean testDatabaseSettingsAreValid ( + String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { boolean result = true; StringBuilder guidanceText = new StringBuilder(); switch (selectedPlatform) { case POSTGRESQL: - try { dbSettingsPostgres.setHost(tbDbHostname); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { - dbSettingsPostgres.setPort(tbDbPort); - } catch (NumberFormatException | CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { + dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { dbSettingsPostgres.setUserName(tbDbUsername); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { dbSettingsPostgres.setPassword(jpDbPassword); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } break; case SQLITE: - try { File databasePath = new File(tfDatabasePath); - dbSettingsSqlite.setDbName(CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT); + dbSettingsSqlite.setDbName(getDefaultSqliteDbName()); dbSettingsSqlite.setDbDirectory(databasePath.getPath()); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } break; + default: + throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedPlatform); } - return new DatabaseSettingsValidResult(guidanceText.toString(), result); + return result; } - - private DatabaseTestResult testDbSettings() { + public DatabaseTestResult testStatus() { switch (selectedPlatform) { case POSTGRESQL: if (dbSettingsPostgres.verifyConnection()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index c6518d4b2e..51659aa21f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -43,10 +43,6 @@ import org.sleuthkit.autopsy.corecomponents.TextPrompt; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; -import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms.SQLITE; -import org.sleuthkit.autopsy.centralrepository.datamodel.PostgresCentralRepoSettings; -import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; /** @@ -63,44 +59,6 @@ public class EamDbSettingsDialog extends JDialog { private final CentralRepoDbManager manager = new CentralRepoDbManager(); - /** - * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) - * @return whether or not the ultimate status after prompts is okay to continue - */ - @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", - "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", - "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", - "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", - "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again."}) - private boolean promptTestStatusWarnings() { - if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) { - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), - Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), - JOptionPane.WARNING_MESSAGE); - } else if (manager.getStatus() == DatabaseTestResult.SCHEMA_INVALID) { - // There's an existing database or file, but it's not in our format. - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), - Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), - JOptionPane.WARNING_MESSAGE); - } else if (manager.getStatus() == DatabaseTestResult.DB_DOES_NOT_EXIST) { - //database doesn't exist do you want to create - boolean createDb = (!warnDoesNotExist || - JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), - Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), - JOptionPane.YES_NO_OPTION)); - - if (createDb) - manager.createDb(); - } - - return (manager.getStatus() == DatabaseTestResult.TESTEDOK); - } - - /** * Creates new form EamDbSettingsDialog */ @@ -108,7 +66,6 @@ public class EamDbSettingsDialog extends JDialog { "EamDbSettingsDialog.lbSingleUserSqLite.text=SQLite should only be used by one examiner at a time.", "EamDbSettingsDialog.lbDatabaseType.text=Database Type :", "EamDbSettingsDialog.fcDatabasePath.title=Select location for central_repository.db"}) - public EamDbSettingsDialog() { super((JFrame) WindowManager.getDefault().getMainWindow(), Bundle.EamDbSettingsDialog_title_text(), @@ -127,7 +84,7 @@ public class EamDbSettingsDialog extends JDialog { if (pathname.isDirectory()) { return true; } - return pathname.getName().toLowerCase().equals((CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT).toLowerCase()); + return pathname.getName().equalsIgnoreCase(CentralRepoDbManager.getDefaultSqliteDbName()); } @Override @@ -141,6 +98,69 @@ public class EamDbSettingsDialog extends JDialog { display(); } + + + + /** + * prompts user based on testing status (i.e. failure to connect, invalid schema, db does not exist, etc.) + * @return whether or not the ultimate status after prompts is okay to continue + */ + @NbBundle.Messages({"EamDbSettingsDialog.okButton.corruptDatabaseExists.title=Error Loading Database", + "EamDbSettingsDialog.okButton.corruptDatabaseExists.message=Database exists but is not the right format. Manually delete it or choose a different path (if applicable).", + "EamDbSettingsDialog.okButton.createDbDialog.title=Database Does Not Exist", + "EamDbSettingsDialog.okButton.createDbDialog.message=Database does not exist, would you like to create it?", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.title=Database Connection Failed", + "EamDbSettingsDialog.okButton.databaseConnectionFailed.message=Unable to connect to database please check your settings and try again.", + "EamDbSettingsDialog.okButton.createSQLiteDbError.message=Unable to create SQLite Database, please ensure location exists and you have write permissions and try again.", + "EamDbSettingsDialog.okButton.createPostgresDbError.message=Unable to create Postgres Database, please ensure address, port, and login credentials are correct for Postgres server and try again.", + "EamDbSettingsDialog.okButton.createDbError.title=Unable to Create Database"}) + private boolean promptTestStatusWarnings() { + if (manager.getStatus() == DatabaseTestResult.CONNECTION_FAILED) { + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_message(), + Bundle.EamDbSettingsDialog_okButton_databaseConnectionFailed_title(), + JOptionPane.WARNING_MESSAGE); + } else if (manager.getStatus() == DatabaseTestResult.SCHEMA_INVALID) { + // There's an existing database or file, but it's not in our format. + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_message(), + Bundle.EamDbSettingsDialog_okButton_corruptDatabaseExists_title(), + JOptionPane.WARNING_MESSAGE); + } else if (manager.getStatus() == DatabaseTestResult.DB_DOES_NOT_EXIST) { + //database doesn't exist. do you want to create? + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_message(), + Bundle.EamDbSettingsDialog_okButton_createDbDialog_title(), + JOptionPane.YES_NO_OPTION)) { + try { + manager.createDb(); + } + catch (CentralRepoException e) { + // in the event that there is a failure to connect, notify user with corresponding message + String errorMessage; + switch (manager.getSelectedPlatform()) { + case POSTGRESQL: + errorMessage = Bundle.EamDbSettingsDialog_okButton_createPostgresDbError_message(); + break; + case SQLITE: + errorMessage = Bundle.EamDbSettingsDialog_okButton_createSQLiteDbError_message(); + break; + default: + errorMessage = ""; + break; + } + + JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), + errorMessage, + Bundle.EamDbSettingsDialog_okButton_createDbError_title(), + JOptionPane.WARNING_MESSAGE); + } + } + } + + return (manager.getStatus() == DatabaseTestResult.TESTEDOK); + } + /** * This method is called from within the constructor to initialize the form. @@ -388,21 +408,20 @@ public class EamDbSettingsDialog extends JDialog { private void customizeComponents() { setTextPrompts(); setTextBoxListeners(); + manager.clearStatus(); switch (manager.getSelectedPlatform()) { case SQLITE: - testingStatus = DatabaseTestResult.UNTESTED; updatePostgresFields(false); updateSqliteFields(true); break; default: POSTGRESQL: - testingStatus = DatabaseTestResult.UNTESTED; updatePostgresFields(true); updateSqliteFields(false); break; } - displayDatabaseSettings(selectedPlatform.equals(CentralRepoPlatforms.POSTGRESQL)); + displayDatabaseSettings(CentralRepoPlatforms.POSTGRESQL.equals(manager.getSelectedPlatform())); } private void display() { @@ -412,7 +431,7 @@ public class EamDbSettingsDialog extends JDialog { @Messages({"EamDbSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."}) private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed - fcDatabasePath.setSelectedFile(new File(dbSettingsSqlite.getDbDirectory())); + fcDatabasePath.setSelectedFile(new File(manager.getDbSettingsSqlite().getDbDirectory())); if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { File databaseFile = fcDatabasePath.getSelectedFile(); if (databaseFile.isFile()) { @@ -428,9 +447,9 @@ public class EamDbSettingsDialog extends JDialog { } }//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed - - - + @NbBundle.Messages({"EamDbSettingsDialog.okButton.errorTitle.text=Restart Required.", + "EamDbSettingsDialog.okButton.errorMsg.text=Please restart Autopsy to begin using the new database platform.", + "EamDbSettingsDialog.okButton.connectionErrorMsg.text=Failed to connect to central repository database."}) private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); manager.testStatus(); @@ -441,7 +460,18 @@ public class EamDbSettingsDialog extends JDialog { return; } - manager.saveNewCentralRepo(); + try{ + manager.saveNewCentralRepo(); + } + catch (CentralRepoException e) { + SwingUtilities.invokeLater(() -> { + JOptionPane.showMessageDialog(this, + Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), + EamDbSettingsDialog_okButton_errorTitle_text(), + JOptionPane.WARNING_MESSAGE); + }); + } + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); dispose(); @@ -455,12 +485,12 @@ public class EamDbSettingsDialog extends JDialog { private void cbDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbDatabaseTypeActionPerformed - selectedPlatform = (CentralRepoPlatforms) cbDatabaseType.getSelectedItem(); + manager.setSelectedPlatform((CentralRepoPlatforms) cbDatabaseType.getSelectedItem()); customizeComponents(); }//GEN-LAST:event_cbDatabaseTypeActionPerformed private void updateFullDbPath() { - dataBaseFileTextArea.setText(tfDatabasePath.getText() + File.separator + CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT); + dataBaseFileTextArea.setText(tfDatabasePath.getText() + File.separator + manager.getDefaultSqliteDbName()); dataBaseFileTextArea.setCaretPosition(dataBaseFileTextArea.getText().length()); } @@ -498,13 +528,13 @@ public class EamDbSettingsDialog extends JDialog { } private void updatePostgresFields(boolean enabled) { - tbDbHostname.setText(enabled ? dbSettingsPostgres.getHost() : ""); + tbDbHostname.setText(enabled ? manager.getDbSettingsPostgres().getHost() : ""); tbDbHostname.setEnabled(enabled); - tbDbPort.setText(enabled ? Integer.toString(dbSettingsPostgres.getPort()) : ""); + tbDbPort.setText(enabled ? Integer.toString(manager.getDbSettingsPostgres().getPort()) : ""); tbDbPort.setEnabled(enabled); - tbDbUsername.setText(enabled ? dbSettingsPostgres.getUserName() : ""); + tbDbUsername.setText(enabled ? manager.getDbSettingsPostgres().getUserName() : ""); tbDbUsername.setEnabled(enabled); - jpDbPassword.setText(enabled ? dbSettingsPostgres.getPassword() : ""); + jpDbPassword.setText(enabled ? manager.getDbSettingsPostgres().getPassword() : ""); jpDbPassword.setEnabled(enabled); } @@ -515,7 +545,7 @@ public class EamDbSettingsDialog extends JDialog { * @param enabled */ private void updateSqliteFields(boolean enabled) { - tfDatabasePath.setText(enabled ? dbSettingsSqlite.getDbDirectory() : ""); + tfDatabasePath.setText(enabled ? manager.getDbSettingsSqlite().getDbDirectory() : ""); tfDatabasePath.setEnabled(enabled); bnDatabasePathFileOpen.setEnabled(enabled); } @@ -568,7 +598,7 @@ public class EamDbSettingsDialog extends JDialog { @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."}) private boolean databaseFieldsArePopulated() { boolean result = true; - switch (selectedPlatform) { + switch (manager.getSelectedPlatform()) { case POSTGRESQL: result = !tbDbHostname.getText().trim().isEmpty() && !tbDbPort.getText().trim().isEmpty() @@ -634,59 +664,19 @@ public class EamDbSettingsDialog extends JDialog { * @return True or false. */ private boolean databaseSettingsAreValid() { - boolean result = true; - StringBuilder guidanceText = new StringBuilder(); - - switch (selectedPlatform) { - case POSTGRESQL: - try { - dbSettingsPostgres.setHost(tbDbHostname.getText().trim()); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { - dbSettingsPostgres.setPort(Integer.valueOf(tbDbPort.getText().trim())); - } catch (NumberFormatException | CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { - dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { - dbSettingsPostgres.setUserName(tbDbUsername.getText().trim()); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - - try { - dbSettingsPostgres.setPassword(new String(jpDbPassword.getPassword())); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - break; - case SQLITE: - try { - File databasePath = new File(tfDatabasePath.getText()); - dbSettingsSqlite.setDbName(CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT); - dbSettingsSqlite.setDbDirectory(databasePath.getPath()); - } catch (CentralRepoException ex) { - guidanceText.append(ex.getMessage()); - result = false; - } - break; + try { + manager.testDatabaseSettingsAreValid( + tbDbHostname.getText().trim(), + tbDbPort.getText().trim(), + tbDbUsername.getText().trim(), + tfDatabasePath.getText().trim(), + new String(jpDbPassword.getPassword())); } - - return result; + catch (Exception e) { + return false; + } + + return true; } /** @@ -698,7 +688,7 @@ public class EamDbSettingsDialog extends JDialog { @Override public void changedUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - testingStatus = DatabaseTestResult.UNTESTED; + manager.clearStatus(); updateFullDbPath(); valid(); } @@ -706,7 +696,7 @@ public class EamDbSettingsDialog extends JDialog { @Override public void insertUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - testingStatus = DatabaseTestResult.UNTESTED; + manager.clearStatus(); updateFullDbPath(); valid(); } @@ -714,7 +704,7 @@ public class EamDbSettingsDialog extends JDialog { @Override public void removeUpdate(DocumentEvent e) { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); - testingStatus = DatabaseTestResult.UNTESTED; + manager.clearStatus(); updateFullDbPath(); valid(); diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index b20ccf5912..4f645919d3 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Tue, 12 Nov 2019 17:21:46 -0500 +#Fri, 14 Feb 2020 12:16:52 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.13.0 +currentVersion=Autopsy 4.14.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 998d3f715c..627464541f 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Tue, 12 Nov 2019 17:21:46 -0500 -CTL_MainWindow_Title=Autopsy 4.13.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 +#Fri, 14 Feb 2020 12:16:52 -0500 +CTL_MainWindow_Title=Autopsy 4.14.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 From 57a6fdac6975c42add7ede8973d027b32887dac1 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Tue, 18 Feb 2020 09:41:35 -0500 Subject: [PATCH 11/36] Updated to based on jira and review comments --- .../autopsy/geolocation/datamodel/Route.java | 11 ++-- .../autopsy/geolocation/datamodel/Track.java | 62 ++++--------------- .../modules/drones/Bundle.properties-MERGED | 4 +- .../autopsy/modules/drones/DATExtractor.java | 14 +++-- .../android/googlemaplocation.py | 9 ++- 5 files changed, 37 insertions(+), 63 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index 31372ea4fe..fa8dacf5d2 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -20,13 +20,14 @@ package org.sleuthkit.autopsy.geolocation.datamodel; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.GeoWaypoints; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints.GeoWaypoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints; /** * A Route represents a TSK_GPS_ROUTE artifact which has a start and end point @@ -117,9 +118,11 @@ public class Route extends GeoPath { if (attribute != null) { String value = attribute.getValueString(); - List waypointList = GeoWaypoints.deserializePoints(value); + GeoWaypoints waypoints = GeoWaypoints.deserialize(value); - for (GeoWaypoint waypoint : waypointList) { + Iterator waypointIter = waypoints.iterator(); + while(waypointIter.hasNext()) { + GeoWaypoint waypoint = waypointIter.next(); addToPath(new Waypoint(artifact, label, null, waypoint.getLatitude(), waypoint.getLongitude(), waypoint.getAltitude(), null, attributeMap, this)); } } else { diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index cb0dd95303..33294d0d18 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -21,13 +21,14 @@ package org.sleuthkit.autopsy.geolocation.datamodel; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint.GeoTrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.GeoTrackPoint; /** * A GPS track with which wraps the TSK_GPS_TRACK artifact. @@ -59,11 +60,11 @@ public final class Track extends GeoPath{ private Track(BlackboardArtifact artifact, Map attributeMap) throws GeoLocationDataException { super(artifact, getTrackName(attributeMap)); - List points = getPointsList(attributeMap); + GeoTrackPoints points = getPointsList(attributeMap); buildPath(points); - startTimestamp = findStartTime(points); - endTimeStamp = findEndTime(points); + startTimestamp = points.getStartTime(); + endTimeStamp = points.getEndTime(); } /** @@ -111,8 +112,10 @@ public final class Track extends GeoPath{ "# {0} - track name", "GEOTrack_point_label_header=Trackpoint for track: {0}" }) - private void buildPath(List points) throws GeoLocationDataException { - for (GeoTrackPoint point : points) { + private void buildPath(GeoTrackPoints points) throws GeoLocationDataException { + Iterator pointIter = points.iterator(); + while(pointIter.hasNext()) { + GeoTrackPoint point = pointIter.next(); addToPath(new TrackWaypoint(Bundle.GEOTrack_point_label_header(getLabel()), point)); } } @@ -125,52 +128,13 @@ public final class Track extends GeoPath{ * * @return GeoTrackPoint list empty list if the attribute was not found. */ - private List getPointsList(Map attributeMap) { + private GeoTrackPoints getPointsList(Map attributeMap) { BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); if (attribute != null) { String value = attribute.getValueString(); - return GeoTrackPoints.deserializePoints(value); + return GeoTrackPoints.deserialize(value); } - return new ArrayList<>(); - } - - /** - * Return the start time for the track. Assumes the points are in time - * order. - * - * @param points List of GeoTrackPoints. - * - * @return First non-null time stamp or null, if one was not found. - */ - private Long findStartTime(List points) { - if (points != null) { - for (GeoTrackPoint point : points) { - if (point.getTimeStamp() != null) { - return point.getTimeStamp(); - } - } - } - return null; - } - - /** - * Return the ends time for the track. Assumes the points are in time - * order. - * - * @param points List of GeoTrackPoints. - * - * @return First non-null time stamp or null, if one was not found. - */ - private Long findEndTime(List points) { - if (points != null) { - for (int index = points.size() - 1; index >= 0; index--) { - GeoTrackPoint point = points.get(index); - if (point.getTimeStamp() != null) { - return point.getTimeStamp(); - } - } - } return null; } @@ -234,12 +198,12 @@ public final class Track extends GeoPath{ value = point.getDistanceTraveled(); if (value != null) { - list.add(new Property(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_DISTANCE_TRAVELED.getDisplayName(), value.toString())); + list.add(new Property("", value.toString())); } value = point.getDistanceFromHP(); if (value != null) { - list.add(new Property(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_DISTANCE_FROM_HOME_POINT.getDisplayName(), value.toString())); + list.add(new Property("", value.toString())); } return list; diff --git a/Core/src/org/sleuthkit/autopsy/modules/drones/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/drones/Bundle.properties-MERGED index 23f2a02775..bf61ad9be0 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/drones/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/drones/Bundle.properties-MERGED @@ -1,6 +1,6 @@ DATExtractor_process_message=Processing DJI DAT file: %s DATFileExtractor_Extractor_Name=DAT File Extractor -DroneIngestModule_Description=Description -DroneIngestModule_Name=Drone +DroneIngestModule_Description=Analyzes files generated by drones. +DroneIngestModule_Name=Drone Analyzer # {0} - AbstractFileName DroneIngestModule_process_start=Started {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java index 256ee59509..68947be6fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java @@ -41,10 +41,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoint.GeoTrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPointList.GeoTrackPoint; import org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.Blackboard.BlackboardException; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPointList; /** * Extract drone position data from DJI Phantom drones. @@ -110,10 +111,10 @@ final class DATExtractor extends DroneExtractor { } // Process the csv file - List trackPoints = processCSVFile(context, DATFile, csvFilePath); + GeoTrackPointList trackPoints = processCSVFile(context, DATFile, csvFilePath); if (trackPoints != null && !trackPoints.isEmpty()) { - (new GeoArtifactsHelper(getSleuthkitCase(), getName(), DATFile)).addTrack(DATFile.getName(), trackPoints); + (new GeoArtifactsHelper(getSleuthkitCase(), getName(), "DatCon", DATFile)).addTrack(DATFile.getName(), trackPoints, null); } else { logger.log(Level.INFO, String.format("No trackpoints with valid longitude or latitude found in %s", DATFile.getName())); //NON-NLS } @@ -187,8 +188,8 @@ final class DATExtractor extends DroneExtractor { * * @throws DroneIngestException */ - private List processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException { - List trackPoints = new ArrayList<>(); + private GeoTrackPointList processCSVFile(IngestJobContext context, AbstractFile DATFile, String csvFilePath) throws DroneIngestException { + GeoTrackPointList trackPoints = new GeoTrackPointList(); try (BufferedReader reader = new BufferedReader(new FileReader(new File(csvFilePath)))) { // First read in the header line and process String line = reader.readLine(); @@ -202,7 +203,7 @@ final class DATExtractor extends DroneExtractor { String[] values = line.split(","); //NON-NLS GeoTrackPoint point = createTrackPoint(headerMap, values); if (point != null) { - trackPoints.add(point); + trackPoints.addPoint(point); } } @@ -258,6 +259,7 @@ final class DATExtractor extends DroneExtractor { return new GeoTrackPoint(latitude, longitude, getDoubleValue(columnLookup.get(HEADER_ALTITUDE), values), + null, getDoubleValue(columnLookup.get(HEADER_VELOCITY), values), getDoubleValue(columnLookup.get(HEADER_DISTANCE_FROM_HP), values), getDoubleValue(columnLookup.get(HEADER_DISTANCE_TRAVELED), values), diff --git a/InternalPythonModules/android/googlemaplocation.py b/InternalPythonModules/android/googlemaplocation.py index 17522c576c..330095c900 100644 --- a/InternalPythonModules/android/googlemaplocation.py +++ b/InternalPythonModules/android/googlemaplocation.py @@ -42,6 +42,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper +from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypointList import traceback import general @@ -87,7 +88,7 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): try: artifactHelper = GeoArtifactsHelper(self.current_case.getSleuthkitCase(), - general.MODULE_NAME, abstractFile) + general.MODULE_NAME, self.PROGRAM_NAME, abstractFile) Class.forName("org.sqlite.JDBC") # load JDBC driver connection = DriverManager.getConnection("jdbc:sqlite:" + databasePath) statement = connection.createStatement() @@ -113,8 +114,12 @@ class GoogleMapLocationAnalyzer(general.AndroidComponentAnalyzer): dest_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("dest_lng")) source_lat = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lat")) source_lng = GoogleMapLocationAnalyzer.convertGeo(resultSet.getString("source_lng")) + + waypointlist = GeoWaypointList() + waypointlist.addPoint(source_lat, source_lng, None, None) + waypointlist.addPoint(dest_lat, dest_lng, None, dest_address) - artifactHelper.addRoute(dest_title, time, dest_address, self.PROGRAM_NAME, self.CAT_DESTINATION, source_lat, source_lng, dest_lat, dest_lng) + artifactHelper.addRoute(dest_title, time, waypointlist, None) except SQLException as ex: # Unable to execute Google map locations SQL query against database. From 49bf930794cebf69f75033859e9aa54ec5811889 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Fri, 21 Feb 2020 10:16:04 -0500 Subject: [PATCH 12/36] finished refactoring --- .../datamodel/CentralRepoDbManager.java | 23 +++++++++---------- .../optionspanel/EamDbSettingsDialog.java | 12 +++++++++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 5df9b445b9..ab2fbfa4c3 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -129,6 +129,17 @@ public class CentralRepoDbManager { return dbSettingsSqlite; } + /** + * Returns if changes to the central repository configuration were + * successfully applied + * + * @return true if the database configuration was successfully changed false + * if it was not + */ + public boolean wasConfigurationChanged() { + return configurationChanged; + } + public boolean createDb() throws CentralRepoException { boolean dbCreated = true; switch (selectedPlatform) { @@ -348,16 +359,4 @@ public class CentralRepoDbManager { return testingStatus; } - - - /** - * Returns if changes to the central repository configuration were - * successfully applied - * - * @return true if the database configuration was successfully changed false - * if it was not - */ - boolean wasConfigurationChanged() { - return configurationChanged; - } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 51659aa21f..6614d90094 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -467,7 +467,7 @@ public class EamDbSettingsDialog extends JDialog { SwingUtilities.invokeLater(() -> { JOptionPane.showMessageDialog(this, Bundle.EamDbSettingsDialog_okButton_errorMsg_text(), - EamDbSettingsDialog_okButton_errorTitle_text(), + Bundle.EamDbSettingsDialog_okButton_errorTitle_text(), JOptionPane.WARNING_MESSAGE); }); } @@ -478,6 +478,16 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_bnOkActionPerformed + /** + * Returns if changes to the central repository configuration were + * successfully applied + * + * @return true if the database configuration was successfully changed false + * if it was not + */ + public boolean wasConfigurationChanged() { + return manager.wasConfigurationChanged(); + } private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed dispose(); From 851a3308ad5bb12945a484b48a641ee25cc20de7 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Fri, 21 Feb 2020 13:51:16 -0500 Subject: [PATCH 13/36] working through initial central repository enable --- .../datamodel/CentralRepoDbManager.java | 23 ++++++------- .../datamodel/SqliteCentralRepoSettings.java | 10 +++++- .../eventlisteners/Installer.java | 34 +++++++++++++++++-- .../optionspanel/EamDbSettingsDialog.java | 5 +-- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index ab2fbfa4c3..60a644f411 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -18,16 +18,11 @@ import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coreutils.Logger; -public class CentralRepoDbManager { - private static final String CENTRAL_REPO_DB_NAME = "central_repository"; - private static final String CENTRAL_REPO_SQLITE_EXT = ".db"; - +public class CentralRepoDbManager { private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); + + private static final String CENTRAL_REPO_DB_NAME = "central_repository"; - public static String getDefaultSqliteDbName() { - return CENTRAL_REPO_DB_NAME + CENTRAL_REPO_SQLITE_EXT; - } - /** * Upgrade the current Central Reposity schema to the newest version. If the * upgrade fails, the Central Repository will be disabled and the current @@ -36,10 +31,9 @@ public class CentralRepoDbManager { @NbBundle.Messages(value = {"EamDbUtil.centralRepoDisabled.message= The Central Repository has been disabled.", "EamDbUtil.centralRepoUpgradeFailed.message=Failed to upgrade Central Repository.", "EamDbUtil.centralRepoConnectionFailed.message=Unable to connect to Central Repository.", "EamDbUtil.exclusiveLockAquisitionFailure.message=Unable to acquire exclusive lock for Central Repository."}) public static void upgradeDatabase() throws CentralRepoException { if (!CentralRepository.isEnabled()) { - // TODO -// EamDbSettingsDialog dialog = new EamDbSettingsDialog(); -// dialog.promptUserForSetup(); + return; } + CentralRepository db = null; CoordinationService.Lock lock = null; //get connection @@ -129,6 +123,11 @@ public class CentralRepoDbManager { return dbSettingsSqlite; } + public void setupDefaultSqliteSettings() { + selectedPlatform = CentralRepoPlatforms.SQLITE; + dbSettingsSqlite.setupDefaultSettings(); + } + /** * Returns if changes to the central repository configuration were * successfully applied @@ -313,7 +312,7 @@ public class CentralRepoDbManager { break; case SQLITE: File databasePath = new File(tfDatabasePath); - dbSettingsSqlite.setDbName(getDefaultSqliteDbName()); + dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); dbSettingsSqlite.setDbDirectory(databasePath.getPath()); break; default: diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index 3b2a424c4a..b0ffee2ed2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -42,8 +42,8 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo */ public final class SqliteCentralRepoSettings { + public final static String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS private final static Logger LOGGER = Logger.getLogger(SqliteCentralRepoSettings.class.getName()); - private final static String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS private final static String DEFAULT_DBDIRECTORY = PlatformUtil.getUserDirectory() + File.separator + "central_repository"; // NON-NLS private final static String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS private final static String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS @@ -89,6 +89,14 @@ public final class SqliteCentralRepoSettings { this.bulkThreshold = RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD; } } + + /** + * sets database directory and name to defaults + */ + public void setupDefaultSettings() { + dbName = DEFAULT_DBNAME; + dbDirectory = DEFAULT_DBDIRECTORY; + } public void saveSettings() { createDbDirectory(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 73ab88d87c..d6f0df3687 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -28,6 +28,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.ModuleSettings; /** * Install event listeners during module initialization @@ -52,7 +53,14 @@ public class Installer extends ModuleInstall { super(); } - @NbBundle.Messages({"Installer.centralRepoUpgradeFailed.title=Central repository disabled"}) + @NbBundle.Messages({ + "Installer.centralRepoUpgradeFailed.title=Central repository disabled", + "Installer.initialCreateSqlite.title=Create Sqlite Central Repository?", + "Installer.initialCreateSqlite.message=The central repository allows a user to find matching artifacts both across cases " + + "and across data sources in the same case. Having data in the central repository is useful for file discovery. Would you " + + "like to create the default Central Repository now? If you choose not to at this time, this setting can be changed in the " + + "options panel." + }) @Override public void restored() { Case.addPropertyChangeListener(pcl); @@ -60,7 +68,29 @@ public class Installer extends ModuleInstall { // Perform the database upgrade and inform the user if it fails try { - CentralRepoDbManager.upgradeDatabase(); + String initialized = ModuleSettings.getConfigSetting("CentralRepository", "initialized"); + if (!Boolean.parseBoolean(initialized)) { + String dialogText = "

" + + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.message") + + "

"; + + boolean setupSqlite = !RuntimeProperties.runningWithGUI() || + JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + dialogText, + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"), + JOptionPane.YES_NO_OPTION); + + if (setupSqlite) { + CentralRepoDbManager manager = new CentralRepoDbManager(); + manager.setupDefaultSqliteSettings(); + manager.saveNewCentralRepo(); + } + + ModuleSettings.setConfigSetting("CentralRepository", "initialized", "true"); + } + else { + CentralRepoDbManager.upgradeDatabase(); + } } catch (CentralRepoException ex) { if (RuntimeProperties.runningWithGUI()) { WindowManager.getDefault().invokeWhenUIReady(() -> { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 6614d90094..c45d05bb68 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoPlatforms; import org.sleuthkit.autopsy.centralrepository.datamodel.DatabaseTestResult; +import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; /** * Configuration dialog for Central Repository database settings. @@ -84,7 +85,7 @@ public class EamDbSettingsDialog extends JDialog { if (pathname.isDirectory()) { return true; } - return pathname.getName().equalsIgnoreCase(CentralRepoDbManager.getDefaultSqliteDbName()); + return pathname.getName().equalsIgnoreCase(SqliteCentralRepoSettings.DEFAULT_DBNAME); } @Override @@ -500,7 +501,7 @@ public class EamDbSettingsDialog extends JDialog { }//GEN-LAST:event_cbDatabaseTypeActionPerformed private void updateFullDbPath() { - dataBaseFileTextArea.setText(tfDatabasePath.getText() + File.separator + manager.getDefaultSqliteDbName()); + dataBaseFileTextArea.setText(tfDatabasePath.getText() + File.separator + SqliteCentralRepoSettings.DEFAULT_DBNAME); dataBaseFileTextArea.setCaretPosition(dataBaseFileTextArea.getText().length()); } From 1b18e39dcfaa31b851799bf8441e4d6556c747c5 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Fri, 21 Feb 2020 16:08:26 -0500 Subject: [PATCH 14/36] created central repo on first load --- .../datamodel/CentralRepoDbManager.java | 3 + .../eventlisteners/Installer.java | 120 ++++++++++++------ 2 files changed, 85 insertions(+), 38 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 60a644f411..320887b74d 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -255,6 +255,9 @@ public class CentralRepoDbManager { break; case SQLITE: // save the new SQLite settings + logger.info(String.format("Attempting to set up sqlite database at path: %s with filename: %s", + dbSettingsSqlite.getDbDirectory(), dbSettingsSqlite.getDbName())); + dbSettingsSqlite.saveSettings(); // Load those newly saved settings into the sqlite db manager instance // in case we are still using the same instance. diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index d6f0df3687..22d2a88836 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -18,8 +18,12 @@ */ package org.sleuthkit.autopsy.centralrepository.eventlisteners; +import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; import org.openide.modules.ModuleInstall; +import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; @@ -55,55 +59,95 @@ public class Installer extends ModuleInstall { @NbBundle.Messages({ "Installer.centralRepoUpgradeFailed.title=Central repository disabled", - "Installer.initialCreateSqlite.title=Create Sqlite Central Repository?", - "Installer.initialCreateSqlite.message=The central repository allows a user to find matching artifacts both across cases " + - "and across data sources in the same case. Having data in the central repository is useful for file discovery. Would you " + - "like to create the default Central Repository now? If you choose not to at this time, this setting can be changed in the " + - "options panel." + "Installer.initialCreateSqlite.title=Enable Central Repository?", + "Installer.initialCreateSqlite.message=The Central Repository is not enabled. Would you like to enable it? " + + "It will store information about all hashes and identifiers that you process. You can use this to ignore previously " + + "seen files and make connections between cases." }) @Override public void restored() { Case.addPropertyChangeListener(pcl); ieListener.installListeners(); - // Perform the database upgrade and inform the user if it fails - try { - String initialized = ModuleSettings.getConfigSetting("CentralRepository", "initialized"); - if (!Boolean.parseBoolean(initialized)) { - String dialogText = "

" + - NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.message") + - "

"; - - boolean setupSqlite = !RuntimeProperties.runningWithGUI() || - JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), - dialogText, - NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"), - JOptionPane.YES_NO_OPTION); - - if (setupSqlite) { - CentralRepoDbManager manager = new CentralRepoDbManager(); - manager.setupDefaultSqliteSettings(); - manager.saveNewCentralRepo(); - } - - ModuleSettings.setConfigSetting("CentralRepository", "initialized", "true"); - } - else { - CentralRepoDbManager.upgradeDatabase(); - } - } catch (CentralRepoException ex) { + String initialized = ModuleSettings.getConfigSetting("CentralRepository", "initialized"); + + // if central repository hasn't been previously initialized, initialize it + if (!Boolean.parseBoolean(initialized)) { + // if running with a GUI, prompt the user if (RuntimeProperties.runningWithGUI()) { - WindowManager.getDefault().invokeWhenUIReady(() -> { - JOptionPane.showMessageDialog(null, - ex.getUserMessage(), - NbBundle.getMessage(this.getClass(), - "Installer.centralRepoUpgradeFailed.title"), - JOptionPane.ERROR_MESSAGE); - }); + try { + SwingUtilities.invokeAndWait(() -> { + try { + String dialogText = "

" + + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.message") + + "

"; + + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), + dialogText, + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.title"), + JOptionPane.YES_NO_OPTION)) { + + setupDefaultSqlite(); + } + } catch (CentralRepoException ex) { + LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); + + reportUpgradeError(ex); + } + }); + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, "There was an error while running the swing utility invoke later while creating the central repository database", ex); + } + } // if no GUI, just initialize + else { + try { + setupDefaultSqlite(); + } catch (CentralRepoException ex) { + LOGGER.log(Level.SEVERE, "There was an error while initializing the central repository database", ex); + + reportUpgradeError(ex); + } + } + + ModuleSettings.setConfigSetting("CentralRepository", "initialized", "true"); + } + + // now run regular module startup code + try { + CentralRepoDbManager.upgradeDatabase(); + } catch (CentralRepoException ex) { + LOGGER.log(Level.SEVERE, "There was an error while upgrading the central repository database", ex); + if (RuntimeProperties.runningWithGUI()) { + reportUpgradeError(ex); } } } + private void setupDefaultSqlite() throws CentralRepoException { + CentralRepoDbUtil.setUseCentralRepo(true); + CentralRepoDbManager manager = new CentralRepoDbManager(); + manager.setupDefaultSqliteSettings(); + manager.createDb(); + manager.saveNewCentralRepo(); + } + + private void reportUpgradeError(CentralRepoException ex) { + try { + SwingUtilities.invokeAndWait(() -> { + JOptionPane.showMessageDialog(null, + ex.getUserMessage(), + NbBundle.getMessage(this.getClass(), + "Installer.centralRepoUpgradeFailed.title"), + JOptionPane.ERROR_MESSAGE); + }); + } catch (Exception e) { + LOGGER.warning("There was an error while running the swing utility invoke later while displaying an error " + + "for creating the central repository database: " + + e.getMessage() + System.lineSeparator() + e.getStackTrace()); + } + + } + @Override public boolean closing() { //platform about to close From 22131f4491dde9a03543d7392550ba83c12d62ad Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 07:54:11 -0500 Subject: [PATCH 15/36] updated formatting in central repo initialization message --- .../eventlisteners/Installer.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 22d2a88836..8f96140837 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -60,9 +60,9 @@ public class Installer extends ModuleInstall { @NbBundle.Messages({ "Installer.centralRepoUpgradeFailed.title=Central repository disabled", "Installer.initialCreateSqlite.title=Enable Central Repository?", - "Installer.initialCreateSqlite.message=The Central Repository is not enabled. Would you like to enable it? " + - "It will store information about all hashes and identifiers that you process. You can use this to ignore previously " + - "seen files and make connections between cases." + "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to?", + "Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. " + + "You can use this to ignore previously seen files and make connections between cases." }) @Override public void restored() { @@ -78,9 +78,13 @@ public class Installer extends ModuleInstall { try { SwingUtilities.invokeAndWait(() -> { try { - String dialogText = "

" - + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.message") - + "

"; + String dialogText = + "" + + "
" + + "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageHeader") + "

" + + "

" + NbBundle.getMessage(this.getClass(), "Installer.initialCreateSqlite.messageDesc") + "

" + + "
" + + ""; if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(WindowManager.getDefault().getMainWindow(), dialogText, From fcf85ee0df4e856794a4946e7d9b914aaa5b4726 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 09:19:45 -0500 Subject: [PATCH 16/36] fix for exception on method --- .../centralrepository/datamodel/CentralRepoDbManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 33a69fef97..d7061719f2 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -148,7 +148,7 @@ public class CentralRepoDbManager { } } - private RdbmsCentralRepoFactory getDbFactory() { + private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { switch (selectedPlatform) { case POSTGRESQL: return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsPostgres); case SQLITE: return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsSqlite); From bf4c252fed6792e0197d5eae9a678405328913e3 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 10:03:52 -0500 Subject: [PATCH 17/36] central repo code cleanup --- .../datamodel/CentralRepoDbManager.java | 136 ++++++++---------- ...ttings.java => CentralRepoDbSettings.java} | 4 +- .../PostgresCentralRepoSettings.java | 2 +- .../datamodel/SqliteCentralRepoSettings.java | 2 +- .../optionspanel/EamDbSettingsDialog.java | 5 +- 5 files changed, 71 insertions(+), 78 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CentralRepoSettings.java => CentralRepoDbSettings.java} (92%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index d7061719f2..7bcd05af12 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -17,10 +17,10 @@ import org.sleuthkit.autopsy.centralrepository.optionspanel.EamDbSettingsDialog; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coreutils.Logger; +public class CentralRepoDbManager { -public class CentralRepoDbManager { private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); - + private static final String CENTRAL_REPO_DB_NAME = "central_repository"; /** @@ -33,7 +33,7 @@ public class CentralRepoDbManager { if (!CentralRepository.isEnabled()) { return; } - + CentralRepository db = null; CoordinationService.Lock lock = null; //get connection @@ -93,19 +93,15 @@ public class CentralRepoDbManager { throw ex; } } - - - - + private DatabaseTestResult testingStatus; private CentralRepoPlatforms selectedPlatform; private PostgresCentralRepoSettings dbSettingsPostgres; private SqliteCentralRepoSettings dbSettingsSqlite; - + private boolean configurationChanged = false; - - + public CentralRepoDbManager() { dbSettingsPostgres = new PostgresCentralRepoSettings(); dbSettingsSqlite = new SqliteCentralRepoSettings(); @@ -122,12 +118,12 @@ public class CentralRepoDbManager { public SqliteCentralRepoSettings getDbSettingsSqlite() { return dbSettingsSqlite; } - + public void setupDefaultSqliteSettings() { selectedPlatform = CentralRepoPlatforms.SQLITE; dbSettingsSqlite.setupDefaultSettings(); } - + /** * Returns if changes to the central repository configuration were * successfully applied @@ -139,20 +135,43 @@ public class CentralRepoDbManager { return configurationChanged; } - - private CentralRepoSettings getSelectedSettings() throws CentralRepoException { + private CentralRepoDbSettings getSelectedSettings() throws CentralRepoException { switch (selectedPlatform) { - case POSTGRESQL: return dbSettingsPostgres; - case SQLITE: return dbSettingsSqlite; - default: throw new CentralRepoException("Unknown database type: " + selectedPlatform); + case POSTGRESQL: + return dbSettingsPostgres; + case SQLITE: + return dbSettingsSqlite; + case DISABLED: + return null; + default: + throw new CentralRepoException("Unknown database type: " + selectedPlatform); } } private RdbmsCentralRepoFactory getDbFactory() throws CentralRepoException { switch (selectedPlatform) { - case POSTGRESQL: return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsPostgres); - case SQLITE: return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsSqlite); - default: throw new CentralRepoException("Unknown database type: " + selectedPlatform); + case POSTGRESQL: + return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsPostgres); + case SQLITE: + return new RdbmsCentralRepoFactory(selectedPlatform, dbSettingsSqlite); + case DISABLED: + return null; + default: + throw new CentralRepoException("Unknown database type: " + selectedPlatform); + } + } + + private String getCurrentSettingsString() throws CentralRepoException { + switch (selectedPlatform) { + case POSTGRESQL: + return String.format("[db type: postgres, host: %s:%d, db name: %s, username: %s]", + dbSettingsPostgres.getHost(), dbSettingsPostgres.getPort(), dbSettingsPostgres.getDbName(), dbSettingsPostgres.getUserName()); + case SQLITE: + return String.format("[db type: sqlite, directory: %s, name: %s]", dbSettingsSqlite.getDbDirectory(), dbSettingsSqlite.getDbName()); + case DISABLED: + return "[db type: disabled]"; + default: + throw new CentralRepoException("Unknown database type: " + selectedPlatform); } } @@ -160,7 +179,7 @@ public class CentralRepoDbManager { boolean result = false; boolean dbCreated = true; - CentralRepoSettings selectedDbSettings = getSelectedSettings(); + CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); if (!selectedDbSettings.verifyDatabaseExists()) { dbCreated = selectedDbSettings.createDatabase(); @@ -170,20 +189,9 @@ public class CentralRepoDbManager { RdbmsCentralRepoFactory centralRepoSchemaFactory = getDbFactory(); result = centralRepoSchemaFactory.initializeDatabaseSchema() - && centralRepoSchemaFactory.insertDefaultDatabaseContent(); + && centralRepoSchemaFactory.insertDefaultDatabaseContent(); } catch (CentralRepoException ex) { - String message = ""; - switch (selectedPlatform) { - case POSTGRESQL: - message = String.format("Unable to create Postgres database for Central Repository at %s:%d with db name: %s and username %s", - dbSettingsPostgres.getHost(), dbSettingsPostgres.getPort(), dbSettingsPostgres.getDbName(), dbSettingsPostgres.getUserName()); - break; - case SQLITE: - message = "Unable to create Sqlite database for Central Repository at " + dbSettingsSqlite.getDbDirectory(); - break; - } - - logger.log(Level.SEVERE, message, ex); + logger.log(Level.SEVERE, "Unable to create database for central repository " + getCurrentSettingsString(), ex); throw new CentralRepoException("Unable to create Postgres database for Central Repository."); } } @@ -203,7 +211,6 @@ public class CentralRepoDbManager { return true; } - /** * saves a new central repository based on current settings */ @@ -234,39 +241,23 @@ public class CentralRepoDbManager { CentralRepoPlatforms.setSelectedPlatform(selectedPlatform.name()); CentralRepoPlatforms.saveSelectedPlatform(); + CentralRepoDbSettings selectedDbSettings = getSelectedSettings(); + + // save the new settings + selectedDbSettings.saveSettings(); + // Load those newly saved settings into the postgres db manager instance + // in case we are still using the same instance. switch (selectedPlatform) { case POSTGRESQL: - // save the new PostgreSQL settings - dbSettingsPostgres.saveSettings(); - // Load those newly saved settings into the postgres db manager instance - // in case we are still using the same instance. + case SQLITE: try { + logger.info("Creating central repo db with settings: " + getCurrentSettingsString()); CentralRepository.getInstance().updateSettings(); configurationChanged = true; } catch (CentralRepoException ex) { logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS return; } - - break; - case SQLITE: - // save the new SQLite settings - logger.info(String.format("Attempting to set up sqlite database at path: %s with filename: %s", - dbSettingsSqlite.getDbDirectory(), dbSettingsSqlite.getDbName())); - - dbSettingsSqlite.saveSettings(); - // Load those newly saved settings into the sqlite db manager instance - // in case we are still using the same instance. - try { - CentralRepository.getInstance().updateSettings(); - configurationChanged = true; - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS - return; - } - break; - case DISABLED: - break; } } @@ -282,42 +273,39 @@ public class CentralRepoDbManager { testingStatus = DatabaseTestResult.UNTESTED; } - - public void setSelectedPlatform(CentralRepoPlatforms newSelected) { selectedPlatform = newSelected; testingStatus = DatabaseTestResult.UNTESTED; } - - + /** * Tests whether or not the database settings are valid. * * @return True or false. */ - public boolean testDatabaseSettingsAreValid ( + public boolean testDatabaseSettingsAreValid( String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { - + boolean result = true; StringBuilder guidanceText = new StringBuilder(); switch (selectedPlatform) { case POSTGRESQL: - dbSettingsPostgres.setHost(tbDbHostname); - dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); - dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); - dbSettingsPostgres.setUserName(tbDbUsername); - dbSettingsPostgres.setPassword(jpDbPassword); + dbSettingsPostgres.setHost(tbDbHostname); + dbSettingsPostgres.setPort(Integer.parseInt(tbDbPort)); + dbSettingsPostgres.setDbName(CENTRAL_REPO_DB_NAME); + dbSettingsPostgres.setUserName(tbDbUsername); + dbSettingsPostgres.setPassword(jpDbPassword); break; case SQLITE: - File databasePath = new File(tfDatabasePath); - dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); - dbSettingsSqlite.setDbDirectory(databasePath.getPath()); + File databasePath = new File(tfDatabasePath); + dbSettingsSqlite.setDbName(SqliteCentralRepoSettings.DEFAULT_DBNAME); + dbSettingsSqlite.setDbDirectory(databasePath.getPath()); break; default: throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedPlatform); } - + return result; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java similarity index 92% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoSettings.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java index d29b398df1..fd4fec0e13 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java @@ -9,8 +9,10 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; * * @author gregd */ -public interface CentralRepoSettings { +public interface CentralRepoDbSettings { + public void saveSettings(); + boolean createDatabase(); boolean deleteDatabase(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index 5f0de140d5..cfdd648ddc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -40,7 +40,7 @@ import static org.sleuthkit.autopsy.centralrepository.datamodel.RdbmsCentralRepo * NOTE: This is public scope because the options panel calls it directly to * set/get */ -public final class PostgresCentralRepoSettings implements CentralRepoSettings { +public final class PostgresCentralRepoSettings implements CentralRepoDbSettings { private final static Logger LOGGER = Logger.getLogger(PostgresCentralRepoSettings.class.getName()); private final static String DEFAULT_HOST = ""; // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index 39c9c6a154..5e88404b0f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil; * NOTE: This is public scope because the options panel calls it directly to * set/get */ -public final class SqliteCentralRepoSettings implements CentralRepoSettings { +public final class SqliteCentralRepoSettings implements CentralRepoDbSettings { public final static String DEFAULT_DBNAME = "central_repository.db"; // NON-NLS private final static Logger LOGGER = Logger.getLogger(SqliteCentralRepoSettings.class.getName()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 319ac9cfda..db657d7fab 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -158,6 +158,8 @@ public class EamDbSettingsDialog extends JDialog { Bundle.EamDbSettingsDialog_okButton_createDbError_title(), JOptionPane.WARNING_MESSAGE); } + + valid(); } } @@ -456,7 +458,8 @@ public class EamDbSettingsDialog extends JDialog { private void bnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOkActionPerformed setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); manager.testStatus(); - + valid(); + boolean testedOk = promptTestStatusWarnings(); if (!testedOk) { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); From 367bd69bddcc41a867e10128d8c27081bd8a3a4b Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 10:11:16 -0500 Subject: [PATCH 18/36] central repo code cleanup --- .../datamodel/CentralRepoDbManager.java | 18 ++---------------- .../datamodel/PostgresCentralRepoSettings.java | 6 ++++++ .../datamodel/SqliteCentralRepoSettings.java | 4 ++++ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 7bcd05af12..c800f27f1a 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -161,20 +161,6 @@ public class CentralRepoDbManager { } } - private String getCurrentSettingsString() throws CentralRepoException { - switch (selectedPlatform) { - case POSTGRESQL: - return String.format("[db type: postgres, host: %s:%d, db name: %s, username: %s]", - dbSettingsPostgres.getHost(), dbSettingsPostgres.getPort(), dbSettingsPostgres.getDbName(), dbSettingsPostgres.getUserName()); - case SQLITE: - return String.format("[db type: sqlite, directory: %s, name: %s]", dbSettingsSqlite.getDbDirectory(), dbSettingsSqlite.getDbName()); - case DISABLED: - return "[db type: disabled]"; - default: - throw new CentralRepoException("Unknown database type: " + selectedPlatform); - } - } - public boolean createDb() throws CentralRepoException { boolean result = false; boolean dbCreated = true; @@ -191,7 +177,7 @@ public class CentralRepoDbManager { result = centralRepoSchemaFactory.initializeDatabaseSchema() && centralRepoSchemaFactory.insertDefaultDatabaseContent(); } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Unable to create database for central repository " + getCurrentSettingsString(), ex); + logger.log(Level.SEVERE, "Unable to create database for central repository with settings " + selectedDbSettings, ex); throw new CentralRepoException("Unable to create Postgres database for Central Repository."); } } @@ -251,7 +237,7 @@ public class CentralRepoDbManager { case POSTGRESQL: case SQLITE: try { - logger.info("Creating central repo db with settings: " + getCurrentSettingsString()); + logger.info("Creating central repo db with settings: " + selectedDbSettings); CentralRepository.getInstance().updateSettings(); configurationChanged = true; } catch (CentralRepoException ex) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java index cfdd648ddc..476b67dbc2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/PostgresCentralRepoSettings.java @@ -64,6 +64,12 @@ public final class PostgresCentralRepoSettings implements CentralRepoDbSettings loadSettings(); } + @Override + public String toString() { + return String.format("PostgresCentralRepoSettings: [db type: postgres, host: %s:%d, db name: %s, username: %s]", + getHost(), getPort(), getDbName(), getUserName()); + } + public void loadSettings() { host = ModuleSettings.getConfigSetting("CentralRepository", "db.postgresql.host"); // NON-NLS if (host == null || host.isEmpty()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java index 5e88404b0f..675a164972 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/SqliteCentralRepoSettings.java @@ -81,6 +81,10 @@ public final class SqliteCentralRepoSettings implements CentralRepoDbSettings { } } + public String toString() { + return String.format("SqliteCentralRepoSettings: [db type: sqlite, directory: %s, name: %s]", getDbDirectory(), getDbName()); + } + /** * sets database directory and name to defaults */ From 8b09842bb50fb2bb086a9e9bff7f990edb070a9e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 11:09:25 -0500 Subject: [PATCH 19/36] fix for licenses on new files in central repo --- .../datamodel/CentralRepoDbManager.java | 19 ++++++++++++++++--- .../datamodel/CentralRepoDbSettings.java | 19 ++++++++++++++++--- .../datamodel/DatabaseTestResult.java | 19 ++++++++++++++++--- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index c800f27f1a..697a468a23 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Central Repository + * + * Copyright 2015-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.centralrepository.datamodel; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java index fd4fec0e13..de568c7553 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Central Repository + * + * Copyright 2015-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.centralrepository.datamodel; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java index d7a13b6041..42df359673 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Central Repository + * + * Copyright 2015-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.centralrepository.datamodel; diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index 4f645919d3..b20ccf5912 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Fri, 14 Feb 2020 12:16:52 -0500 +#Tue, 12 Nov 2019 17:21:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.14.0 +currentVersion=Autopsy 4.13.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 627464541f..998d3f715c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Fri, 14 Feb 2020 12:16:52 -0500 -CTL_MainWindow_Title=Autopsy 4.14.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 +#Tue, 12 Nov 2019 17:21:46 -0500 +CTL_MainWindow_Title=Autopsy 4.13.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 From 0004afacd12a4f7a697ccfdf2c9c5810632107e2 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 13:05:36 -0500 Subject: [PATCH 20/36] some more code cleanup --- .../datamodel/CentralRepoDbManager.java | 197 +++++++++--------- .../datamodel/CentralRepoDbSettings.java | 2 +- .../datamodel/DatabaseTestResult.java | 3 + .../eventlisteners/Installer.java | 5 +- .../optionspanel/EamDbSettingsDialog.java | 25 +-- 5 files changed, 117 insertions(+), 115 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 697a468a23..a6b0003c35 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -18,18 +18,16 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; -import java.awt.Cursor; import java.io.File; import java.sql.SQLException; import java.util.logging.Level; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; import org.openide.util.NbBundle; -import org.openide.windows.WindowManager; -import org.sleuthkit.autopsy.centralrepository.optionspanel.EamDbSettingsDialog; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; import org.sleuthkit.autopsy.coreutils.Logger; +/** + * Contains business logic for saving and validating settings for central repo + */ public class CentralRepoDbManager { private static final Logger logger = Logger.getLogger(CentralRepoDbManager.class.getName()); @@ -49,69 +47,85 @@ public class CentralRepoDbManager { CentralRepository db = null; CoordinationService.Lock lock = null; + //get connection try { + db = CentralRepository.getInstance(); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); + onUpgradeError("Error updating central repository, unable to make connection", + Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } + + //get lock necessary for upgrade + if (db != null) { try { - db = CentralRepository.getInstance(); + // This may return null if locking isn't supported, which is fine. It will + // throw an exception if locking is supported but we can't get the lock + // (meaning the database is in use by another user) + lock = db.getExclusiveMultiUserDbLock(); + //perform upgrade } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); - throw new CentralRepoException("Error updating central repository, unable to make connection", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + logger.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); + onUpgradeError("Error updating central repository, unable to acquire exclusive lock", + Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); } - //get lock necessary for upgrade - if (db != null) { - try { - // This may return null if locking isn't supported, which is fine. It will - // throw an exception if locking is supported but we can't get the lock - // (meaning the database is in use by another user) - lock = db.getExclusiveMultiUserDbLock(); - //perform upgrade - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); - throw new CentralRepoException("Error updating central repository, unable to acquire exclusive lock", Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } - try { - db.upgradeSchema(); - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (SQLException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (IncompatibleCentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - throw new CentralRepoException("Error updating central repository", ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } finally { - if (lock != null) { - try { - lock.release(); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.SEVERE, "Error releasing database lock", ex); - } + + try { + db.upgradeSchema(); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (SQLException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (IncompatibleCentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", + ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } finally { + if (lock != null) { + try { + lock.release(); + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.SEVERE, "Error releasing database lock", ex); } } - } else { - throw new CentralRepoException("Unable to connect to database", Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message()); } - } catch (CentralRepoException ex) { - // Disable the central repo and clear the current settings. - try { - if (null != CentralRepository.getInstance()) { - CentralRepository.getInstance().shutdownConnections(); - } - } catch (CentralRepoException ex2) { - logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); - } - CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); - CentralRepoPlatforms.saveSelectedPlatform(); - throw ex; + } else { + onUpgradeError("Unable to connect to database", + Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), null); } } + + private static void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { + // Disable the central repo and clear the current settings. + try { + if (null != CentralRepository.getInstance()) { + CentralRepository.getInstance().shutdownConnections(); + } + } catch (CentralRepoException ex2) { + logger.log(Level.SEVERE, "Error shutting down central repo connection pool", ex2); + } + CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); + CentralRepoPlatforms.saveSelectedPlatform(); + if (innerException == null) { + throw new CentralRepoException(message, desc); + } + else { + throw new CentralRepoException(message, desc, innerException); + } + } + + + private DatabaseTestResult testingStatus; private CentralRepoPlatforms selectedPlatform; - private PostgresCentralRepoSettings dbSettingsPostgres; - private SqliteCentralRepoSettings dbSettingsSqlite; + private final PostgresCentralRepoSettings dbSettingsPostgres; + private final SqliteCentralRepoSettings dbSettingsSqlite; private boolean configurationChanged = false; @@ -191,7 +205,7 @@ public class CentralRepoDbManager { && centralRepoSchemaFactory.insertDefaultDatabaseContent(); } catch (CentralRepoException ex) { logger.log(Level.SEVERE, "Unable to create database for central repository with settings " + selectedDbSettings, ex); - throw new CentralRepoException("Unable to create Postgres database for Central Repository."); + throw ex; } } if (!result) { @@ -246,17 +260,15 @@ public class CentralRepoDbManager { selectedDbSettings.saveSettings(); // Load those newly saved settings into the postgres db manager instance // in case we are still using the same instance. - switch (selectedPlatform) { - case POSTGRESQL: - case SQLITE: - try { - logger.info("Creating central repo db with settings: " + selectedDbSettings); - CentralRepository.getInstance().updateSettings(); - configurationChanged = true; - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS - return; - } + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL || selectedPlatform == CentralRepoPlatforms.SQLITE) { + try { + logger.info("Creating central repo db with settings: " + selectedDbSettings); + CentralRepository.getInstance().updateSettings(); + configurationChanged = true; + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, Bundle.CentralRepoDbManager_connectionErrorMsg_text(), ex); //NON-NLS + return; + } } } @@ -285,9 +297,6 @@ public class CentralRepoDbManager { public boolean testDatabaseSettingsAreValid( String tbDbHostname, String tbDbPort, String tbDbUsername, String tfDatabasePath, String jpDbPassword) throws CentralRepoException, NumberFormatException { - boolean result = true; - StringBuilder guidanceText = new StringBuilder(); - switch (selectedPlatform) { case POSTGRESQL: dbSettingsPostgres.setHost(tbDbHostname); @@ -305,41 +314,39 @@ public class CentralRepoDbManager { throw new IllegalStateException("Central Repo has an unknown selected platform: " + selectedPlatform); } - return result; + return true; } public DatabaseTestResult testStatus() { - switch (selectedPlatform) { - case POSTGRESQL: - if (dbSettingsPostgres.verifyConnection()) { - if (dbSettingsPostgres.verifyDatabaseExists()) { - if (dbSettingsPostgres.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } - } else { - testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; - } - } else { - testingStatus = DatabaseTestResult.CONNECTION_FAILED; - } - break; - case SQLITE: - if (dbSettingsSqlite.dbFileExists()) { - if (dbSettingsSqlite.verifyConnection()) { - if (dbSettingsSqlite.verifyDatabaseSchema()) { - testingStatus = DatabaseTestResult.TESTEDOK; - } else { - testingStatus = DatabaseTestResult.SCHEMA_INVALID; - } + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + if (dbSettingsPostgres.verifyConnection()) { + if (dbSettingsPostgres.verifyDatabaseExists()) { + if (dbSettingsPostgres.verifyDatabaseSchema()) { + testingStatus = DatabaseTestResult.TESTEDOK; } else { testingStatus = DatabaseTestResult.SCHEMA_INVALID; } } else { testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; } - break; + } else { + testingStatus = DatabaseTestResult.CONNECTION_FAILED; + } + } + else if (selectedPlatform == CentralRepoPlatforms.SQLITE) { + if (dbSettingsSqlite.dbFileExists()) { + if (dbSettingsSqlite.verifyConnection()) { + if (dbSettingsSqlite.verifyDatabaseSchema()) { + testingStatus = DatabaseTestResult.TESTEDOK; + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.SCHEMA_INVALID; + } + } else { + testingStatus = DatabaseTestResult.DB_DOES_NOT_EXIST; + } } return testingStatus; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java index de568c7553..01d8ed1d6f 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java @@ -24,7 +24,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; */ public interface CentralRepoDbSettings { - public void saveSettings(); + void saveSettings(); boolean createDatabase(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java index 42df359673..27a7b16278 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DatabaseTestResult.java @@ -18,6 +18,9 @@ */ package org.sleuthkit.autopsy.centralrepository.datamodel; +/** + * provides the status of the database after attempting to validate central repo settings + */ public enum DatabaseTestResult { UNTESTED, CONNECTION_FAILED, diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 8f96140837..bd960af6e9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -23,7 +23,6 @@ import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.openide.modules.ModuleInstall; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; @@ -99,7 +98,7 @@ public class Installer extends ModuleInstall { reportUpgradeError(ex); } }); - } catch (Exception ex) { + } catch (InterruptedException | InvocationTargetException ex) { LOGGER.log(Level.SEVERE, "There was an error while running the swing utility invoke later while creating the central repository database", ex); } } // if no GUI, just initialize @@ -144,7 +143,7 @@ public class Installer extends ModuleInstall { "Installer.centralRepoUpgradeFailed.title"), JOptionPane.ERROR_MESSAGE); }); - } catch (Exception e) { + } catch (InterruptedException | InvocationTargetException e) { LOGGER.warning("There was an error while running the swing utility invoke later while displaying an error " + "for creating the central repository database: " + e.getMessage() + System.lineSeparator() + e.getStackTrace()); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index db657d7fab..373a746cab 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -614,22 +614,15 @@ public class EamDbSettingsDialog extends JDialog { @Messages({"EamDbSettingsDialog.validation.incompleteFields=Fill in all values for the selected database."}) private boolean databaseFieldsArePopulated() { boolean result = true; - switch (manager.getSelectedPlatform()) { - case POSTGRESQL: - result = !tbDbHostname.getText().trim().isEmpty() - && !tbDbPort.getText().trim().isEmpty() - // && !tbDbName.getText().trim().isEmpty() - && !tbDbUsername.getText().trim().isEmpty() - && 0 < jpDbPassword.getPassword().length; - - break; - - case SQLITE: - result = !tfDatabasePath.getText().trim().isEmpty(); - break; + if (manager.getSelectedPlatform() == CentralRepoPlatforms.POSTGRESQL) { + result = !tbDbHostname.getText().trim().isEmpty() + && !tbDbPort.getText().trim().isEmpty() + // && !tbDbName.getText().trim().isEmpty() + && !tbDbUsername.getText().trim().isEmpty() + && 0 < jpDbPassword.getPassword().length; } - - if (!result) { + else if (manager.getSelectedPlatform() == CentralRepoPlatforms.SQLITE) { + result = !tfDatabasePath.getText().trim().isEmpty(); } return result; @@ -688,7 +681,7 @@ public class EamDbSettingsDialog extends JDialog { tfDatabasePath.getText().trim(), new String(jpDbPassword.getPassword())); } - catch (Exception e) { + catch (CentralRepoException | NumberFormatException | IllegalStateException e) { return false; } From 86285c071c659a865743e68655a5ca0eb02e3a8e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\gregd" Date: Mon, 24 Feb 2020 13:37:29 -0500 Subject: [PATCH 21/36] further cleanup of central repo code --- .../datamodel/CentralRepoDbManager.java | 143 +++++++++++------- .../optionspanel/EamDbSettingsDialog.java | 18 +-- 2 files changed, 93 insertions(+), 68 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index a6b0003c35..e4f9eea857 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -34,6 +34,82 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; + /** + * attains the database connectivity for central repository + * + * @return the CentralRepository object to connect to + * @throws CentralRepoException + */ + private static CentralRepository attainCentralRepository() throws CentralRepoException { + //get connection + try { + return CentralRepository.getInstance(); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); + onUpgradeError("Error updating central repository, unable to make connection", + Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } + + // will never be reached + return null; + } + + /** + * attains central repository lock + * + * @param db the database connection + * @return the lock if acquired + * @throws CentralRepoException + */ + private static CoordinationService.Lock attainCentralRepoLock(CentralRepository db) throws CentralRepoException { + try { + // This may return null if locking isn't supported, which is fine. It will + // throw an exception if locking is supported but we can't get the lock + // (meaning the database is in use by another user) + return db.getExclusiveMultiUserDbLock(); + //perform upgrade + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); + onUpgradeError("Error updating central repository, unable to acquire exclusive lock", + Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } + + // will never be reached + return null; + } + + /** + * updates central repository schema if necessary + * + * @param db the database connectivity + * @param lock the acquired lock + * @throws CentralRepoException + */ + private static void updatedDbSchema(CentralRepository db, CoordinationService.Lock lock) throws CentralRepoException { + try { + db.upgradeSchema(); + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (SQLException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } catch (IncompatibleCentralRepoException ex) { + logger.log(Level.SEVERE, "Error updating central repository", ex); + onUpgradeError("Error updating central repository", + ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); + } finally { + if (lock != null) { + try { + lock.release(); + } catch (CoordinationService.CoordinationServiceException ex) { + logger.log(Level.SEVERE, "Error releasing database lock", ex); + } + } + } + } + /** * Upgrade the current Central Reposity schema to the newest version. If the * upgrade fails, the Central Repository will be disabled and the current @@ -45,60 +121,18 @@ public class CentralRepoDbManager { return; } - CentralRepository db = null; - CoordinationService.Lock lock = null; - - //get connection - try { - db = CentralRepository.getInstance(); - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository, unable to make connection", ex); - onUpgradeError("Error updating central repository, unable to make connection", - Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } + CentralRepository db = attainCentralRepository(); //get lock necessary for upgrade if (db != null) { - try { - // This may return null if locking isn't supported, which is fine. It will - // throw an exception if locking is supported but we can't get the lock - // (meaning the database is in use by another user) - lock = db.getExclusiveMultiUserDbLock(); - //perform upgrade - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository, unable to acquire exclusive lock", ex); - onUpgradeError("Error updating central repository, unable to acquire exclusive lock", - Bundle.EamDbUtil_exclusiveLockAquisitionFailure_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } - - try { - db.upgradeSchema(); - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - onUpgradeError("Error updating central repository", ex.getUserMessage() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (SQLException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - onUpgradeError("Error updating central repository", - Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } catch (IncompatibleCentralRepoException ex) { - logger.log(Level.SEVERE, "Error updating central repository", ex); - onUpgradeError("Error updating central repository", - ex.getMessage() + "\n\n" + Bundle.EamDbUtil_centralRepoUpgradeFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), ex); - } finally { - if (lock != null) { - try { - lock.release(); - } catch (CoordinationService.CoordinationServiceException ex) { - logger.log(Level.SEVERE, "Error releasing database lock", ex); - } - } - } + CoordinationService.Lock lock = attainCentralRepoLock(db); + updatedDbSchema(db, lock); } else { - onUpgradeError("Unable to connect to database", - Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), null); + onUpgradeError("Unable to connect to database", + Bundle.EamDbUtil_centralRepoConnectionFailed_message() + Bundle.EamDbUtil_centralRepoDisabled_message(), null); } } - + private static void onUpgradeError(String message, String desc, Exception innerException) throws CentralRepoException { // Disable the central repo and clear the current settings. try { @@ -111,15 +145,11 @@ public class CentralRepoDbManager { CentralRepoPlatforms.setSelectedPlatform(CentralRepoPlatforms.DISABLED.name()); CentralRepoPlatforms.saveSelectedPlatform(); if (innerException == null) { - throw new CentralRepoException(message, desc); - } - else { - throw new CentralRepoException(message, desc, innerException); + throw new CentralRepoException(message, desc); + } else { + throw new CentralRepoException(message, desc, innerException); } } - - - private DatabaseTestResult testingStatus; private CentralRepoPlatforms selectedPlatform; @@ -332,8 +362,7 @@ public class CentralRepoDbManager { } else { testingStatus = DatabaseTestResult.CONNECTION_FAILED; } - } - else if (selectedPlatform == CentralRepoPlatforms.SQLITE) { + } else if (selectedPlatform == CentralRepoPlatforms.SQLITE) { if (dbSettingsSqlite.dbFileExists()) { if (dbSettingsSqlite.verifyConnection()) { if (dbSettingsSqlite.verifyDatabaseSchema()) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 373a746cab..25289da2af 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -414,17 +414,13 @@ public class EamDbSettingsDialog extends JDialog { setTextPrompts(); setTextBoxListeners(); manager.clearStatus(); - switch (manager.getSelectedPlatform()) { - case SQLITE: - updatePostgresFields(false); - updateSqliteFields(true); - break; - default: - POSTGRESQL: - updatePostgresFields(true); - updateSqliteFields(false); - break; - + if (manager.getSelectedPlatform() == CentralRepoPlatforms.SQLITE) { + updatePostgresFields(false); + updateSqliteFields(true); + } + else { + updatePostgresFields(true); + updateSqliteFields(false); } displayDatabaseSettings(CentralRepoPlatforms.POSTGRESQL.equals(manager.getSelectedPlatform())); } From f75e02b739b0c365c3f4540c9c991ab4df1e6080 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 25 Feb 2020 14:49:16 -0500 Subject: [PATCH 22/36] 6022 fix for summarization of files when no textextractor is found --- .../org/sleuthkit/autopsy/filequery/FileSearch.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index ee5c36c8e3..fbf8356e16 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -291,13 +291,21 @@ class FileSearch { * @return The beginning of text from the specified AbstractFile. */ private static String getFirstLines(AbstractFile file) { - try (Reader reader = TextExtractorFactory.getExtractor(file, null).getReader()) { + TextExtractor extractor; + try { + extractor = TextExtractorFactory.getExtractor(file, null); + } catch (TextExtractorFactory.NoTextExtractorFound ignored) { + //no extractor found, use Strings Extractor + extractor = TextExtractorFactory.getStringsExtractor(file, null); + } + + try (Reader reader = extractor.getReader()) { char[] cbuf = new char[PREVIEW_SIZE]; reader.read(cbuf, 0, PREVIEW_SIZE); return new String(cbuf); } catch (IOException ex) { return Bundle.FileSearch_documentSummary_noBytes(); - } catch (TextExtractorFactory.NoTextExtractorFound | TextExtractor.InitReaderException ex) { + } catch (TextExtractor.InitReaderException ex) { return Bundle.FileSearch_documentSummary_noPreview(); } } From 6d412131b032682e5808c5d04551a0a085cd3280 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 25 Feb 2020 16:12:44 -0500 Subject: [PATCH 23/36] updated messages --- .../datamodel/CentralRepoDbManager.java | 15 +++++++++------ .../datamodel/CentralRepoDbSettings.java | 3 +-- .../eventlisteners/Installer.java | 4 +--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index e4f9eea857..38f9218abc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -35,12 +35,12 @@ public class CentralRepoDbManager { private static final String CENTRAL_REPO_DB_NAME = "central_repository"; /** - * attains the database connectivity for central repository + * obtains the database connectivity for central repository * * @return the CentralRepository object to connect to * @throws CentralRepoException */ - private static CentralRepository attainCentralRepository() throws CentralRepoException { + private static CentralRepository obtainCentralRepository() throws CentralRepoException { //get connection try { return CentralRepository.getInstance(); @@ -55,13 +55,13 @@ public class CentralRepoDbManager { } /** - * attains central repository lock + * obtains central repository lock * * @param db the database connection * @return the lock if acquired * @throws CentralRepoException */ - private static CoordinationService.Lock attainCentralRepoLock(CentralRepository db) throws CentralRepoException { + private static CoordinationService.Lock obtainCentralRepoLock(CentralRepository db) throws CentralRepoException { try { // This may return null if locking isn't supported, which is fine. It will // throw an exception if locking is supported but we can't get the lock @@ -121,11 +121,11 @@ public class CentralRepoDbManager { return; } - CentralRepository db = attainCentralRepository(); + CentralRepository db = obtainCentralRepository(); //get lock necessary for upgrade if (db != null) { - CoordinationService.Lock lock = attainCentralRepoLock(db); + CoordinationService.Lock lock = obtainCentralRepoLock(db); updatedDbSchema(db, lock); } else { onUpgradeError("Unable to connect to database", @@ -163,6 +163,9 @@ public class CentralRepoDbManager { dbSettingsPostgres = new PostgresCentralRepoSettings(); dbSettingsSqlite = new SqliteCentralRepoSettings(); selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + + // set the default selected platform for displaying in the ui of EamDbSettingsDialog + // if selected option is not applicable if (selectedPlatform == null || selectedPlatform.equals(CentralRepoPlatforms.DISABLED)) { selectedPlatform = CentralRepoPlatforms.POSTGRESQL; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java index 01d8ed1d6f..f9bf520654 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbSettings.java @@ -19,8 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.datamodel; /** - * - * @author gregd + * common interface for settings pertaining to the database in central repository */ public interface CentralRepoDbSettings { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index bd960af6e9..cc3836c8ed 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -144,9 +144,7 @@ public class Installer extends ModuleInstall { JOptionPane.ERROR_MESSAGE); }); } catch (InterruptedException | InvocationTargetException e) { - LOGGER.warning("There was an error while running the swing utility invoke later while displaying an error " + - "for creating the central repository database: " - + e.getMessage() + System.lineSeparator() + e.getStackTrace()); + LOGGER.log(Level.WARNING, e.getMessage(), e); } } From 4cda428708eae34074818dfd6cd15cc6db0d3258 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 26 Feb 2020 12:25:08 -0500 Subject: [PATCH 24/36] updates in central repository to avoid bug on initialization if sqlite db already exists --- .../datamodel/CentralRepoDbManager.java | 23 ++++++++++++++++++- .../eventlisteners/Installer.java | 16 ++++++------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java index 38f9218abc..d2647965a5 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbManager.java @@ -179,9 +179,30 @@ public class CentralRepoDbManager { return dbSettingsSqlite; } - public void setupDefaultSqliteSettings() { + /** + * setup sqlite db with default settings + * @throws CentralRepoException if unable to successfully set up database + */ + public void setupDefaultSqliteDb() throws CentralRepoException { + // change in-memory settings to default sqlite selectedPlatform = CentralRepoPlatforms.SQLITE; dbSettingsSqlite.setupDefaultSettings(); + + // if db is not present, attempt to create it + DatabaseTestResult curStatus = testStatus(); + if (curStatus == DatabaseTestResult.DB_DOES_NOT_EXIST) { + createDb(); + curStatus = testStatus(); + } + + // the only successful setup status is tested ok + if (curStatus != DatabaseTestResult.TESTEDOK) { + throw new CentralRepoException("Unable to successfully create sqlite database"); + } + + // if successfully got here, then save the settings + CentralRepoDbUtil.setUseCentralRepo(true); + saveNewCentralRepo(); } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index cc3836c8ed..1609047e6d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -29,6 +29,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; +import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; @@ -57,7 +58,6 @@ public class Installer extends ModuleInstall { } @NbBundle.Messages({ - "Installer.centralRepoUpgradeFailed.title=Central repository disabled", "Installer.initialCreateSqlite.title=Enable Central Repository?", "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to?", "Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. " + @@ -127,21 +127,19 @@ public class Installer extends ModuleInstall { } private void setupDefaultSqlite() throws CentralRepoException { - CentralRepoDbUtil.setUseCentralRepo(true); CentralRepoDbManager manager = new CentralRepoDbManager(); - manager.setupDefaultSqliteSettings(); - manager.createDb(); - manager.saveNewCentralRepo(); + manager.setupDefaultSqliteDb(); } + @NbBundle.Messages({ "Installer.centralRepoUpgradeFailed.title=Central repository disabled" }) private void reportUpgradeError(CentralRepoException ex) { try { SwingUtilities.invokeAndWait(() -> { JOptionPane.showMessageDialog(null, - ex.getUserMessage(), - NbBundle.getMessage(this.getClass(), - "Installer.centralRepoUpgradeFailed.title"), - JOptionPane.ERROR_MESSAGE); + ex.getUserMessage(), + NbBundle.getMessage(this.getClass(), + "Installer.centralRepoUpgradeFailed.title"), + JOptionPane.ERROR_MESSAGE); }); } catch (InterruptedException | InvocationTargetException e) { LOGGER.log(Level.WARNING, e.getMessage(), e); From bcf728f1b7b368e98630cc0bd71ada7972682053 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 26 Feb 2020 15:53:26 -0500 Subject: [PATCH 25/36] Updated to support GeoArtifactHelper changes --- .../autopsy/geolocation/datamodel/Route.java | 10 ++++++---- .../autopsy/geolocation/datamodel/Track.java | 18 ++++++++++-------- .../autopsy/modules/drones/DATExtractor.java | 4 ++-- .../android/googlemaplocation.py | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index fa8dacf5d2..a08c343b6a 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -26,8 +26,9 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints.GeoWaypoint; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList.GeoWaypoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil.GeoWaypointList; /** * A Route represents a TSK_GPS_ROUTE artifact which has a start and end point @@ -42,6 +43,8 @@ public class Route extends GeoPath { // This list is not expected to change after construction so the // constructor will take care of creating an unmodifiable List private final List propertiesList; + + private static final TskGeoWaypointsUtil attributeUtil = new TskGeoWaypointsUtil(""); /** * Construct a route for the given artifact. @@ -117,8 +120,7 @@ public class Route extends GeoPath { } if (attribute != null) { - String value = attribute.getValueString(); - GeoWaypoints waypoints = GeoWaypoints.deserialize(value); + GeoWaypointList waypoints = attributeUtil.fromAttribute(attribute); Iterator waypointIter = waypoints.iterator(); while(waypointIter.hasNext()) { diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index 33294d0d18..b6dc5a1528 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -27,8 +27,9 @@ import java.util.Map; import org.openide.util.NbBundle.Messages; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints.GeoTrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint; /** * A GPS track with which wraps the TSK_GPS_TRACK artifact. @@ -37,6 +38,8 @@ public final class Track extends GeoPath{ private final Long startTimestamp; private final Long endTimeStamp; + + private static final TskGeoTrackpointsUtil attributeUtil = new TskGeoTrackpointsUtil(""); /** * Construct a new Track for the given artifact. @@ -60,7 +63,7 @@ public final class Track extends GeoPath{ private Track(BlackboardArtifact artifact, Map attributeMap) throws GeoLocationDataException { super(artifact, getTrackName(attributeMap)); - GeoTrackPoints points = getPointsList(attributeMap); + GeoTrackPointList points = getPointsList(attributeMap); buildPath(points); startTimestamp = points.getStartTime(); @@ -112,8 +115,8 @@ public final class Track extends GeoPath{ "# {0} - track name", "GEOTrack_point_label_header=Trackpoint for track: {0}" }) - private void buildPath(GeoTrackPoints points) throws GeoLocationDataException { - Iterator pointIter = points.iterator(); + private void buildPath(GeoTrackPointList points) throws GeoLocationDataException { + Iterator pointIter = points.iterator(); while(pointIter.hasNext()) { GeoTrackPoint point = pointIter.next(); addToPath(new TrackWaypoint(Bundle.GEOTrack_point_label_header(getLabel()), point)); @@ -128,11 +131,10 @@ public final class Track extends GeoPath{ * * @return GeoTrackPoint list empty list if the attribute was not found. */ - private GeoTrackPoints getPointsList(Map attributeMap) { + private GeoTrackPointList getPointsList(Map attributeMap) { BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); if (attribute != null) { - String value = attribute.getValueString(); - return GeoTrackPoints.deserialize(value); + return attributeUtil.fromAttribute(attribute); } return null; diff --git a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java index 68947be6fa..97cfbd40be 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/modules/drones/DATExtractor.java @@ -41,11 +41,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; import org.sleuthkit.autopsy.ingest.IngestJobContext; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPointList.GeoTrackPoint; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint; import org.sleuthkit.datamodel.blackboardutils.GeoArtifactsHelper; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.Blackboard.BlackboardException; -import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPointList; +import org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoTrackpointsUtil.GeoTrackPointList; /** * Extract drone position data from DJI Phantom drones. diff --git a/InternalPythonModules/android/googlemaplocation.py b/InternalPythonModules/android/googlemaplocation.py index 330095c900..c04aadfba3 100644 --- a/InternalPythonModules/android/googlemaplocation.py +++ b/InternalPythonModules/android/googlemaplocation.py @@ -42,7 +42,7 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper -from org.sleuthkit.datamodel.blackboardutils.attributes import GeoWaypointList +from org.sleuthkit.datamodel.blackboardutils.attributes.TskGeoWaypointsUtil import GeoWaypointList import traceback import general From 605aa0086575c67361b59c36252266aa6ce52e58 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 27 Feb 2020 10:15:59 -0500 Subject: [PATCH 26/36] Updated based on review comments --- .../org/sleuthkit/autopsy/geolocation/datamodel/Route.java | 5 +---- .../org/sleuthkit/autopsy/geolocation/datamodel/Track.java | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index a08c343b6a..cda71c0e60 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -20,7 +20,6 @@ package org.sleuthkit.autopsy.geolocation.datamodel; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; import org.openide.util.NbBundle.Messages; @@ -122,9 +121,7 @@ public class Route extends GeoPath { if (attribute != null) { GeoWaypointList waypoints = attributeUtil.fromAttribute(attribute); - Iterator waypointIter = waypoints.iterator(); - while(waypointIter.hasNext()) { - GeoWaypoint waypoint = waypointIter.next(); + for(GeoWaypoint waypoint: waypoints) { addToPath(new Waypoint(artifact, label, null, waypoint.getLatitude(), waypoint.getLongitude(), waypoint.getAltitude(), null, attributeMap, this)); } } else { diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index b6dc5a1528..53ec4dfcbf 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -116,9 +116,7 @@ public final class Track extends GeoPath{ "GEOTrack_point_label_header=Trackpoint for track: {0}" }) private void buildPath(GeoTrackPointList points) throws GeoLocationDataException { - Iterator pointIter = points.iterator(); - while(pointIter.hasNext()) { - GeoTrackPoint point = pointIter.next(); + for(GeoTrackPoint point: points) { addToPath(new TrackWaypoint(Bundle.GEOTrack_point_label_header(getLabel()), point)); } } From 64709370987a64988d9a686df11dfb3e393b7978 Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Thu, 27 Feb 2020 10:52:29 -0500 Subject: [PATCH 27/36] Added missing geolocation detail lables --- .../geolocation/datamodel/Bundle.properties-MERGED | 2 ++ .../sleuthkit/autopsy/geolocation/datamodel/Track.java | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED index 18627193b9..d603e85b7b 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Bundle.properties-MERGED @@ -6,4 +6,6 @@ Route_Label=As-the-crow-flies Route Route_point_label=Waypoints for route Route_Start_Label=Start SearchWaypoint_DisplayLabel=GPS Search +Track_distanceFromHome_displayName=Distance from home point +Track_distanceTraveled_displayName=Distance traveled TrackpointWaypoint_DisplayLabel=GPS Trackpoint diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index 53ec4dfcbf..3760c6f1eb 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -21,7 +21,6 @@ package org.sleuthkit.autopsy.geolocation.datamodel; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; import org.openide.util.NbBundle.Messages; @@ -183,6 +182,10 @@ public final class Track extends GeoPath{ * * @return A list of Waypoint.properies. */ + @Messages({ + "Track_distanceTraveled_displayName=Distance traveled", + "Track_distanceFromHome_displayName=Distance from home point" + }) private List createPropertyList(GeoTrackPoint point) { List list = new ArrayList<>(); @@ -198,12 +201,12 @@ public final class Track extends GeoPath{ value = point.getDistanceTraveled(); if (value != null) { - list.add(new Property("", value.toString())); + list.add(new Property(Bundle.Track_distanceTraveled_displayName(), value.toString())); } value = point.getDistanceFromHP(); if (value != null) { - list.add(new Property("", value.toString())); + list.add(new Property(Bundle.Track_distanceFromHome_displayName(), value.toString())); } return list; From ede829860d8e948ea9e4f9d97f35a071036844ea Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 27 Feb 2020 12:31:56 -0500 Subject: [PATCH 28/36] cleaned up dependencies --- .../autopsy/centralrepository/eventlisteners/Installer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 1609047e6d..37b2bb37a9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -28,8 +28,6 @@ import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbManager; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil; -import org.sleuthkit.autopsy.centralrepository.datamodel.SqliteCentralRepoSettings; import org.sleuthkit.autopsy.core.RuntimeProperties; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.ModuleSettings; From 8e1cbce2d7188932e099b851071547f665cc7314 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 27 Feb 2020 15:01:49 -0500 Subject: [PATCH 29/36] update to check if cr initialized outside of code base --- .../eventlisteners/Installer.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 37b2bb37a9..54a642b0dc 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.centralrepository.eventlisteners; import java.lang.reflect.InvocationTargetException; +import java.util.Map; import java.util.logging.Level; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; @@ -66,10 +67,25 @@ public class Installer extends ModuleInstall { Case.addPropertyChangeListener(pcl); ieListener.installListeners(); - String initialized = ModuleSettings.getConfigSetting("CentralRepository", "initialized"); + + Map centralRepoSettings = ModuleSettings.getConfigSettings("CentralRepository"); + String initializedStr = centralRepoSettings.get("initialized"); + + // check to see if the repo has been initialized asking to setup cr + boolean initialized = Boolean.parseBoolean(initializedStr); + + // if it hasn't received that flag, check for a previous install where cr is already setup + if (!initialized) { + boolean prevRepo = Boolean.parseBoolean(centralRepoSettings.get("db.useCentralRepo")); + // if it has been previously set up and is in use, mark as previously initialized and save the settings + if (prevRepo) { + initialized = true; + ModuleSettings.setConfigSetting("CentralRepository", "initialized", "true"); + } + } // if central repository hasn't been previously initialized, initialize it - if (!Boolean.parseBoolean(initialized)) { + if (!initialized) { // if running with a GUI, prompt the user if (RuntimeProperties.runningWithGUI()) { try { From 9d26e2b69b03698e0a1da4beac09a5aebc5f191f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 28 Feb 2020 10:11:15 -0500 Subject: [PATCH 30/36] reverting merged properties --- .../contextviewer/Bundle.properties-MERGED | 3 +++ .../autopsy/core/Bundle.properties-MERGED | 8 +------- .../corecomponents/Bundle.properties-MERGED | 6 +++--- .../autopsy/coreutils/Bundle.properties-MERGED | 4 +--- .../filesearch/Bundle.properties-MERGED | 4 ++-- .../autopsy/ingest/Bundle.properties-MERGED | 2 +- .../Bundle.properties-MERGED | 8 ++------ .../modules/exif/Bundle.properties-MERGED | 4 +--- .../fileextmismatch/Bundle.properties-MERGED | 18 +++++++++--------- .../hashdatabase/Bundle.properties-MERGED | 10 ++-------- .../interestingitems/Bundle.properties-MERGED | 4 ++-- .../photoreccarver/Bundle.properties-MERGED | 2 +- .../modules/html/Bundle.properties-MERGED | 6 +++--- .../recentactivity/Bundle.properties-MERGED | 11 ++++++++--- .../netbeans/core/startup/Bundle.properties | 4 ++-- .../core/windows/view/ui/Bundle.properties | 6 +++--- 16 files changed, 44 insertions(+), 56 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED index 79f4f61bfa..b29e7190fd 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/contextviewer/Bundle.properties-MERGED @@ -3,6 +3,7 @@ ContextViewer.downloadedOn=On ContextViewer.downloadSource=Downloaded from: ContextViewer.downloadURL=URL ContextViewer.email=Email +ContextViewer.file=File ContextViewer.jSourceGoToResultButton.text=Go to Result ContextViewer.jSourceTextLabel.text=jLabel2 ContextViewer.jSourceNameLabel.text=jSourceNameLabel @@ -11,5 +12,7 @@ ContextViewer.message=Message ContextViewer.messageFrom=From ContextViewer.messageOn=On ContextViewer.messageTo=To +ContextViewer.on=On +ContextViewer.recentDocs=Recent Documents: ContextViewer.title=Context ContextViewer.toolTip=Displays context for selected file. diff --git a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED index 0b16a9701f..c84f1f1b86 100755 --- a/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/core/Bundle.properties-MERGED @@ -3,13 +3,7 @@ Installer.closing.confirmationDialog.title=Ingest is Running # {0} - exception message Installer.closing.messageBox.caseCloseExceptionMessage=Error closing case: {0} OpenIDE-Module-Display-Category=Infrastructure -OpenIDE-Module-Long-Description=\ - This is the core Autopsy module.\n\n\ - The module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\n\ - The framework included in the module contains APIs for developing modules for ingest, viewers and reporting. \ - The modules can be deployed as Plugins using the Autopsy plugin installer.\n\ - This module should not be uninstalled - without it, Autopsy will not run.\n\n\ - For more information, see http://www.sleuthkit.org/autopsy/ +OpenIDE-Module-Long-Description=This is the core Autopsy module.\n\nThe module contains the core components needed for the bare application to run; the RCP platform, windowing GUI, sleuthkit bindings, datamodel / storage, explorer, result viewers, content viewers, ingest framework, reporting, and core tools, such as the file search.\n\nThe framework included in the module contains APIs for developing modules for ingest, viewers and reporting. The modules can be deployed as Plugins using the Autopsy plugin installer.\nThis module should not be uninstalled - without it, Autopsy will not run.\n\nFor more information, see http://www.sleuthkit.org/autopsy/ OpenIDE-Module-Name=Autopsy-Core OpenIDE-Module-Short-Description=Autopsy Core Module org_sleuthkit_autopsy_core_update_center=http://sleuthkit.org/autopsy/updates.xml diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED index 9f363b7723..f252420726 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties-MERGED @@ -63,9 +63,9 @@ DataContentViewerHex.totalPageLabel.text_1=100 DataContentViewerHex.pageLabel2.text=Page # Product Information panel -LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
+LBL_Description=
\n Product Version: {0} ({9})
Sleuth Kit Version: {7}
Netbeans RCP Build: {8}
Java: {1}; {2}
System: {3}; {4}; {5}
Userdir: {6}
Format_OperatingSystem_Value={0} version {1} running on {2} -LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
+LBL_Copyright=
Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools.
Copyright © 2003-2018.
SortChooser.dialogTitle=Choose Sort Criteria ThumbnailViewChildren.progress.cancelling=(Cancelling) # {0} - file name @@ -95,7 +95,7 @@ DataResultViewerThumbnail.pageNextButton.text= DataResultViewerThumbnail.imagesLabel.text=Images: DataResultViewerThumbnail.imagesRangeLabel.text=- DataResultViewerThumbnail.pageNumLabel.text=- -DataResultViewerThumbnail.filePathLabel.text=\ \ \ +DataResultViewerThumbnail.filePathLabel.text=\ DataResultViewerThumbnail.goToPageLabel.text=Go to Page: DataResultViewerThumbnail.goToPageField.text= AdvancedConfigurationDialog.cancelButton.text=Cancel diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED index a0d535f8e6..18e279dd2c 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/coreutils/Bundle.properties-MERGED @@ -30,9 +30,7 @@ PlatformUtil.getProcVmUsed.sigarNotInit.msg=Cannot get virt mem used, sigar not PlatformUtil.getProcVmUsed.gen.msg=Cannot get virt mem used, {0} PlatformUtil.getJvmMemInfo.usageText=JVM heap usage: {0}, JVM non-heap usage: {1} PlatformUtil.getPhysicalMemInfo.usageText=Physical memory usage (max, total, free): {0}, {1}, {2} -PlatformUtil.getAllMemUsageInfo.usageText={0}\n\ -{1}\n\ -Process Virtual Memory: {2} +PlatformUtil.getAllMemUsageInfo.usageText={0}\n{1}\nProcess Virtual Memory: {2} # {0} - file name ReadImageTask.mesageText=Reading image: {0} StringExtract.illegalStateException.cannotInit.msg=Unicode table not properly initialized, cannot instantiate StringExtract diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index 0e732c1519..c585d0edf5 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -14,7 +14,7 @@ KnownStatusSearchPanel.knownCheckBox.text=Known Status: KnownStatusSearchPanel.knownBadOptionCheckBox.text=Notable KnownStatusSearchPanel.knownOptionCheckBox.text=Known (NSRL or other) KnownStatusSearchPanel.unknownOptionCheckBox.text=Unknown -DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected\! +DateSearchFilter.noneSelectedMsg.text=At least one date type must be selected! DateSearchPanel.dateCheckBox.text=Date: DateSearchPanel.jLabel4.text=Timezone: DateSearchPanel.jLabel3.text=*The date format is mm/dd/yyyy @@ -57,7 +57,7 @@ FileSearchPanel.search.results.details=Large number of matches may impact perfor FileSearchPanel.search.exception.noFilterSelected.msg=At least one filter must be selected. FileSearchPanel.search.validationErr.msg=Validation Error: {0} FileSearchPanel.emptyWhereClause.text=Invalid options, nothing to show. -KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected\! +KnownStatusSearchFilter.noneSelectedMsg.text=At least one known status must be selected! NameSearchFilter.emptyNameMsg.text=Must enter something for name search. SizeSearchPanel.sizeCompareComboBox.equalTo=equal to SizeSearchPanel.sizeCompareComboBox.greaterThan=greater than diff --git a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED index 9e4f612b6b..6be3e48e71 100755 --- a/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/ingest/Bundle.properties-MERGED @@ -140,7 +140,7 @@ IngestJob.cancelReason.outOfDiskSpace.text=Out of disk space IngestJob.cancelReason.servicesDown.text=Services Down IngestJob.cancelReason.caseClosed.text=Case closed IngestJobSettingsPanel.globalSettingsButton.text=Global Settings -gest +gest= IngestJobSettingsPanel.globalSettingsButton.actionCommand=Advanced IngestJobSettingsPanel.globalSettingsButton.text=Global Settings IngestJobSettingsPanel.pastJobsButton.text=History diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED index 4585d86449..4729293fb9 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/Bundle.properties-MERGED @@ -11,12 +11,7 @@ ExtractArchiveWithPasswordAction.progress.text=Unpacking contents of archive: {0 ExtractArchiveWithPasswordAction.prompt.text=Enter Password ExtractArchiveWithPasswordAction.prompt.title=Enter Password OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\n\ - Contents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\n\ - If the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\n\ - The extracted files are navigable in the directory tree.\n\n\ - The module is supported on Windows, Linux and Mac operating systems. +OpenIDE-Module-Long-Description=Embedded File Extraction Ingest Module\n\nThe Embedded File Extraction Ingest Module processes document files (such as doc, docx, ppt, pptx, xls, xlsx) and archive files (such as zip and others archive types supported by the 7zip extractor).\nContents of these files are extracted and the derived files are added back to the current ingest to be processed by the configured ingest modules.\nIf the derived file happens to be an archive file, it will be re-processed by the 7zip extractor - the extractor will process archive files N-levels deep.\n\nThe extracted files are navigable in the directory tree.\n\nThe module is supported on Windows, Linux and Mac operating systems. OpenIDE-Module-Name=Embedded File Extraction OpenIDE-Module-Short-Description=Embedded File Extraction Ingest Module EmbeddedFileExtractorIngestModule.SevenZipContentReadStream.seek.exception.invalidOrigin=Invalid seek origin: {0} @@ -28,6 +23,7 @@ EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnMsg=Possib EmbeddedFileExtractorIngestModule.ArchiveExtractor.isZipBombCheck.warnDetails=Compression ratio is {0}, skipping items in {1}. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnMsg.zipBomb=Possible ZIP bomb detected: {0} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.warnDetails.zipBomb=The archive is {0} levels deep, skipping processing of {1} +EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.unknownPath.msg=Unknown item path in archive: {0}, will use: {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.msg=Not enough disk space to unpack archive item: {0}, {1} EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.notEnoughDiskSpace.details=The archive item is too large to unpack, skipping unpacking this item. EmbeddedFileExtractorIngestModule.ArchiveExtractor.unpack.errUnpacking.msg=Error unpacking {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED index f9a5a88b1b..4915d5a124 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/exif/Bundle.properties-MERGED @@ -2,9 +2,7 @@ CannotRunFileTypeDetection=Cannot run file type detection. ExifParserFileIngestModule.indexError.message=Failed to post EXIF Metadata artifact(s). ExifParserFileIngestModule.userContent.description=EXIF metadata exists for this file. OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Exif metadata ingest module. \n\n\ - The ingest module analyzes image files, extracts Exif information and posts the Exif data as results. +OpenIDE-Module-Long-Description=Exif metadata ingest module. \n\nThe ingest module analyzes image files, extracts Exif information and posts the Exif data as results. OpenIDE-Module-Name=ExifParser OpenIDE-Module-Short-Description=Exif metadata ingest module ExifParserFileIngestModule.moduleName.text=Exif Parser diff --git a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED index cfaadf1635..5063bd55fa 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/fileextmismatch/Bundle.properties-MERGED @@ -36,27 +36,27 @@ FileExtMismatchSettingsPanel.jLabel1.text=File Types: FileExtMismatchSettingsPanel.newExtButton.text=New Extension FileExtMismatchSettingsPanel.newMimePrompt.message=Add a new MIME file type: FileExtMismatchSettingsPanel.newMimePrompt.title=New MIME -FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty\! +FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.message=MIME type text is empty! FileExtMismatchSettingsPanel.newMimePrompt.emptyMime.title=Empty type -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.message=MIME type not supported! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotSupported.title=Type not supported -FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists\! +FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.message=MIME type already exists! FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeExists.title=Type already exists FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.message=MIME type is not detectable by this module. FileExtMismatchSettingsPanel.newMimePrompt.mimeTypeNotDetectable.title=Type not detectable -FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeTypeButton.noneSelected.title=No type selected FileExtMismatchSettingsPanel.newExtPrompt.message=Add an allowed extension: FileExtMismatchSettingsPanel.newExtPrompt.title=New allowed extension -FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty\! +FileExtMismatchSettingsPanel.newExtPrompt.empty.message=Extension text is empty! FileExtMismatchSettingsPanel.newExtPrompt.empty.title=Extension text empty -FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected\! +FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.message=No MIME type selected! FileExtMismatchSettingsPanel.newExtPrompt.noMimeType.title=No MIME type selected -FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists\! +FileExtMismatchSettingsPanel.newExtPrompt.extExists.message=Extension already exists! FileExtMismatchSettingsPanel.newExtPrompt.extExists.title=Extension already exists -FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected\! +FileExtMismatchSettingsPanel.removeExtButton.noneSelected.message=No extension selected! FileExtMismatchSettingsPanel.removeExtButton.noneSelected.title=No extension selected -FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected\! +FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.message=No MIME type selected! FileExtMismatchSettingsPanel.removeExtButton.noMimeTypeSelected.title=No MIME type selected FileExtMismatchSettingsPanel.removeTypeButton.toolTipText= FileExtMismatchModuleSettingsPanel.checkAllRadioButton.text=Check all file types diff --git a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED index 0b470ce6b1..44057d0016 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/hashdatabase/Bundle.properties-MERGED @@ -49,10 +49,7 @@ ImportCentralRepoDbProgressDialog.errorParsingFile.message=Error parsing hash se ImportCentralRepoDbProgressDialog.linesProcessed.message=\ hashes processed ImportCentralRepoDbProgressDialog.title.text=Central Repository Import Progress OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=\ - Hash Set ingest module. \n\n\ - The ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\n\ - The module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. +OpenIDE-Module-Long-Description=Hash Set ingest module. \n\nThe ingest module analyzes files in the disk image and marks them as "known" (based on NSRL hashset lookup for "known" files) and "bad / interesting" (based on one or more hash sets supplied by the user).\n\nThe module also contains additional non-ingest tools that are integrated in the GUI, such as file lookup by hash and hash set configuration. OpenIDE-Module-Name=HashDatabases OptionsCategory_Name_HashDatabase=Hash Sets OptionsCategory_Keywords_HashDatabase=Hash Sets @@ -181,10 +178,7 @@ HashDbSearchThread.name.searching=Searching HashDbSearchThread.noMoreFilesWithMD5Msg=No other files with the same MD5 hash were found. ModalNoButtons.indexingDbsTitle=Indexing hash sets ModalNoButtons.indexingDbTitle=Indexing hash set -ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \n\ -The generated index will be left unusable. If you choose to continue,\n\ - please delete the corresponding -md5.idx file in the hash folder.\n\ - Exit indexing? +ModalNoButtons.exitHashDbIndexingMsg=You are about to exit out of indexing your hash sets. \nThe generated index will be left unusable. If you choose to continue,\nplease delete the corresponding -md5.idx file in the hash folder.\nExit indexing? ModalNoButtons.dlgTitle.unfinishedIndexing=Unfinished Indexing ModalNoButtons.indexThis.currentlyIndexing1Db=Currently indexing 1 hash set ModalNoButtons.indexThese.currentlyIndexing1OfNDbs=Currently indexing 1 of {0} diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED index 1279d3642b..31a0690b82 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties-MERGED @@ -83,8 +83,8 @@ FilesSetRulePanel.nameTextField.text= FilesSetRulePanel.ruleNameLabel.text=Rule Name (Optional): FilesSetRulePanel.messages.emptyNameCondition=You must specify a name pattern for this rule. FilesSetRulePanel.messages.invalidNameRegex=The name regular expression is not valid:\n\n{0} -FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, \", <, or > unless it is a regular expression. -FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, \", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInName=The name cannot contain \\, /, :, *, ?, ", <, or > unless it is a regular expression. +FilesSetRulePanel.messages.invalidCharInPath=The path cannot contain \\, :, *, ?, ", <, or > unless it is a regular expression. FilesSetRulePanel.messages.invalidPathRegex=The path regular expression is not valid:\n\n{0} FilesSetDefsPanel.doFileSetsDialog.duplicateRuleSet.text=Rule set with name {0} already exists. FilesSetRulePanel.pathSeparatorInfoLabel.text=Folder must be in parent path. Use '/' to give consecutive names diff --git a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED index 87dacfc16c..2dc971a40d 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/photoreccarver/Bundle.properties-MERGED @@ -21,7 +21,7 @@ PhotoRecIngestModule.complete.totalParsetime=Total Parsing Time: PhotoRecIngestModule.complete.photoRecResults=PhotoRec Results PhotoRecIngestModule.NotEnoughDiskSpace.detail.msg=PhotoRec error processing {0} with {1} Not enough space on primary disk to save unallocated space. PhotoRecIngestModule.cancelledByUser=PhotoRec cancelled by user. -PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value \= {0} when scanning {1} +PhotoRecIngestModule.error.exitValue=PhotoRec carver returned error exit value = {0} when scanning {1} PhotoRecIngestModule.error.msg=Error processing {0} with PhotoRec carver. PhotoRecIngestModule.complete.numberOfErrors=Number of Errors while Carving: PhotoRecCarverIngestJobSettingsPanel.detectionSettingsLabel.text=PhotoRec Settings diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED index 32f6867f0c..0be7595111 100755 --- a/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/report/modules/html/Bundle.properties-MERGED @@ -5,8 +5,8 @@ ReportHTML.getName.text=HTML Report ReportHTML.getDesc.text=A report about results and tagged items in HTML format. ReportHTML.writeIndex.title=for case {0} ReportHTML.writeIndex.noFrames.msg=Your browser is not compatible with our frame setup. -ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, -ReportHTML.writeIndex.seeSum=and the summary page for a case summary. +ReportHTML.writeIndex.noFrames.seeNav=Please see the navigation page for artifact links, +ReportHTML.writeIndex.seeSum=and the summary page for a case summary. ReportHTML.writeNav.title=Report Navigation ReportHTML.writeNav.h1=Report Navigation ReportHTML.writeNav.summary=Case Summary @@ -16,7 +16,7 @@ ReportHTML.writeSum.caseNumber=Case Number: ReportHTML.writeSum.caseNumImages=Number of Images: ReportHTML.writeSum.examiner=Examiner: ReportHTML.writeSum.title=Case Summary -ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed\! +ReportHTML.writeSum.warningMsg=Warning, this report was run before ingest services completed! # # autopsy/test/scripts/regression.py._html_report_diff() uses reportGenOn.text, caseName, caseNum, # examiner as a regex signature to skip report.html and summary.html diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED index ebdce8a327..18deff87f4 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED @@ -1,6 +1,7 @@ cannotBuildXmlParser=Unable to build XML parser: cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml: cannotParseXml=Unable to parse XML file: +Chrome.getBookmark.errMsg.errAnalyzeFile={0}: Error while trying to analyze file: {1} ChromeCacheExtract_adding_artifacts_msg=Chrome Cache: Adding %d artifacts for analysis. ChromeCacheExtract_adding_extracted_files_msg=Chrome Cache: Adding %d extracted files for analysis. ChromeCacheExtract_loading_files_msg=Chrome Cache: Loading files from %s. @@ -13,9 +14,9 @@ ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries DataSourceUsage_AndroidMedia=Android Media Card DataSourceUsage_DJU_Drone_DAT=DJI Internal SD Card DataSourceUsage_FlashDrive=Flash Drive -# {0} - OS name DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0}) DataSourceUsageAnalyzer.parentModuleName=Recent Activity +Extract.dbConn.errMsg.failedToQueryDb={0}: Failed to query database. Extract.indexError.message=Failed to index artifact for keyword search. Extract.noOpenCase.errMsg=No open case available. ExtractEdge_getHistory_containerFileNotFound=Error while trying to analyze Edge history @@ -24,6 +25,11 @@ ExtractEdge_process_errMsg_errGettingWebCacheFiles=Error trying to retrieving Ed ExtractEdge_process_errMsg_spartanFail=Failure processing Microsoft Edge spartan.edb file ExtractEdge_process_errMsg_unableFindESEViewer=Unable to find ESEDatabaseViewer ExtractEdge_process_errMsg_webcacheFail=Failure processing Microsoft Edge WebCacheV01.dat file +ExtractIE.getBookmark.ere.noSpace=RecentActivity +ExtractIE.getBookmark.errMsg.errPostingBookmarks=Error posting Internet Explorer Bookmark artifacts. +ExtractIE.getCookie.errMsg.errPostingCookies=Error posting Internet Explorer Cookie artifacts. +ExtractIE.getHistory.errMsg.errPostingHistory=Error posting Internet Explorer History artifacts. +Extractor.errPostingArtifacts=Error posting {0} artifacts to the blackboard. ExtractOs.androidOs.label=Android ExtractOs.androidVolume.label=OS Drive (Android) ExtractOs.debianLinuxOs.label=Linux (Debian) @@ -90,7 +96,7 @@ Chrome.getLogin.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file Chrome.getAutofill.errMsg.errGettingFiles=Error when trying to get Chrome Web Data files. Chrome.getAutofill.errMsg.errAnalyzingFiles={0}: Error while trying to analyze file:{1} ExtractIE.moduleName.text=Internet Explorer -ExtractIE.getBookmark.errMsg.errGettingBookmarks={0}: Error getting Internet Explorer Bookmarks. +ExtractIE.getBookmark.errMsg.errGettingBookmarks=Error getting Internet Explorer Bookmarks. ExtractIE.parentModuleName.noSpace=RecentActivity ExtractIE.parentModuleName=Recent Activity ExtractIE.getURLFromIEBmkFile.errMsg={0}: Error parsing IE bookmark File {1} @@ -192,7 +198,6 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity RecentDocumentsByLnk.parentModuleName=Recent Activity RegRipperFullNotFound=Full version RegRipper executable not found. RegRipperNotFound=Autopsy RegRipper executable not found. -# {0} - file name SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}. SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine SearchEngineURLQueryAnalyzer.engineName.none=NONE diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index 32871906e7..b20ccf5912 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Thu, 27 Feb 2020 08:01:10 -0500 +#Tue, 12 Nov 2019 17:21:46 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 @@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18 SplashRunningTextColor=0x0 SplashRunningTextFontSize=19 -currentVersion=Autopsy 4.14.0 +currentVersion=Autopsy 4.13.0 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 6c1cb1455b..998d3f715c 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Thu, 27 Feb 2020 08:01:10 -0500 -CTL_MainWindow_Title=Autopsy 4.14.0 -CTL_MainWindow_Title_No_Project=Autopsy 4.14.0 +#Tue, 12 Nov 2019 17:21:46 -0500 +CTL_MainWindow_Title=Autopsy 4.13.0 +CTL_MainWindow_Title_No_Project=Autopsy 4.13.0 From 9a27b155f89f809710355940c90917c60d605fa8 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Mon, 2 Mar 2020 13:12:52 -0500 Subject: [PATCH 31/36] 6013: Insert row in CR accounts table when accounts are created in Case database. --- .../datamodel/CRAccount.java | 136 ++++++++++++++ .../datamodel/CentralRepository.java | 27 ++- .../CorrelationAttributeInstance.java | 38 +++- .../CorrelationAttributeNormalizer.java | 23 ++- .../datamodel/CorrelationAttributeUtil.java | 35 +++- .../datamodel/RdbmsCentralRepo.java | 176 ++++++++++++++++-- 6 files changed, 410 insertions(+), 25 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java new file mode 100644 index 0000000000..97e3b93702 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java @@ -0,0 +1,136 @@ +/* + * Central Repository + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.datamodel; + +import org.sleuthkit.datamodel.Account; + + +/** + * This class abstracts an Account as stored in the CR database. + */ +public final class CRAccount { + + // primary key in the Accounts table in CR database + private final long account_id; + + private final CRAccountType crAccountType; + private final String typeSpecificID; + + /** + * A CRAccounType encapsulates an account type and the correlation type + * that it maps to. + */ + public static final class CRAccountType { + + // id is the primary key in the account_types table + private final int crAccountTypeID; + private final Account.Type acctType; + private final int correlationTypeID; + + CRAccountType(int acctTypeID, Account.Type acctType, int correlation_type_id) { + this.acctType = acctType; + this.correlationTypeID = correlation_type_id; + this.crAccountTypeID = acctTypeID; + } + + + /** + * @return the acctType + */ + public Account.Type getAcctType() { + return acctType; + } + + public int getCorrelationTypeId() { + return this.correlationTypeID; + } + + public int getCRAccountTypeId() { + return this.crAccountTypeID; + } + } + + public CRAccount(long account_id, CRAccountType accountType, String typeSpecificId) { + this.account_id = account_id; + this.crAccountType = accountType; + this.typeSpecificID = typeSpecificId; + } + + /** + * Gets unique identifier (assigned by a provider) for the account. Example + * includes an email address, a phone number, or a website username. + * + * @return type specific account id. + */ + public String getTypeSpecificID() { + return this.typeSpecificID; + } + + /** + * Gets the account type + * + * @return account type + */ + public CRAccountType getAccountType() { + return this.crAccountType; + } + + /** + * Gets the unique row id for this account in the database. + * + * @return unique row id. + */ + public long getAccountID() { + return this.account_id; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 43 * hash + (int) (this.account_id ^ (this.account_id >>> 32)); + hash = 43 * hash + (this.crAccountType != null ? this.crAccountType.hashCode() : 0); + hash = 43 * hash + (this.typeSpecificID != null ? this.typeSpecificID.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CRAccount other = (CRAccount) obj; + if (this.account_id != other.getAccountID()) { + return false; + } + if ((this.typeSpecificID == null) ? (other.getTypeSpecificID() != null) : !this.typeSpecificID.equals(other.getTypeSpecificID())) { + return false; + } + if (this.crAccountType != other.getAccountType() && (this.crAccountType == null || !this.crAccountType.equals(other.getAccountType()))) { + return false; + } + return true; + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index fe54161762..4fee5a0ddc 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; /** @@ -808,8 +809,32 @@ public interface CentralRepository { /** * Returns list of all correlation types. * - * @return list of Correlation types + * @return list of Correlation types * @throws CentralRepoException */ List getCorrelationTypes() throws CentralRepoException; + + + /** + * Get CR account type by type name. + * + * @param accountTypeName account type name to look for + * @return CR account type + * @throws CentralRepoException + */ + CRAccountType getCRAccountTypeByName(String accountTypeName) throws CentralRepoException; + + /** + * Get an account from the accounts table matching the given type/ID. + * Inserts a row if one doesn't exists. + * + * @param crAccountType CR account type to look for or create + * @param accountUniqueID type specific unique account id + * @return CR account + * + * @throws CentralRepoException + */ + CRAccount getOrCreateCRAccount(CRAccount.CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException; + + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 12fd9eac04..d5461f4554 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -50,6 +50,7 @@ public class CorrelationAttributeInstance implements Serializable { private String comment; private TskData.FileKnown knownStatus; private Long objectId; + private Long accountId; public CorrelationAttributeInstance( CorrelationAttributeInstance.Type correlationType, @@ -73,6 +74,20 @@ public class CorrelationAttributeInstance implements Serializable { String comment, TskData.FileKnown knownStatus, Long fileObjectId + ) throws CentralRepoException, CorrelationAttributeNormalizationException { + this(type, value, -1, eamCase, eamDataSource, filePath, comment, knownStatus, fileObjectId, (long)-1); + } + CorrelationAttributeInstance( + Type type, + String value, + int instanceId, + CorrelationCase eamCase, + CorrelationDataSource eamDataSource, + String filePath, + String comment, + TskData.FileKnown knownStatus, + Long fileObjectId, + Long accountId ) throws CentralRepoException, CorrelationAttributeNormalizationException { if (filePath == null) { throw new CentralRepoException("file path is null"); @@ -88,6 +103,7 @@ public class CorrelationAttributeInstance implements Serializable { this.comment = comment; this.knownStatus = knownStatus; this.objectId = fileObjectId; + this.accountId = accountId; } public Boolean equals(CorrelationAttributeInstance otherInstance) { @@ -98,7 +114,8 @@ public class CorrelationAttributeInstance implements Serializable { && (this.getCorrelationDataSource().equals(otherInstance.getCorrelationDataSource())) && (this.getFilePath().equals(otherInstance.getFilePath())) && (this.getKnownStatus().equals(otherInstance.getKnownStatus())) - && (this.getComment().equals(otherInstance.getComment()))); + && (this.getComment().equals(otherInstance.getComment())) + && (this.getAccountId().equals(otherInstance.getAccountId()))); } @Override @@ -106,6 +123,7 @@ public class CorrelationAttributeInstance implements Serializable { return this.getID() + this.getCorrelationCase().getCaseUUID() + this.getCorrelationDataSource().getDeviceID() + + this.getAccountId() + this.getFilePath() + this.getCorrelationType().toString() + this.getCorrelationValue() @@ -210,6 +228,24 @@ public class CorrelationAttributeInstance implements Serializable { return objectId; } + /** + * Get the accountId of the account associated with the correlation + * attribute. + * + * @return the accountId of the account + */ + public Long getAccountId() { + return accountId; + } + + /** + * Set the accountId of the account associated with this correlation + * attribute. + */ + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + // Type ID's for Default Correlation Types public static final int FILES_TYPE_ID = 0; public static final int DOMAIN_TYPE_ID = 1; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java index 4e5811a0c8..4154c579ca 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Optional; import org.apache.commons.validator.routines.DomainValidator; import org.apache.commons.validator.routines.EmailValidator; +import org.openide.util.Exceptions; /** * Provides functions for normalizing data by attribute type before insertion or @@ -76,11 +77,23 @@ final public class CorrelationAttributeNormalizer { return normalizeIccid(trimmedData); default: - final String errorMessage = String.format( - "Validator function not found for attribute type: %s", - attributeType.getDisplayName()); - throw new CorrelationAttributeNormalizationException(errorMessage); - } + try { + // If the atttribute is not one of the above + // but is one of the other default correlation types, then let the data go as is + List defaultCorrelationTypes = CorrelationAttributeInstance.getDefaultCorrelationTypes(); + for (CorrelationAttributeInstance.Type defaultCorrelationType : defaultCorrelationTypes) { + if (defaultCorrelationType.getId() == attributeType.getId()) { + return trimmedData; + } + } + final String errorMessage = String.format( + "Validator function not found for attribute type: %s", + attributeType.getDisplayName()); + throw new CorrelationAttributeNormalizationException(errorMessage); + } catch (CentralRepoException ex) { + throw new CorrelationAttributeNormalizationException(ex.getMessage()); + } + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 814169ef85..60af3dccaa 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -24,6 +24,7 @@ import java.util.logging.Level; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -222,6 +223,8 @@ public class CorrelationAttributeUtil { /** * Makes a correlation attribute instance for an account artifact. + * + * Also creates an account in the CR DB if it doesn't exist. * * IMPORTANT: The correlation attribute instance is NOT added to the central * repository by this method. @@ -239,13 +242,31 @@ public class CorrelationAttributeUtil { * * @return The correlation attribute instance. */ - private static void makeCorrAttrFromAcctArtifact(List corrAttrInstances, BlackboardArtifact acctArtifact) { - // RAMAN TODO: Convert TSK_ACCOUNT_TYPE attribute to correlation attribute type - // RAMAN TODO: Extract TSK_ID as value -// CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, corrAttrValue); -// if (corrAttr != null) { -// corrAttrInstances.add(corrAttr); -// } + private static void makeCorrAttrFromAcctArtifact(List corrAttrInstances, BlackboardArtifact acctArtifact) throws TskCoreException, CentralRepoException { + + // Get the account type from the artifact + BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); + String accountTypeStr = accountTypeAttribute.getValueString(); + + // Get the corresponding CRAccountType from the database. + CRAccountType crAccountType = CentralRepository.getInstance().getCRAccountTypeByName(accountTypeStr); + + int corrTypeId = crAccountType.getCorrelationTypeId(); + CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); + + // Get the account identifier + BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); + String accountIdStr = accountIdAttribute.getValueString(); + + // add/get the account and get its account_id. + CRAccount crAccount = CentralRepository.getInstance().getOrCreateCRAccount(crAccountType, accountIdStr); + + CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); + if (corrAttr != null) { + // set the account_id in correlation attribute + corrAttr.setAccountId(crAccount.getAccountID()); + corrAttrInstances.add(corrAttr); + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index abbae1c867..993f3350b2 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -41,12 +41,15 @@ import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil.updateSchemaVersion; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; import org.sleuthkit.autopsy.healthmonitor.TimingMetric; +import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.CaseDbSchemaVersionNumber; import org.sleuthkit.datamodel.TskData; @@ -71,6 +74,12 @@ abstract class RdbmsCentralRepo implements CentralRepository { private final Map> bulkArtifacts; private static final int CASE_CACHE_TIMEOUT = 5; private static final int DATA_SOURCE_CACHE_TIMEOUT = 5; + private static final int ACCOUNTS_CACHE_TIMEOUT = 5; + private static final Cache accountTypesCache = CacheBuilder.newBuilder().build(); + private static final Cache, CRAccount> accountsCache = CacheBuilder.newBuilder() + .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES). + build(); + private static final Cache typeCache = CacheBuilder.newBuilder().build(); private static final Cache caseCacheByUUID = CacheBuilder.newBuilder() .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). @@ -993,22 +1002,22 @@ abstract class RdbmsCentralRepo implements CentralRepository { public void addArtifactInstance(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { checkAddArtifactInstanceNulls(eamArtifact); - Connection conn = connect(); + - PreparedStatement preparedStatement = null; + // @@@ We should cache the case and data source IDs in memory String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); String sql = "INSERT INTO " + tableName - + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " - + "VALUES (?, ?, ?, ?, ?, ?, ?) " + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + getConflictClause(); - try { - preparedStatement = conn.prepareStatement(sql); - + try (Connection conn = connect(); + PreparedStatement preparedStatement = conn.prepareStatement(sql);) { + if (!eamArtifact.getCorrelationValue().isEmpty()) { preparedStatement.setInt(1, eamArtifact.getCorrelationCase().getID()); preparedStatement.setInt(2, eamArtifact.getCorrelationDataSource().getID()); @@ -1022,18 +1031,163 @@ abstract class RdbmsCentralRepo implements CentralRepository { preparedStatement.setString(6, eamArtifact.getComment()); } preparedStatement.setLong(7, eamArtifact.getFileObjectId()); + + if (eamArtifact.getAccountId() >= 0) { + preparedStatement.setLong(8, eamArtifact.getAccountId()); + } else { + preparedStatement.setNull(8, Types.INTEGER); + } preparedStatement.executeUpdate(); } } catch (SQLException ex) { throw new CentralRepoException("Error inserting new artifact into artifacts table.", ex); // NON-NLS - } finally { - CentralRepoDbUtil.closeStatement(preparedStatement); - CentralRepoDbUtil.closeConnection(conn); - } + } } + /** + * Gets the CR account for the given account type and account ID. + * Create a new account first, if one doesn't exist + * + * @param accountType account type + * @param accountUniqueID unique account identifier + * + * @return A matching account, either existing or newly created. + * + * @throws TskCoreException exception thrown if a critical error occurs + * within TSK core + */ + @Override + public CRAccount getOrCreateCRAccount(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + // Get the account fom the accounts table + CRAccount account = getCRAccount(crAccountType, accountUniqueID); + + // account not found in the table, create it + if (null == account) { + + String query = "INSERT INTO accounts (account_type_id, account_unique_identifier) " + + "VALUES ( " + crAccountType.getCRAccountTypeId() + ", '" + + accountUniqueID + "' )"; + + try (Connection connection = connect(); + Statement s = connection.createStatement();) { + + s.execute(query); + // get the account from the db - should exist now. + account = getCRAccount(crAccountType, accountUniqueID); + } catch (SQLException ex) { + throw new CentralRepoException("Error adding an account to CR database.", ex); + } + } + + return account; + } + + + @Override + public CRAccountType getCRAccountTypeByName(String accountTypeName) throws CentralRepoException { + try { + return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName)); + } catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) { + throw new CentralRepoException("Error looking up CR account type in cache.", ex); + } + } + + + /** + * Gets the CR account type for the specified type name. + * + * @param accountTypeName account type name to look for + * @return CR account type + * + * @throws CentralRepoException + */ + private CRAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException { + + String sql = "SELECT * FROM account_types WHERE type_name = ?"; + try ( Connection conn = connect(); + PreparedStatement preparedStatement = conn.prepareStatement(sql);) { + + preparedStatement.setString(1, accountTypeName); + try (ResultSet resultSet = preparedStatement.executeQuery();) { + if (resultSet.next()) { + Account.Type acctType = new Account.Type(accountTypeName, resultSet.getString("display_name")); + CRAccountType crAccountType = new CRAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id")); + accountTypesCache.put(accountTypeName, crAccountType); + return crAccountType; + } else { + throw new CentralRepoException("Failed to find entry for account type = " + accountTypeName); + } + } + } catch (SQLException ex) { + throw new CentralRepoException("Error getting correlation type by id.", ex); // NON-NLS + } + } + + /** + * Get the CR account with the given account type and the unique account identifier. + * Looks in the cache first. + * If not found in cache, reads from the database and saves in cache. + * + * Returns null if the account is not found in the cache and not in the database. + * + * @param crAccountType account type to look for + * @param accountUniqueID unique account id + * @return CRAccount for the give type/id. May return null if not found. + * + * @throws CentralRepoException + */ + private CRAccount getCRAccount(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + + CRAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID)); + if (crAccount == null) { + crAccount = getCRAccountFromDb(crAccountType, accountUniqueID); + if (crAccount != null) { + accountsCache.put(Pair.of(crAccountType, accountUniqueID), crAccount); + } + } + + return crAccount; + } + + + /** + * Get the Account with the given account type and account identifier, + * from the database. + * + * @param accountType account type + * @param accountUniqueID unique account identifier + * + * @return Account, returns NULL is no matching account found + * + * @throws TskCoreException exception thrown if a critical error occurs + * within TSK core + */ + private CRAccount getCRAccountFromDb(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + + CRAccount account = null; + + String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?"; + try ( Connection connection = connect(); + PreparedStatement preparedStatement = connection.prepareStatement(sql);) { + + preparedStatement.setInt(1, crAccountType.getCRAccountTypeId()); + preparedStatement.setString(2, accountUniqueID); + + try (ResultSet resultSet = preparedStatement.executeQuery();) { + if (resultSet.next()) { + account = new CRAccount(resultSet.getInt("id"), crAccountType, resultSet.getString("account_unique_identifier")); //NON-NLS + } + } + } catch (SQLException ex) { + throw new CentralRepoException("Error getting account type id", ex); + } + + return account; + } + + private void checkAddArtifactInstanceNulls(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { if (eamArtifact == null) { throw new CentralRepoException("CorrelationAttribute is null"); From 863f5f3f499f9e2b468298461c137e5b6d4f4285 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Mon, 2 Mar 2020 14:14:01 -0500 Subject: [PATCH 32/36] Address Codacy comments. --- .../datamodel/CorrelationAttributeNormalizer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java index 4154c579ca..f68dab484a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeNormalizer.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Optional; import org.apache.commons.validator.routines.DomainValidator; import org.apache.commons.validator.routines.EmailValidator; -import org.openide.util.Exceptions; /** * Provides functions for normalizing data by attribute type before insertion or @@ -91,7 +90,7 @@ final public class CorrelationAttributeNormalizer { attributeType.getDisplayName()); throw new CorrelationAttributeNormalizationException(errorMessage); } catch (CentralRepoException ex) { - throw new CorrelationAttributeNormalizationException(ex.getMessage()); + throw new CorrelationAttributeNormalizationException("Failed to get default correlation types.", ex); } } } From 54ea1f9265f323cf21f0ee0dfb940d913fbfee5b Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 3 Mar 2020 10:25:10 -0500 Subject: [PATCH 33/36] Addressed review comments. --- ...CRAccount.java => CentralRepoAccount.java} | 63 ++++++++++--------- .../datamodel/CentralRepository.java | 8 +-- .../CorrelationAttributeInstance.java | 2 +- .../datamodel/CorrelationAttributeUtil.java | 12 ++-- .../datamodel/RdbmsCentralRepo.java | 36 +++++------ 5 files changed, 61 insertions(+), 60 deletions(-) rename Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/{CRAccount.java => CentralRepoAccount.java} (54%) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoAccount.java similarity index 54% rename from Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java rename to Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoAccount.java index 97e3b93702..70d6f99e37 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CRAccount.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoAccount.java @@ -24,29 +24,30 @@ import org.sleuthkit.datamodel.Account; /** * This class abstracts an Account as stored in the CR database. */ -public final class CRAccount { +public final class CentralRepoAccount { // primary key in the Accounts table in CR database - private final long account_id; + private final long accountId; - private final CRAccountType crAccountType; - private final String typeSpecificID; + private final CentralRepoAccountType accountType; + // type specifc unique account id + private final String typeSpecificId; /** - * A CRAccounType encapsulates an account type and the correlation type + * Encapsulates a central repo account type and the correlation type * that it maps to. */ - public static final class CRAccountType { + public static final class CentralRepoAccountType { // id is the primary key in the account_types table - private final int crAccountTypeID; + private final int accountTypeId; private final Account.Type acctType; - private final int correlationTypeID; + private final int correlationTypeId; - CRAccountType(int acctTypeID, Account.Type acctType, int correlation_type_id) { + CentralRepoAccountType(int acctTypeID, Account.Type acctType, int correlationTypeId) { this.acctType = acctType; - this.correlationTypeID = correlation_type_id; - this.crAccountTypeID = acctTypeID; + this.correlationTypeId = correlationTypeId; + this.accountTypeId = acctTypeID; } @@ -58,18 +59,18 @@ public final class CRAccount { } public int getCorrelationTypeId() { - return this.correlationTypeID; + return this.correlationTypeId; } - public int getCRAccountTypeId() { - return this.crAccountTypeID; + public int getAccountTypeId() { + return this.accountTypeId; } } - public CRAccount(long account_id, CRAccountType accountType, String typeSpecificId) { - this.account_id = account_id; - this.crAccountType = accountType; - this.typeSpecificID = typeSpecificId; + public CentralRepoAccount(long accountId, CentralRepoAccountType accountType, String typeSpecificId) { + this.accountId = accountId; + this.accountType = accountType; + this.typeSpecificId = typeSpecificId; } /** @@ -78,8 +79,8 @@ public final class CRAccount { * * @return type specific account id. */ - public String getTypeSpecificID() { - return this.typeSpecificID; + public String getTypeSpecificId() { + return this.typeSpecificId; } /** @@ -87,8 +88,8 @@ public final class CRAccount { * * @return account type */ - public CRAccountType getAccountType() { - return this.crAccountType; + public CentralRepoAccountType getAccountType() { + return this.accountType; } /** @@ -96,16 +97,16 @@ public final class CRAccount { * * @return unique row id. */ - public long getAccountID() { - return this.account_id; + public long getAccountId() { + return this.accountId; } @Override public int hashCode() { int hash = 5; - hash = 43 * hash + (int) (this.account_id ^ (this.account_id >>> 32)); - hash = 43 * hash + (this.crAccountType != null ? this.crAccountType.hashCode() : 0); - hash = 43 * hash + (this.typeSpecificID != null ? this.typeSpecificID.hashCode() : 0); + hash = 43 * hash + (int) (this.accountId ^ (this.accountId >>> 32)); + hash = 43 * hash + (this.accountType != null ? this.accountType.hashCode() : 0); + hash = 43 * hash + (this.typeSpecificId != null ? this.typeSpecificId.hashCode() : 0); return hash; } @@ -120,14 +121,14 @@ public final class CRAccount { if (getClass() != obj.getClass()) { return false; } - final CRAccount other = (CRAccount) obj; - if (this.account_id != other.getAccountID()) { + final CentralRepoAccount other = (CentralRepoAccount) obj; + if (this.accountId != other.getAccountId()) { return false; } - if ((this.typeSpecificID == null) ? (other.getTypeSpecificID() != null) : !this.typeSpecificID.equals(other.getTypeSpecificID())) { + if ((this.typeSpecificId == null) ? (other.getTypeSpecificId() != null) : !this.typeSpecificId.equals(other.getTypeSpecificId())) { return false; } - if (this.crAccountType != other.getAccountType() && (this.crAccountType == null || !this.crAccountType.equals(other.getAccountType()))) { + if (this.accountType != other.getAccountType() && (this.accountType == null || !this.accountType.equals(other.getAccountType()))) { return false; } return true; diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 4fee5a0ddc..904712c73c 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Set; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import org.sleuthkit.autopsy.coordinationservice.CoordinationService; /** @@ -816,13 +816,13 @@ public interface CentralRepository { /** - * Get CR account type by type name. + * Get account type by type name. * * @param accountTypeName account type name to look for * @return CR account type * @throws CentralRepoException */ - CRAccountType getCRAccountTypeByName(String accountTypeName) throws CentralRepoException; + CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException; /** * Get an account from the accounts table matching the given type/ID. @@ -834,7 +834,7 @@ public interface CentralRepository { * * @throws CentralRepoException */ - CRAccount getOrCreateCRAccount(CRAccount.CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException; + CentralRepoAccount getOrCreateAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index d5461f4554..1ab978bc84 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -242,7 +242,7 @@ public class CorrelationAttributeInstance implements Serializable { * Set the accountId of the account associated with this correlation * attribute. */ - public void setAccountId(Long accountId) { + void setAccountId(Long accountId) { this.accountId = accountId; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 60af3dccaa..04aa6fc16e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -24,7 +24,7 @@ import java.util.logging.Level; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -248,8 +248,8 @@ public class CorrelationAttributeUtil { BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); - // Get the corresponding CRAccountType from the database. - CRAccountType crAccountType = CentralRepository.getInstance().getCRAccountTypeByName(accountTypeStr); + // Get the corresponding CentralRepoAccountType from the database. + CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); int corrTypeId = crAccountType.getCorrelationTypeId(); CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); @@ -258,13 +258,13 @@ public class CorrelationAttributeUtil { BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); String accountIdStr = accountIdAttribute.getValueString(); - // add/get the account and get its account_id. - CRAccount crAccount = CentralRepository.getInstance().getOrCreateCRAccount(crAccountType, accountIdStr); + // add/get the account and get its accountId. + CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); if (corrAttr != null) { // set the account_id in correlation attribute - corrAttr.setAccountId(crAccount.getAccountID()); + corrAttr.setAccountId(crAccount.getAccountId()); corrAttrInstances.add(corrAttr); } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 993f3350b2..93f6268979 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -44,7 +44,7 @@ import java.util.logging.Level; import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.centralrepository.datamodel.CRAccount.CRAccountType; +import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import static org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoDbUtil.updateSchemaVersion; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.healthmonitor.HealthMonitor; @@ -75,8 +75,8 @@ abstract class RdbmsCentralRepo implements CentralRepository { private static final int CASE_CACHE_TIMEOUT = 5; private static final int DATA_SOURCE_CACHE_TIMEOUT = 5; private static final int ACCOUNTS_CACHE_TIMEOUT = 5; - private static final Cache accountTypesCache = CacheBuilder.newBuilder().build(); - private static final Cache, CRAccount> accountsCache = CacheBuilder.newBuilder() + private static final Cache accountTypesCache = CacheBuilder.newBuilder().build(); + private static final Cache, CentralRepoAccount> accountsCache = CacheBuilder.newBuilder() .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); @@ -1047,7 +1047,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { } /** - * Gets the CR account for the given account type and account ID. + * Gets the Central Repo account for the given account type and account ID. * Create a new account first, if one doesn't exist * * @param accountType account type @@ -1059,15 +1059,15 @@ abstract class RdbmsCentralRepo implements CentralRepository { * within TSK core */ @Override - public CRAccount getOrCreateCRAccount(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + public CentralRepoAccount getOrCreateAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { // Get the account fom the accounts table - CRAccount account = getCRAccount(crAccountType, accountUniqueID); + CentralRepoAccount account = getAccount(crAccountType, accountUniqueID); // account not found in the table, create it if (null == account) { String query = "INSERT INTO accounts (account_type_id, account_unique_identifier) " - + "VALUES ( " + crAccountType.getCRAccountTypeId() + ", '" + + "VALUES ( " + crAccountType.getAccountTypeId() + ", '" + accountUniqueID + "' )"; try (Connection connection = connect(); @@ -1075,7 +1075,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { s.execute(query); // get the account from the db - should exist now. - account = getCRAccount(crAccountType, accountUniqueID); + account = getAccount(crAccountType, accountUniqueID); } catch (SQLException ex) { throw new CentralRepoException("Error adding an account to CR database.", ex); } @@ -1086,7 +1086,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { @Override - public CRAccountType getCRAccountTypeByName(String accountTypeName) throws CentralRepoException { + public CentralRepoAccountType getAccountTypeByName(String accountTypeName) throws CentralRepoException { try { return accountTypesCache.get(accountTypeName, () -> getCRAccountTypeFromDb(accountTypeName)); } catch (CacheLoader.InvalidCacheLoadException | ExecutionException ex) { @@ -1103,7 +1103,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { * * @throws CentralRepoException */ - private CRAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException { + private CentralRepoAccountType getCRAccountTypeFromDb(String accountTypeName) throws CentralRepoException { String sql = "SELECT * FROM account_types WHERE type_name = ?"; try ( Connection conn = connect(); @@ -1113,7 +1113,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { try (ResultSet resultSet = preparedStatement.executeQuery();) { if (resultSet.next()) { Account.Type acctType = new Account.Type(accountTypeName, resultSet.getString("display_name")); - CRAccountType crAccountType = new CRAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id")); + CentralRepoAccountType crAccountType = new CentralRepoAccountType(resultSet.getInt("id"), acctType, resultSet.getInt("correlation_type_id")); accountTypesCache.put(accountTypeName, crAccountType); return crAccountType; } else { @@ -1134,13 +1134,13 @@ abstract class RdbmsCentralRepo implements CentralRepository { * * @param crAccountType account type to look for * @param accountUniqueID unique account id - * @return CRAccount for the give type/id. May return null if not found. + * @return CentralRepoAccount for the give type/id. May return null if not found. * * @throws CentralRepoException */ - private CRAccount getCRAccount(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + private CentralRepoAccount getAccount(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { - CRAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID)); + CentralRepoAccount crAccount = accountsCache.getIfPresent(Pair.of(crAccountType, accountUniqueID)); if (crAccount == null) { crAccount = getCRAccountFromDb(crAccountType, accountUniqueID); if (crAccount != null) { @@ -1164,20 +1164,20 @@ abstract class RdbmsCentralRepo implements CentralRepository { * @throws TskCoreException exception thrown if a critical error occurs * within TSK core */ - private CRAccount getCRAccountFromDb(CRAccountType crAccountType, String accountUniqueID) throws CentralRepoException { + private CentralRepoAccount getCRAccountFromDb(CentralRepoAccountType crAccountType, String accountUniqueID) throws CentralRepoException { - CRAccount account = null; + CentralRepoAccount account = null; String sql = "SELECT * FROM accounts WHERE account_type_id = ? AND account_unique_identifier = ?"; try ( Connection connection = connect(); PreparedStatement preparedStatement = connection.prepareStatement(sql);) { - preparedStatement.setInt(1, crAccountType.getCRAccountTypeId()); + preparedStatement.setInt(1, crAccountType.getAccountTypeId()); preparedStatement.setString(2, accountUniqueID); try (ResultSet resultSet = preparedStatement.executeQuery();) { if (resultSet.next()) { - account = new CRAccount(resultSet.getInt("id"), crAccountType, resultSet.getString("account_unique_identifier")); //NON-NLS + account = new CentralRepoAccount(resultSet.getInt("id"), crAccountType, resultSet.getString("account_unique_identifier")); //NON-NLS } } } catch (SQLException ex) { From 08bd00734dadcd87b23d76fd1cc5a0ec29ca90fe Mon Sep 17 00:00:00 2001 From: Kelly Kelly Date: Wed, 4 Mar 2020 16:21:40 -0500 Subject: [PATCH 34/36] Updated based on review comments --- .../org/sleuthkit/autopsy/geolocation/datamodel/Route.java | 2 +- .../org/sleuthkit/autopsy/geolocation/datamodel/Track.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java index cda71c0e60..67de1e55ba 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Route.java @@ -43,7 +43,7 @@ public class Route extends GeoPath { // constructor will take care of creating an unmodifiable List private final List propertiesList; - private static final TskGeoWaypointsUtil attributeUtil = new TskGeoWaypointsUtil(""); + private static final TskGeoWaypointsUtil attributeUtil = new TskGeoWaypointsUtil(); /** * Construct a route for the given artifact. diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java index 3760c6f1eb..1a816179f6 100755 --- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java +++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/Track.java @@ -38,7 +38,7 @@ public final class Track extends GeoPath{ private final Long startTimestamp; private final Long endTimeStamp; - private static final TskGeoTrackpointsUtil attributeUtil = new TskGeoTrackpointsUtil(""); + private static final TskGeoTrackpointsUtil attributeUtil = new TskGeoTrackpointsUtil(); /** * Construct a new Track for the given artifact. @@ -204,7 +204,7 @@ public final class Track extends GeoPath{ list.add(new Property(Bundle.Track_distanceTraveled_displayName(), value.toString())); } - value = point.getDistanceFromHP(); + value = point.getDistanceFromHomePoint(); if (value != null) { list.add(new Property(Bundle.Track_distanceFromHome_displayName(), value.toString())); } From 82806cec8ea94f2e2bc0485dc95345bf65eec1b0 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 4 Mar 2020 17:48:59 -0500 Subject: [PATCH 35/36] Removed the disabled ios module from develop --- .../autopsy/modules/iOS/Bundle.properties | 5 - .../modules/iOS/Bundle.properties-MERGED | 8 - .../autopsy/modules/iOS/Bundle_ja.properties | 8 - .../autopsy/modules/iOS/CallLogAnalyzer.java | 192 -------------- .../autopsy/modules/iOS/ContactAnalyzer.java | 251 ------------------ .../modules/iOS/TextMessageAnalyzer.java | 198 -------------- .../autopsy/modules/iOS/iOSIngestModule.java | 50 ---- .../autopsy/modules/iOS/iOSModuleFactory.java | 59 ---- 8 files changed, 771 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties delete mode 100755 Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties-MERGED delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle_ja.properties delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/CallLogAnalyzer.java delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/ContactAnalyzer.java delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/TextMessageAnalyzer.java delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/iOSIngestModule.java delete mode 100644 Core/src/org/sleuthkit/autopsy/modules/iOS/iOSModuleFactory.java diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties deleted file mode 100644 index 8909d23e0e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties +++ /dev/null @@ -1,5 +0,0 @@ -iOSModuleFactory.moduleName=iOS Analyzer -iOSModuleFactory.moduleDescription=Extracts system and 3rd party app data -TextMessageAnalyzer.bbAttribute.incoming=Incoming -TextMessageAnalyzer.bbAttribute.outgoing=Outgoing -TextMessageAnalyzer.bbAttribute.smsMessage=SMS Message diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties-MERGED deleted file mode 100755 index 33c0a3ed08..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle.properties-MERGED +++ /dev/null @@ -1,8 +0,0 @@ -CallLogAnalyzer.indexError.message=Failed to index call log artifact for keyword search. -ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search. -iOSModuleFactory.moduleName=iOS Analyzer -iOSModuleFactory.moduleDescription=Extracts system and 3rd party app data -TextMessageAnalyzer.bbAttribute.incoming=Incoming -TextMessageAnalyzer.bbAttribute.outgoing=Outgoing -TextMessageAnalyzer.bbAttribute.smsMessage=SMS Message -TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search. diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle_ja.properties b/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle_ja.properties deleted file mode 100644 index 03cd3cc41e..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/Bundle_ja.properties +++ /dev/null @@ -1,8 +0,0 @@ -CallLogAnalyzer.indexError.message=\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u691c\u7d22\u3059\u308b\u305f\u3081\u306e\u3001\u901a\u8a71\u30ed\u30b0\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -ContactAnalyzer.indexError.message=\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u691c\u7d22\u3059\u308b\u305f\u3081\u306e\u3001\u9023\u7d61\u5148\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 -iOSModuleFactory.moduleName=iOS Analyzer -iOSModuleFactory.moduleDescription=\u30b7\u30b9\u30c6\u30e0\u3068\u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u88fd\u30a2\u30d7\u30ea\u30c7\u30fc\u30bf\u3092\u62bd\u51fa -TextMessageAnalyzer.bbAttribute.incoming=\u53d7\u4fe1 -TextMessageAnalyzer.bbAttribute.outgoing=\u9001\u4fe1 -TextMessageAnalyzer.bbAttribute.smsMessage=SMS\u30e1\u30c3\u30bb\u30fc\u30b8 -TextMessageAnalyzer.indexError.message=\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u691c\u7d22\u3059\u308b\u305f\u3081\u306e\u3001\u30c6\u30ad\u30b9\u30c8\u30e1\u30c3\u30bb\u30fc\u30b8\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3092\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002 diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/CallLogAnalyzer.java b/Core/src/org/sleuthkit/autopsy/modules/iOS/CallLogAnalyzer.java deleted file mode 100644 index 908673f466..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/CallLogAnalyzer.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2014-2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.modules.iOS; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.logging.Level; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.autopsy.datamodel.ContentUtils; -import org.sleuthkit.autopsy.ingest.IngestJobContext; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Blackboard; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Look for call logs and allow resulting blackboard artifacts to be generated. - */ -final class CallLogAnalyzer { - - private Connection connection = null; - private ResultSet resultSet = null; - private Statement statement = null; - private long fileId = 0; - private java.io.File jFile = null; - private final String moduleName = iOSModuleFactory.getModuleName(); - private static final Logger logger = Logger.getLogger(CallLogAnalyzer.class.getName()); - private Blackboard blackboard; - - /** - * Find call logs given an ingest job context and index the results. - * - * @param context The ingest job context. - */ - public void findCallLogs(IngestJobContext context) { - Case openCase; - try { - openCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - blackboard = openCase.getSleuthkitCase().getBlackboard(); - List absFiles; - try { - SleuthkitCase skCase = openCase.getSleuthkitCase(); - absFiles = skCase.findAllFilesWhere("name ='contacts2.db' OR name ='contacts.db'"); //NON-NLS //get exact file names - if (absFiles.isEmpty()) { - return; - } - for (AbstractFile file : absFiles) { - String dbPath = ""; - try { - jFile = new java.io.File(Case.getCurrentCaseThrows().getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", "")); - dbPath = jFile.toString(); //path of file as string - fileId = file.getId(); - ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled); - findCallLogsInDB(dbPath, fileId); - } catch (ReadContentInputStreamException ex) { - logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS - } catch (Exception ex) { - logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS - } - } - } catch (TskCoreException e) { - logger.log(Level.SEVERE, "Error finding Call logs", e); //NON-NLS - } - } - - /** - * Index results for call logs found in the database. - * - * @param DatabasePath The path to the database. - * @param fileId The ID of the file associated with artifacts. - */ - @Messages({"CallLogAnalyzer.indexError.message=Failed to index call log artifact for keyword search."}) - private void findCallLogsInDB(String DatabasePath, long fileId) { - if (DatabasePath == null || DatabasePath.isEmpty()) { - return; - } - try { - Class.forName("org.sqlite.JDBC"); //NON-NLS //load JDBC driver - connection = DriverManager.getConnection("jdbc:sqlite:" + DatabasePath); //NON-NLS - statement = connection.createStatement(); - } catch (ClassNotFoundException | SQLException e) { - logger.log(Level.SEVERE, "Error opening database", e); //NON-NLS - } - - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - SleuthkitCase skCase = currentCase.getSleuthkitCase(); - try { - AbstractFile file = skCase.getAbstractFileById(fileId); - if (file == null) { - logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS - return; - } - - try { - resultSet = statement.executeQuery( - "SELECT number,date,duration,type, name FROM calls ORDER BY date DESC;"); //NON-NLS - - BlackboardArtifact bba; - String name; // name of person dialed or called. null if unregistered - String number; //string phone number - String duration; //duration of call in seconds - String date; // Unix time - String type; // 1 incoming, 2 outgoing, 3 missed - - while (resultSet.next()) { - name = resultSet.getString("name"); //NON-NLS - number = resultSet.getString("number"); //NON-NLS - duration = resultSet.getString("duration"); //NON-NLS - date = resultSet.getString("date"); //NON-NLS - type = resultSet.getString("type"); //NON-NLS - - bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG); //create a call log and then add attributes from result set. - Collection attributes = new ArrayList<>(); - if (type.equalsIgnoreCase("outgoing")) { //NON-NLS - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, moduleName, number)); - } else { /// Covers INCOMING and MISSED - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, moduleName, number)); - } - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_START, moduleName, date)); // RC: Should be long! - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_END, moduleName, duration + date)); // RC: Should be long! - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, type)); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, moduleName, name)); - - bba.addAttributes(attributes); - try { - /* - * post the artifact which will index the artifact for - * keyword search, and fire an event to notify UI of - * this new artifact - */ - blackboard.postArtifact(bba, moduleName); - } catch (Blackboard.BlackboardException ex) { - logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS - MessageNotifyUtil.Notify.error( - Bundle.CallLogAnalyzer_indexError_message(), bba.getDisplayName()); - } - } - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing Call logs to the Blackboard", e); //NON-NLS - } finally { - try { - resultSet.close(); - statement.close(); - connection.close(); - } catch (Exception e) { - logger.log(Level.SEVERE, "Error closing the database", e); //NON-NLS - } - } - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing Call logs to the Blackboard", e); //NON-NLS - } - } -} diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/ContactAnalyzer.java b/Core/src/org/sleuthkit/autopsy/modules/iOS/ContactAnalyzer.java deleted file mode 100644 index cde321fab4..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/ContactAnalyzer.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2014-2019 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.modules.iOS; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.logging.Level; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.autopsy.datamodel.ContentUtils; -import org.sleuthkit.autopsy.ingest.IngestJobContext; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Blackboard; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.ReadContentInputStream; -import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Look for call logs and allow resulting blackboard artifacts to be generated. - */ -final class ContactAnalyzer { - - private Connection connection = null; - private String dbPath = ""; - private long fileId = 0; - private java.io.File jFile = null; - private final String moduleName = iOSModuleFactory.getModuleName(); - private static final Logger logger = Logger.getLogger(ContactAnalyzer.class.getName()); - private Blackboard blackboard; - - /** - * Find contacts given an ingest job context and index the results. - * - * @param context The ingest job context. - */ - public void findContacts(IngestJobContext context) { - Case openCase; - try { - openCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - - blackboard = openCase.getSleuthkitCase().getBlackboard(); - List absFiles; - try { - SleuthkitCase skCase = openCase.getSleuthkitCase(); - absFiles = skCase.findAllFilesWhere("LOWER(name) LIKE LOWER('%call_history%') "); //NON-NLS //get exact file names - if (absFiles.isEmpty()) { - return; - } - for (AbstractFile file : absFiles) { - try { - jFile = new java.io.File(openCase.getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", "")); - dbPath = jFile.toString(); //path of file as string - fileId = file.getId(); - ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled); - } catch (ReadContentInputStreamException ex) { - logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS - } catch (Exception ex) { - logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS - } - } - } catch (TskCoreException e) { - logger.log(Level.SEVERE, "Error finding Contacts", e); //NON-NLS - } - } - - /** - * Create blackboard artifacts and index results for call logs found in the - * database. - * - * @param DatabasePath The path to the database. - * @param fileId The ID of the file associated with artifacts. - */ - @Messages({"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."}) - private void findContactsInDB(String DatabasePath, long fileId) { - if (DatabasePath == null || DatabasePath.isEmpty()) { - return; - } - - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - - Statement statement = null; - try { - Class.forName("org.sqlite.JDBC"); //NON-NLS //load JDBC driver - connection = DriverManager.getConnection("jdbc:sqlite:" + DatabasePath); //NON-NLS - statement = connection.createStatement(); - } catch (ClassNotFoundException | SQLException e) { - logger.log(Level.SEVERE, "Error opening database", e); //NON-NLS - } - - SleuthkitCase skCase = currentCase.getSleuthkitCase(); - try { - AbstractFile file = skCase.getAbstractFileById(fileId); - if (file == null) { - logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS - return; - } - - ResultSet resultSet = null; - try { - // get display_name, mimetype(email or phone number) and data1 (phonenumber or email address depending on mimetype) - //sorted by name, so phonenumber/email would be consecutive for a person if they exist. - resultSet = statement.executeQuery( - "SELECT mimetype,data1, name_raw_contact.display_name AS display_name \n" //NON-NLS - + "FROM raw_contacts JOIN contacts ON (raw_contacts.contact_id=contacts._id) \n" //NON-NLS - + "JOIN raw_contacts AS name_raw_contact ON(name_raw_contact_id=name_raw_contact._id) " //NON-NLS - + "LEFT OUTER JOIN data ON (data.raw_contact_id=raw_contacts._id) \n" //NON-NLS - + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id=mimetypes._id) \n" //NON-NLS - + "WHERE mimetype = 'vnd.android.cursor.item/phone_v2' OR mimetype = 'vnd.android.cursor.item/email_v2'\n" //NON-NLS - + "ORDER BY name_raw_contact.display_name ASC;"); //NON-NLS - - BlackboardArtifact bba; - bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT); - Collection attributes = new ArrayList<>(); - String name; - String oldName = ""; - String mimetype; // either phone or email - String data1; // the phone number or email - while (resultSet.next()) { - name = resultSet.getString("display_name"); //NON-NLS - data1 = resultSet.getString("data1"); //NON-NLS - mimetype = resultSet.getString("mimetype"); //NON-NLS - if (name.equals(oldName) == false) { - bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT); - attributes = new ArrayList<>(); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, moduleName, name)); - } - if (mimetype.equals("vnd.android.cursor.item/phone_v2")) { //NON-NLS - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER, moduleName, data1)); - } else { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, moduleName, data1)); - } - - // TODO: If this code comes back to life, add code to create the account - // and relationship between the phone numbers & emails. Also - // investigate if the mimetype "vnd.android.cursor.item/phone_v2" - // makes sense in an ios word - - oldName = name; - - bba.addAttributes(attributes); - try { - // index the artifact for keyword search - blackboard.postArtifact(bba, moduleName); - } catch (Blackboard.BlackboardException ex) { - logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS - MessageNotifyUtil.Notify.error( - Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName()); - } - } - - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing Contacts to Blackboard", e); //NON-NLS - } finally { - try { - resultSet.close(); - statement.close(); - connection.close(); - } catch (Exception e) { - logger.log(Level.SEVERE, "Error closing database", e); //NON-NLS - } - } - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing Contacts to Blackboard", e); //NON-NLS - } - - } - - public static void copyFileUsingStream(AbstractFile file, File jFile) throws IOException { - InputStream is = new ReadContentInputStream(file); - OutputStream os = new FileOutputStream(jFile); - byte[] buffer = new byte[8192]; - int length; - try { - while ((length = is.read(buffer)) != -1) { - os.write(buffer, 0, length); - os.flush(); - - } - - } finally { - is.close(); - os.close(); - } - } - - public static void copyFileUsingStreams(AbstractFile file, File jFile) { - InputStream istream; - OutputStream ostream = null; - int c; - final int EOF = -1; - istream = new ReadContentInputStream(file); - try { - ostream = new FileOutputStream(jFile); - while ((c = istream.read()) != EOF) { - ostream.write(c); - } - } catch (IOException e) { - logger.log(Level.WARNING, "Error copying file", e); - } finally { - try { - istream.close(); - ostream.close(); - } catch (IOException e) { - logger.log(Level.WARNING, "File did not close", e); - } - } - } -} diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/TextMessageAnalyzer.java b/Core/src/org/sleuthkit/autopsy/modules/iOS/TextMessageAnalyzer.java deleted file mode 100644 index c541bf608a..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/TextMessageAnalyzer.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2014-2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.modules.iOS; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.logging.Level; -import org.openide.util.NbBundle; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; -import org.sleuthkit.autopsy.datamodel.ContentUtils; -import org.sleuthkit.autopsy.ingest.IngestJobContext; -import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.Blackboard; -import org.sleuthkit.datamodel.BlackboardArtifact; -import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.ReadContentInputStream; -import org.sleuthkit.datamodel.SleuthkitCase; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Look for text messages and allow resulting blackboard artifacts to be - * generated. - */ -class TextMessageAnalyzer { - - private Connection connection = null; - private ResultSet resultSet = null; - private Statement statement = null; - private String dbPath = ""; - private long fileId = 0; - private java.io.File jFile = null; - List absFiles; - private final String moduleName = iOSModuleFactory.getModuleName(); - private static final Logger logger = Logger.getLogger(TextMessageAnalyzer.class.getName()); - private Blackboard blackboard; - - /** - * Find text messages given an ingest job context and index the results. - * - * @param context The ingest job context. - */ - void findTexts(IngestJobContext context) { - Case openCase; - try { - openCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - blackboard = openCase.getSleuthkitCase().getBlackboard(); - try { - SleuthkitCase skCase = openCase.getSleuthkitCase(); - absFiles = skCase.findAllFilesWhere("name ='mmssms.db'"); //NON-NLS //get exact file name - if (absFiles.isEmpty()) { - return; - } - for (AbstractFile file : absFiles) { - try { - jFile = new java.io.File(Case.getCurrentCaseThrows().getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", "")); - dbPath = jFile.toString(); //path of file as string - fileId = file.getId(); - ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled); - findTextsInDB(dbPath, fileId); - } catch (ReadContentInputStream.ReadContentInputStreamException ex) { - logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS - } catch (Exception ex) { - logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS - } - } - } catch (TskCoreException e) { - logger.log(Level.SEVERE, "Error finding text messages", e); //NON-NLS - } - } - - /** - * Create blackboard artifacts and index results for text messages found in - * the database. - * - * @param DatabasePath The path to the database. - * @param fileId The ID of the file associated with artifacts. - */ - @Messages({"TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search."}) - private void findTextsInDB(String DatabasePath, long fileId) { - if (DatabasePath == null || DatabasePath.isEmpty()) { - return; - } - Case currentCase; - try { - currentCase = Case.getCurrentCaseThrows(); - } catch (NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS - return; - } - try { - Class.forName("org.sqlite.JDBC"); //NON-NLS //load JDBC driver - connection = DriverManager.getConnection("jdbc:sqlite:" + DatabasePath); //NON-NLS - statement = connection.createStatement(); - } catch (ClassNotFoundException | SQLException e) { - logger.log(Level.SEVERE, "Error opening database", e); //NON-NLS - } - - SleuthkitCase skCase = currentCase.getSleuthkitCase(); - try { - AbstractFile file = skCase.getAbstractFileById(fileId); - if (file == null) { - logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS - return; - } - - try { - resultSet = statement.executeQuery( - "SELECT address,date,type,subject,body FROM sms;"); //NON-NLS - - BlackboardArtifact bba; - String address; // may be phone number, or other addresses - String date;//unix time - String type; // message received in inbox = 1, message sent = 2 - String subject;//message subject - String body; //message body - while (resultSet.next()) { - address = resultSet.getString("address"); //NON-NLS - date = resultSet.getString("date"); //NON-NLS - type = resultSet.getString("type"); //NON-NLS - subject = resultSet.getString("subject"); //NON-NLS - body = resultSet.getString("body"); //NON-NLS - - bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE); //create Message artifact and then add attributes from result set. - Collection attributes = new ArrayList<>(); - // @@@ NEed to put into more specific TO or FROM - if (type.equals("1")) { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, NbBundle.getMessage(this.getClass(), "TextMessageAnalyzer.bbAttribute.incoming"))); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, moduleName, address)); - } else { - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, NbBundle.getMessage(this.getClass(), "TextMessageAnalyzer.bbAttribute.outgoing"))); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, moduleName, address)); - } - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, moduleName, date)); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION, moduleName, type)); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT, moduleName, subject)); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT, moduleName, body)); - attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE, moduleName, NbBundle.getMessage(this.getClass(), "TextMessageAnalyzer.bbAttribute.smsMessage"))); - - bba.addAttributes(attributes); - try { - /* - * post the artifact which will index the artifact for - * keyword search, and fire an event to notify UI of - * this new artifact - */ blackboard.postArtifact(bba, moduleName); - } catch (Blackboard.BlackboardException ex) { - logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS - MessageNotifyUtil.Notify.error( - Bundle.TextMessageAnalyzer_indexError_message(), bba.getDisplayName()); - } - } - - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing text messages to Blackboard", e); //NON-NLS - } finally { - try { - resultSet.close(); - statement.close(); - connection.close(); - } catch (Exception e) { - logger.log(Level.SEVERE, "Error closing database", e); //NON-NLS - } - } - } catch (Exception e) { - logger.log(Level.SEVERE, "Error parsing text messages to Blackboard", e); //NON-NLS - } - } -} diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSIngestModule.java deleted file mode 100644 index b0aacc9119..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSIngestModule.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2014 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.modules.iOS; - -import java.util.HashMap; -import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress; -import org.sleuthkit.autopsy.ingest.IngestModule; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; -import org.sleuthkit.autopsy.ingest.IngestJobContext; -import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter; -import org.sleuthkit.autopsy.ingest.IngestServices; - -class iOSIngestModule implements DataSourceIngestModule { - - private static final HashMap fileCountsForIngestJobs = new HashMap<>(); - private IngestJobContext context = null; - private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter(); - private static final Logger logger = Logger.getLogger(iOSModuleFactory.class.getName()); - private IngestServices services = IngestServices.getInstance(); - - @Override - public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException { - this.context = context; - } - - @Override - public IngestModule.ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) { - ContactAnalyzer FindContacts = new ContactAnalyzer(); - FindContacts.findContacts(context); - return IngestModule.ProcessResult.OK; - } -} diff --git a/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSModuleFactory.java b/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSModuleFactory.java deleted file mode 100644 index 942dca5379..0000000000 --- a/Core/src/org/sleuthkit/autopsy/modules/iOS/iOSModuleFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2014 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.modules.iOS; - -import org.openide.util.NbBundle; -import org.sleuthkit.autopsy.coreutils.Version; -import org.sleuthkit.autopsy.ingest.DataSourceIngestModule; -import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter; -import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings; - -//@ServiceProvider(service = IngestModuleFactory.class) // -public class iOSModuleFactory extends IngestModuleFactoryAdapter { - - static String getModuleName() { - return NbBundle.getMessage(iOSModuleFactory.class, "iOSModuleFactory.moduleName"); - } - - @Override - public String getModuleDisplayName() { - return getModuleName(); - } - - @Override - public String getModuleDescription() { - return NbBundle.getMessage(iOSModuleFactory.class, "iOSModuleFactory.moduleDescription"); - } - - @Override - public String getModuleVersionNumber() { - return Version.getVersion(); - } - - @Override - public boolean isDataSourceIngestModuleFactory() { - return true; - } - - @Override - public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings settings) { - return new iOSIngestModule(); - } - -} From 22fccaf14227f641142affc50440128b352f6e28 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Wed, 4 Mar 2020 18:59:20 -0500 Subject: [PATCH 36/36] Improve enable CR message --- .../autopsy/centralrepository/eventlisteners/Installer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 54a642b0dc..208f201a30 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -58,7 +58,7 @@ public class Installer extends ModuleInstall { @NbBundle.Messages({ "Installer.initialCreateSqlite.title=Enable Central Repository?", - "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to?", + "Installer.initialCreateSqlite.messageHeader=The Central Repository is not enabled. Would you like to enable it?", "Installer.initialCreateSqlite.messageDesc=It will store information about all hashes and identifiers that you process. " + "You can use this to ignore previously seen files and make connections between cases." })