diff --git a/bindings/java/doxygen/artifact_catalog.dox b/bindings/java/doxygen/artifact_catalog.dox index 53ad511e8febc358dcec6ee5430605f0f92b02cc..820754976fec970f8a58702a22b3563d15bc2666 100644 --- a/bindings/java/doxygen/artifact_catalog.dox +++ b/bindings/java/doxygen/artifact_catalog.dox @@ -244,6 +244,18 @@ None ### OPTIONAL ATTRIBUTES - TSK_PHOTODNA_HASH (The PhotoDNA hash of an image) +--- +## TSK_GPS_AREA +An outline of an area. + +### REQUIRED ATTRIBUTES +- TSK_GEO_WAYPOINTS (JSON list of waypoints. Use org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints class to create/process) + +### OPTIONAL ATTRIBUTES +- TSK_LOCATION (Location of the route, e.g., a state or city) +- TSK_NAME (Name of the area, e.g., Minute Man Trail) +- TSK_PROG_NAME (Name of the application that was the source of the GPS route) + --- ## TSK_GPS_BOOKMARK A bookmarked GPS location or saved waypoint. diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java index 5e905c088a0f7e70c9b6edaf402901ec7a83fd76..354ba1742d779adcac4d9b4f02ee874cdbb81171 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java +++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java @@ -1260,7 +1260,12 @@ public enum ARTIFACT_TYPE implements SleuthkitVisitableItem { * Stores a role on a given domain. */ TSK_WEB_ACCOUNT_TYPE(59, "TSK_WEB_ACCOUNT_TYPE", - bundle.getString("BlackboardArtifact.tskWebAccountType.text")); + bundle.getString("BlackboardArtifact.tskWebAccountType.text")), + /** + * Stores the outline of an area using GPS coordinates. + */ + TSK_GPS_AREA(60, "TSK_GPS_AREA", + bundle.getString("BlackboardArtifact.tskGPSArea.text")); /* To developers: For each new artifact, ensure that: * - The enum value has 1-line JavaDoc description * - The artifact catalog (artifact_catalog.dox) is updated to reflect the attributes it uses diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java index 0e9d449e28ccab2b4ccd05c739a118ff2c6cf3aa..537f587c783a21e22bbef88b9d4ba45ae73062e4 100755 --- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java +++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java @@ -1416,7 +1416,13 @@ public enum ATTRIBUTE_TYPE { TSK_LAST_PRINTED_DATETIME(149, "TSK_LAST_PRINTED_DATETIME", bundle.getString("BlackboardAttribute.tsklastprinteddatetime.text"), TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME), - + /* + * Use org.sleuthkit.datamodel.blackboardutils.attributes.GeoAreaPoints to create and + * process TSK_GEO_AREAPOINTS attributes. + */ + TSK_GEO_AREAPOINTS(150, "TSK_GEO_AREAPOINTS", + bundle.getString("BlackboardAttribute.tskgeoareapoints.text"), + TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON), ; diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties index c3da2ea73394283627e42d91e29f5c069ecb2841..b57f4f91dc0f5fd14b30cb9148d9543f73a7cbf2 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties @@ -57,6 +57,7 @@ BlackboardArtifact.tskTrack.text=GPS Track BlackboardArtifact.tskWebAccountType.text=Web Account Type BlackboardArtifact.shortDescriptionDate.text=at {0} BlackboardArtifact.tskAssociatedObject.text=Associated Object +BlackboardArtifact.tskGPSArea.text=GPS Area BlackboardAttribute.tskAccountType.text=Account Type BlackboardAttribute.tskUrl.text=URL BlackboardAttribute.tskDatetime.text=Date/Time @@ -200,6 +201,7 @@ BlackboardAttribute.tskhashphotodna.text=PhotoDNA Hash BlackboardAttribute.tskbytessent.text=Bytes Sent BlackboardAttribute.tskbytesreceived.text=Bytes Received BlackboardAttribute.tsklastprinteddatetime.text=Last Printed Date +BlackboardAttribute.tskgeoareapoints.text=List of points making up the outline of an area AbstractFile.readLocal.exception.msg4.text=Error reading local file\: {0} AbstractFile.readLocal.exception.msg1.text=Error reading local file, local path is not set AbstractFile.readLocal.exception.msg2.text=Error reading local file, it does not exist at local path\: {0} diff --git a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED index c3da2ea73394283627e42d91e29f5c069ecb2841..b57f4f91dc0f5fd14b30cb9148d9543f73a7cbf2 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED +++ b/bindings/java/src/org/sleuthkit/datamodel/Bundle.properties-MERGED @@ -57,6 +57,7 @@ BlackboardArtifact.tskTrack.text=GPS Track BlackboardArtifact.tskWebAccountType.text=Web Account Type BlackboardArtifact.shortDescriptionDate.text=at {0} BlackboardArtifact.tskAssociatedObject.text=Associated Object +BlackboardArtifact.tskGPSArea.text=GPS Area BlackboardAttribute.tskAccountType.text=Account Type BlackboardAttribute.tskUrl.text=URL BlackboardAttribute.tskDatetime.text=Date/Time @@ -200,6 +201,7 @@ BlackboardAttribute.tskhashphotodna.text=PhotoDNA Hash BlackboardAttribute.tskbytessent.text=Bytes Sent BlackboardAttribute.tskbytesreceived.text=Bytes Received BlackboardAttribute.tsklastprinteddatetime.text=Last Printed Date +BlackboardAttribute.tskgeoareapoints.text=List of points making up the outline of an area AbstractFile.readLocal.exception.msg4.text=Error reading local file\: {0} AbstractFile.readLocal.exception.msg1.text=Error reading local file, local path is not set AbstractFile.readLocal.exception.msg2.text=Error reading local file, it does not exist at local path\: {0} diff --git a/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java index 52c433a6a04435ffc0765cc714460906b2a7ceb6..019c6becc0a48c0232ab2d296d80264832c8f3e6 100755 --- a/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java +++ b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/GeoArtifactsHelper.java @@ -29,6 +29,7 @@ import org.sleuthkit.datamodel.blackboardutils.attributes.BlackboardJsonAttrUtil; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoWaypoints; import org.sleuthkit.datamodel.blackboardutils.attributes.GeoTrackPoints; +import org.sleuthkit.datamodel.blackboardutils.attributes.GeoAreaPoints; /** * An artifact creation helper that adds geolocation artifacts to the case @@ -38,6 +39,7 @@ public final class GeoArtifactsHelper extends ArtifactHelperBase { private static final BlackboardAttribute.Type WAYPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_WAYPOINTS); private static final BlackboardAttribute.Type TRACKPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_TRACKPOINTS); + private static final BlackboardAttribute.Type AREAPOINTS_ATTR_TYPE = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_AREAPOINTS); private final String programName; /** @@ -168,5 +170,53 @@ public BlackboardArtifact addRoute(String routeName, Long creationTime, GeoWaypo return artifact; } + /** + * Adds a TSK_GPS_AREA artifact to the case database. A Global Positioning + * System (GPS) area artifact records an area on the map outlines by + * an ordered set of GPS coordinates. + * + * @param areaName The name of the GPS area, may be null. + * @param areaPoints The points that make up the outline of the area. This list + * should be non-null and non-empty. + * @param moreAttributes Additional attributes for the TSK_GPS_AREA + * artifact, may be null. + * + * @return The TSK_GPS_AREA artifact that was added to the case database. + * + * @throws TskCoreException If there is an error creating the + * artifact. + * @throws BlackboardException If there is a error posting the artifact + * to the blackboard. + * @throws IllegalArgumentException If the area points provided are null or + * empty. + */ + public BlackboardArtifact addArea(String areaName, GeoAreaPoints areaPoints, List<BlackboardAttribute> moreAttributes) throws TskCoreException, BlackboardException { + if (areaPoints == null || areaPoints.isEmpty()) { + throw new IllegalArgumentException(String.format("addArea was passed a null or empty list of points")); + } + + BlackboardArtifact artifact = getContent().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE); + List<BlackboardAttribute> attributes = new ArrayList<>(); + + attributes.add(BlackboardJsonAttrUtil.toAttribute(AREAPOINTS_ATTR_TYPE, getModuleName(), areaPoints)); + + if (areaName != null) { + attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, getModuleName(), areaName)); + } + + if (programName != null) { + attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getModuleName(), programName)); + } + + if (moreAttributes != null) { + attributes.addAll(moreAttributes); + } + + artifact.addAttributes(attributes); + + getSleuthkitCase().getBlackboard().postArtifact(artifact, getModuleName()); + + return artifact; + } } diff --git a/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/attributes/GeoAreaPoints.java b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/attributes/GeoAreaPoints.java new file mode 100644 index 0000000000000000000000000000000000000000..7707b4313e464cd31503e05864d0c5ec75c7d639 --- /dev/null +++ b/bindings/java/src/org/sleuthkit/datamodel/blackboardutils/attributes/GeoAreaPoints.java @@ -0,0 +1,123 @@ +/* + * Sleuth Kit Data Model + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier <at> sleuthkit <dot> 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.datamodel.blackboardutils.attributes; + +import com.google.gson.annotations.SerializedName; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * A GeoAreaPoints object is a collection of AreaPoint objects. + * Every AreaPoint is a location in a geographic coordinate + * system with latitude and longitude axes. + * + * GeoWaypoints objects are designed to be used as the string value of the + * TSK_GEO_AREAPOINTS attribute of a TSK_GPS_AREA artifact. TSK_GPS_AREA + * artifacts are used to record a series of locations used to outline an + * area on the map. + */ +public class GeoAreaPoints implements Iterable<GeoAreaPoints.AreaPoint> { + + private final List<AreaPoint> points; + + /** + * Constructs an empty GeoAreaPoints object. + */ + public GeoAreaPoints() { + points = new ArrayList<>(); + } + + /** + * Adds an area point to this list of points outlining the area. + * + * @param areaPoint A point. + */ + public void addPoint(AreaPoint areaPoint) { + if (areaPoint == null) { + throw new IllegalArgumentException("addPoint was passed a null waypoint"); + } + + points.add(areaPoint); + } + + /** + * Returns whether or not this list of area points is empty. + * + * @return True or false. + */ + public boolean isEmpty() { + return points.isEmpty(); + } + + @Override + public Iterator<AreaPoint> iterator() { + return points.iterator(); + } + + /** + * A representation of an area point, which is a a location in + * a geographic coordinate system with latitude and longitude axes. + * Area points are used to mark the outline of an area on the map. + */ + public static class AreaPoint { + + @SerializedName("TSK_GEO_LATITUDE") + private final Double latitude; + @SerializedName("TSK_GEO_LONGITUDE") + private final Double longitude; + + /** + * Constructs a representation of an area point. + * + * @param latitude The latitude of the area point. + * @param longitude The longitude of the area point. + */ + public AreaPoint(Double latitude, Double longitude) { + if (latitude == null) { + throw new IllegalArgumentException("Constructor was passed null latitude"); + } + + if (longitude == null) { + throw new IllegalArgumentException("Constructor was passed null longitude"); + } + + this.latitude = latitude; + this.longitude = longitude; + } + + /** + * Gets the latitude of this area point. + * + * @return The latitude. + */ + public Double getLatitude() { + return latitude; + } + + /** + * Gets the longitude of this area point. + * + * @return The longitude. + */ + public Double getLongitude() { + return longitude; + } + } +}