Autopsy  4.13.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
WaypointBuilder.java
Go to the documentation of this file.
1 /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2019 Basis Technology Corp.
6  * contact: carrier <at> sleuthkit <dot> org
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 package org.sleuthkit.autopsy.geolocation.datamodel;
21 
22 import java.sql.ResultSet;
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.logging.Level;
28 import org.sleuthkit.datamodel.BlackboardArtifact;
29 import org.sleuthkit.datamodel.CaseDbAccessManager;
30 import org.sleuthkit.datamodel.BlackboardAttribute;
31 import org.sleuthkit.datamodel.SleuthkitCase;
32 import org.sleuthkit.datamodel.TskCoreException;
33 import org.sleuthkit.datamodel.DataSource;
34 
39 public final class WaypointBuilder {
40 
41  private static final Logger logger = Logger.getLogger(WaypointBuilder.class.getName());
42 
43  // SELECT statement for getting a list of waypoints.
44  final static String GEO_ARTIFACT_QUERY
45  = "SELECT artifact_id, artifact_type_id "
46  + "FROM blackboard_attributes "
47  + "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS
48 
49  // SELECT statement to get only artifact_ids
50  final static String GEO_ARTIFACT_QUERY_ID_ONLY
51  = "SELECT artifact_id "
52  + "FROM blackboard_attributes "
53  + "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS
54 
55  // This Query will return a list of waypoint artifacts
56  final static String GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY
57  = "SELECT blackboard_attributes.artifact_id "
58  + "FROM blackboard_attributes, blackboard_artifacts "
59  + "WHERE blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id "
60  + "AND blackboard_attributes.attribute_type_id IN(%d, %d) "
61  + "AND data_source_obj_id IN (%s)"; //NON-NLS
62 
63  // Select will return the "most recent" timestamp from all waypoings
64  final static String MOST_RECENT_TIME
65  = "SELECT MAX(value_int64) - (%d * 86400)" //86400 is the number of seconds in a day.
66  + "FROM blackboard_attributes "
67  + "WHERE attribute_type_id IN(%d, %d) "
68  + "AND artifact_id "
69  + "IN ( "
70  + "%s" //GEO_ARTIFACT with or without data source
71  + " )";
72 
73  // Returns a list of artifacts with no time stamp
74  final static String SELECT_WO_TIMESTAMP
75  = "SELECT DISTINCT artifact_id, artifact_type_id "
76  + "FROM blackboard_attributes "
77  + "WHERE artifact_id NOT IN (%s) "
78  + "AND artifact_id IN (%s)"; //NON-NLS
79 
83  public interface WaypointFilterQueryCallBack {
84 
90  void process(List<Waypoint> wwaypoints);
91  }
92 
96  private WaypointBuilder() {
97 
98  }
99 
113  public static List<Waypoint> getAllWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
114  List<Waypoint> points = new ArrayList<>();
115 
116  points.addAll(getTrackpointWaypoints(skCase));
117  points.addAll(getEXIFWaypoints(skCase));
118  points.addAll(getSearchWaypoints(skCase));
119  points.addAll(getLastKnownWaypoints(skCase));
120  points.addAll(getBookmarkWaypoints(skCase));
121 
122  return points;
123  }
124 
132  public static List<Route> getRoutes(List<Waypoint> waypoints) {
133  List<Route> routeList = new ArrayList<>();
134  for (Waypoint point : waypoints) {
135  Route route = point.getRoute();
136  if (route != null && !routeList.contains(route)) {
137  routeList.add(route);
138  }
139  }
140 
141  return routeList;
142  }
143 
153  public static List<Waypoint> getTrackpointWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
154  List<BlackboardArtifact> artifacts = null;
155  try {
156  artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT);
157  } catch (TskCoreException ex) {
158  throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_TRACKPOINT", ex);//NON-NLS
159  }
160 
161  List<Waypoint> points = new ArrayList<>();
162  for (BlackboardArtifact artifact : artifacts) {
163  try {
164  Waypoint point = new TrackpointWaypoint(artifact);
165  points.add(point);
166  } catch (GeoLocationDataException ex) {
167  logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_TRACKPOINT artifactID: %d", artifact.getArtifactID()));//NON-NLS
168  }
169  }
170  return points;
171  }
172 
180  public static List<Waypoint> getTrackpointWaypoints(List<Waypoint> waypoints) {
181  List<Waypoint> specificPoints = new ArrayList<>();
182 
183  for (Waypoint point : waypoints) {
184  if (point instanceof TrackpointWaypoint) {
185  specificPoints.add(point);
186  }
187  }
188 
189  return specificPoints;
190  }
191 
201  static public List<Waypoint> getEXIFWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
202  List<BlackboardArtifact> artifacts = null;
203  try {
204  artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
205  } catch (TskCoreException ex) {
206  throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);//NON-NLS
207  }
208 
209  List<Waypoint> points = new ArrayList<>();
210  if (artifacts != null) {
211  for (BlackboardArtifact artifact : artifacts) {
212  try {
213  Waypoint point = new EXIFWaypoint(artifact);
214  points.add(point);
215  } catch (GeoLocationDataException ex) {
216  // I am a little relucant to log this error because I suspect
217  // this will happen more often than not. It is valid for
218  // METADAT_EXIF to not have longitude and latitude
219  }
220  }
221  }
222  return points;
223  }
224 
232  public static List<Waypoint> getEXIFWaypoints(List<Waypoint> waypoints) {
233  List<Waypoint> specificPoints = new ArrayList<>();
234 
235  for (Waypoint point : waypoints) {
236  if (point instanceof EXIFWaypoint) {
237  specificPoints.add(point);
238  }
239  }
240 
241  return specificPoints;
242  }
243 
253  public static List<Waypoint> getSearchWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
254  List<BlackboardArtifact> artifacts = null;
255  try {
256  artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH);
257  } catch (TskCoreException ex) {
258  throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_SEARCH", ex);//NON-NLS
259  }
260 
261  List<Waypoint> points = new ArrayList<>();
262  if (artifacts != null) {
263  for (BlackboardArtifact artifact : artifacts) {
264  try {
265  Waypoint point = new SearchWaypoint(artifact);
266  points.add(point);
267  } catch (GeoLocationDataException ex) {
268  logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_SEARCH artifactID: %d", artifact.getArtifactID()));//NON-NLS
269  }
270  }
271  }
272  return points;
273  }
274 
282  public static List<Waypoint> getSearchWaypoints(List<Waypoint> waypoints) {
283  List<Waypoint> specificPoints = new ArrayList<>();
284 
285  for (Waypoint point : waypoints) {
286  if (point instanceof SearchWaypoint) {
287  specificPoints.add(point);
288  }
289  }
290 
291  return specificPoints;
292  }
293 
303  public static List<Waypoint> getLastKnownWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
304  List<BlackboardArtifact> artifacts = null;
305  try {
306  artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION);
307  } catch (TskCoreException ex) {
308  throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_LAST_KNOWN_LOCATION", ex);//NON-NLS
309  }
310 
311  List<Waypoint> points = new ArrayList<>();
312  if (artifacts != null) {
313  for (BlackboardArtifact artifact : artifacts) {
314  try {
315  Waypoint point = new LastKnownWaypoint(artifact);
316  points.add(point);
317  } catch (GeoLocationDataException ex) {
318  logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_LAST_KNOWN_LOCATION artifactID: %d", artifact.getArtifactID()));//NON-NLS
319  }
320  }
321  }
322  return points;
323  }
324 
333  public static List<Waypoint> getLastKnownWaypoints(List<Waypoint> waypoints) {
334  List<Waypoint> specificPoints = new ArrayList<>();
335 
336  for (Waypoint point : waypoints) {
337  if (point instanceof LastKnownWaypoint) {
338  specificPoints.add(point);
339  }
340  }
341 
342  return specificPoints;
343  }
344 
354  public static List<Waypoint> getBookmarkWaypoints(SleuthkitCase skCase) throws GeoLocationDataException {
355  List<BlackboardArtifact> artifacts = null;
356  try {
357  artifacts = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK);
358  } catch (TskCoreException ex) {
359  throw new GeoLocationDataException("Unable to get artifacts for type: TSK_GPS_BOOKMARK", ex);//NON-NLS
360  }
361 
362  List<Waypoint> points = new ArrayList<>();
363  if (artifacts != null) {
364  for (BlackboardArtifact artifact : artifacts) {
365  try {
366  Waypoint point = new BookmarkWaypoint(artifact);
367  points.add(point);
368  } catch (GeoLocationDataException ex) {
369  logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_BOOKMARK artifactID: %d", artifact.getArtifactID()), ex);//NON-NLS
370  }
371  }
372  }
373  return points;
374  }
375 
384  public static List<Waypoint> getBookmarkWaypoints(List<Waypoint> waypoints) {
385  List<Waypoint> specificPoints = new ArrayList<>();
386 
387  for (Waypoint point : waypoints) {
388  if (point instanceof BookmarkWaypoint) {
389  specificPoints.add(point);
390  }
391  }
392 
393  return specificPoints;
394  }
395 
426  static public void getAllWaypoints(SleuthkitCase skCase, List<DataSource> dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp, WaypointFilterQueryCallBack queryCallBack) throws GeoLocationDataException {
427  String query = buildQuery(dataSources, showAll, cntDaysFromRecent, noTimeStamp);
428 
429  logger.log(Level.INFO, query);
430 
431  try {
432  // The CaseDBAccessManager.select function will add a SELECT
433  // to the beginning of the query
434  if (query.startsWith("SELECT")) { //NON-NLS
435  query = query.replaceFirst("SELECT", ""); //NON-NLS
436  }
437 
438  skCase.getCaseDbAccessManager().select(query, new CaseDbAccessManager.CaseDbAccessQueryCallback() {
439  @Override
440  public void process(ResultSet rs) {
441  List<Waypoint> waypoints = new ArrayList<>();
442  try {
443  while (rs.next()) {
444  int artifact_type_id = rs.getInt("artifact_type_id"); //NON-NLS
445  long artifact_id = rs.getLong("artifact_id"); //NON-NLS
446 
447  BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact_type_id);
448 
449  waypoints.addAll(getWaypointForArtifact(skCase.getBlackboardArtifact(artifact_id), type));
450 
451  }
452  queryCallBack.process(waypoints);
453  } catch (GeoLocationDataException | SQLException | TskCoreException ex) {
454  logger.log(Level.WARNING, "Failed to filter waypoint.", ex); //NON-NLS
455  }
456 
457  }
458  });
459  } catch (TskCoreException ex) {
460  logger.log(Level.WARNING, "Failed to filter waypoint.", ex); //NON-NLS
461  }
462  }
463 
472  static private String buildQueryForWaypointsWOTimeStamps(List<DataSource> dataSources) {
473 
474 // SELECT_WO_TIMESTAMP
475 // SELECT DISTINCT artifact_id, artifact_type_id
476 // FROM blackboard_attributes
477 // WHERE artifact_id NOT IN (%s)
478 // AND artifact_id IN (%s)
479 
480 // GEO_ARTIFACT_QUERY_ID_ONLY
481 // SELECT artifact_id
482 // FROM blackboard_attributes
483 // WHERE attribute_type_id IN (%d, %d)
484 
485  return String.format(SELECT_WO_TIMESTAMP,
486  String.format(GEO_ARTIFACT_QUERY_ID_ONLY,
487  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
488  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID()),
489  getWaypointListQuery(dataSources));
490  }
491 
514  static private String buildQuery(List<DataSource> dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp) {
515  String mostRecentQuery = "";
516 
517  if (!showAll && cntDaysFromRecent > 0) {
518 // MOST_RECENT_TIME
519 // SELECT MAX(value_int64) - (%d * 86400)
520 // FROM blackboard_attributes
521 // WHERE attribute_type_id IN(%d, %d)
522 // AND artifact_id
523 // IN ( %s )
524 //
525  mostRecentQuery = String.format("AND value_int64 > (%s)", //NON-NLS
526  String.format(MOST_RECENT_TIME,
527  cntDaysFromRecent,
528  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
529  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID(),
530  getWaypointListQuery(dataSources)
531  ));
532  }
533 
534 // GEO_ARTIFACT_QUERY
535 // SELECT artifact_id, artifact_type_id
536 // FROM blackboard_attributes
537 // WHERE attribute_type_id IN (%d, %d)
538  String query = String.format(GEO_ARTIFACT_QUERY,
539  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
540  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED.getTypeID());
541 
542  // That are in the list of artifacts for the given data Sources
543  query += String.format("AND artifact_id IN(%s)", getWaypointListQuery(dataSources)); //NON-NLS
544  query += mostRecentQuery;
545 
546  if (showAll || noTimeStamp) {
547  query = String.format("%s UNION %s", buildQueryForWaypointsWOTimeStamps(dataSources), query); //NON-NLS
548  }
549 
550  return query;
551  }
552 
565  static private String getWaypointListQuery(List<DataSource> dataSources) {
566 
567  if (dataSources == null || dataSources.isEmpty()) {
568 // GEO_ARTIFACT_QUERY
569 // SELECT artifact_id, artifact_type_id
570 // FROM blackboard_attributes
571 // WHERE attribute_type_id IN (%d, %d)
572  return String.format(GEO_ARTIFACT_QUERY,
573  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(),
574  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID());
575  }
576 
577  String dataSourceList = "";
578  for (DataSource source : dataSources) {
579  dataSourceList += Long.toString(source.getId()) + ",";
580  }
581 
582  if (!dataSourceList.isEmpty()) {
583  // Remove the last ,
584  dataSourceList = dataSourceList.substring(0, dataSourceList.length() - 1);
585  }
586 
587  return String.format(GEO_ARTIFACT_WITH_DATA_SOURCES_QUERY,
588  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(),
589  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_START.getTypeID(),
590  dataSourceList);
591  }
592 
603  static private List<Waypoint> getWaypointForArtifact(BlackboardArtifact artifact, BlackboardArtifact.ARTIFACT_TYPE type) throws GeoLocationDataException {
604  List<Waypoint> waypoints = new ArrayList<>();
605  switch (type) {
606  case TSK_METADATA_EXIF:
607  waypoints.add(new EXIFWaypoint(artifact));
608  break;
609  case TSK_GPS_BOOKMARK:
610  waypoints.add(new BookmarkWaypoint(artifact));
611  break;
612  case TSK_GPS_TRACKPOINT:
613  waypoints.add(new TrackpointWaypoint(artifact));
614  break;
615  case TSK_GPS_SEARCH:
616  waypoints.add(new SearchWaypoint(artifact));
617  break;
618  case TSK_GPS_ROUTE:
619  Route route = new Route(artifact);
620  waypoints.addAll(route.getRoute());
621  break;
622  case TSK_GPS_LAST_KNOWN_LOCATION:
623  waypoints.add(new LastKnownWaypoint(artifact));
624  break;
625  default:
626  waypoints.add(new CustomArtifactWaypoint(artifact));
627  }
628 
629  return waypoints;
630  }
631 }
static List< Waypoint > getLastKnownWaypoints(List< Waypoint > waypoints)
static String buildQuery(List< DataSource > dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp)
static List< Waypoint > getBookmarkWaypoints(SleuthkitCase skCase)
static List< Waypoint > getBookmarkWaypoints(List< Waypoint > waypoints)
static void getAllWaypoints(SleuthkitCase skCase, List< DataSource > dataSources, boolean showAll, int cntDaysFromRecent, boolean noTimeStamp, WaypointFilterQueryCallBack queryCallBack)
static List< Waypoint > getSearchWaypoints(SleuthkitCase skCase)
static List< Waypoint > getSearchWaypoints(List< Waypoint > waypoints)
static List< Waypoint > getTrackpointWaypoints(SleuthkitCase skCase)
static List< Route > getRoutes(List< Waypoint > waypoints)
static List< Waypoint > getAllWaypoints(SleuthkitCase skCase)
static String getWaypointListQuery(List< DataSource > dataSources)
static List< Waypoint > getWaypointForArtifact(BlackboardArtifact artifact, BlackboardArtifact.ARTIFACT_TYPE type)
static List< Waypoint > getEXIFWaypoints(List< Waypoint > waypoints)
static List< Waypoint > getTrackpointWaypoints(List< Waypoint > waypoints)
static String buildQueryForWaypointsWOTimeStamps(List< DataSource > dataSources)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static List< Waypoint > getLastKnownWaypoints(SleuthkitCase skCase)
static List< Waypoint > getEXIFWaypoints(SleuthkitCase skCase)

Copyright © 2012-2019 Basis Technology. Generated on: Tue Jan 7 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.