Autopsy  4.13.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractedContent.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.datamodel;
20 
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.EnumSet;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Set;
30 import java.util.logging.Level;
31 import org.openide.nodes.ChildFactory;
32 import org.openide.nodes.Children;
33 import org.openide.nodes.Node;
34 import org.openide.nodes.Sheet;
35 import org.openide.util.NbBundle;
36 import org.openide.util.lookup.Lookups;
42 import org.sleuthkit.datamodel.Blackboard;
43 import org.sleuthkit.datamodel.BlackboardArtifact;
44 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
45 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
46 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT;
47 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE;
48 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
49 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO;
50 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT;
51 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
52 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
53 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
54 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
55 import org.sleuthkit.datamodel.SleuthkitCase;
56 import org.sleuthkit.datamodel.TskCoreException;
57 
62 public class ExtractedContent implements AutopsyVisitableItem {
63 
66  public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
67  private final long filteringDSObjId; // 0 if not filtering/grouping by data source
68  private SleuthkitCase skCase; // set to null after case has been closed
69  private Blackboard blackboard;
70 
76  public ExtractedContent(SleuthkitCase skCase) {
77  this(skCase, 0);
78  }
79 
86  public ExtractedContent(SleuthkitCase skCase, long objId) {
87  this.skCase = skCase;
88  this.filteringDSObjId = objId;
89  this.blackboard = skCase.getBlackboard();
90  }
91 
92  @Override
93  public <T> T accept(AutopsyItemVisitor<T> visitor) {
94  return visitor.visit(this);
95  }
96 
97  public SleuthkitCase getSleuthkitCase() {
98  return skCase;
99  }
100 
101  static String getIconFilePath(int typeID) {
102  String filePath = "org/sleuthkit/autopsy/images/"; //NON-NLS
103  if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
104  return filePath + "bookmarks.png"; //NON-NLS
105  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
106  return filePath + "cookies.png"; //NON-NLS
107  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
108  return filePath + "history.png"; //NON-NLS
109  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
110  return filePath + "downloads.png"; //NON-NLS
111  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
112  return filePath + "recent_docs.png"; //NON-NLS
113  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()) {
114  return filePath + "gps_trackpoint.png"; //NON-NLS
115  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
116  return filePath + "programs.png"; //NON-NLS
117  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
118  return filePath + "usb_devices.png"; //NON-NLS
119  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
120  return filePath + "mail-icon-16.png"; //NON-NLS
121  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXTRACTED_TEXT.getTypeID()) {
122  return filePath + "text-file.png"; //NON-NLS
123  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
124  return filePath + "searchquery.png"; //NON-NLS
125  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()) {
126  return filePath + "camera-icon-16.png"; //NON-NLS
127  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID()) {
128  return filePath + "computer.png"; //NON-NLS
129  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()) {
130  return filePath + "account-icon-16.png"; //NON-NLS
131  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
132  return filePath + "contact.png"; //NON-NLS
133  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
134  return filePath + "message.png"; //NON-NLS
135  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) {
136  return filePath + "calllog.png"; //NON-NLS
137  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID()) {
138  return filePath + "calendar.png"; //NON-NLS
139  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID()) {
140  return filePath + "speeddialentry.png"; //NON-NLS
141  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()) {
142  return filePath + "bluetooth.png"; //NON-NLS
143  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()) {
144  return filePath + "gpsfav.png"; //NON-NLS
145  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()) {
146  return filePath + "gps-lastlocation.png"; //NON-NLS
147  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID()) {
148  return filePath + "gps-search.png"; //NON-NLS
149  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID()) {
150  return filePath + "installed.png"; //NON-NLS
151  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID()
152  || typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID()) {
153  return filePath + "encrypted-file.png"; //NON-NLS
154  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) {
155  return filePath + "mismatch-16.png"; //NON-NLS
156  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) {
157  return filePath + "gps_trackpoint.png"; //NON-NLS
158  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID()) {
159  return filePath + "drive_network.png"; //NON-NLS
160  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED.getTypeID()) {
161  return filePath + "face.png"; //NON-NLS
162  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) {
163  return filePath + "network-wifi.png"; //NON-NLS
164  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()) {
165  return filePath + "network-wifi.png"; //NON-NLS
166  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) {
167  return filePath + "sim_card.png"; //NON-NLS
168  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) {
169  return filePath + "Bluetooth.png"; //NON-NLS
170  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) {
171  return filePath + "devices.png"; //NON-NLS
172  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_VERIFICATION_FAILED.getTypeID()) {
173  return filePath + "validationFailed.png"; //NON-NLS
174  }
175  return filePath + "artifact-icon.png"; //NON-NLS
176  }
177 
178  public class RootNode extends DisplayableItemNode {
179 
180  public RootNode(SleuthkitCase skCase) {
181  super(Children.create(new TypeFactory(), true), Lookups.singleton(NAME));
182  super.setName(NAME);
183  super.setDisplayName(NAME);
184  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/extracted_content.png"); //NON-NLS
185  }
186 
187  @Override
188  public boolean isLeafTypeNode() {
189  return false;
190  }
191 
192  @Override
193  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
194  return visitor.visit(this);
195  }
196 
197  @Override
198  protected Sheet createSheet() {
199  Sheet sheet = super.createSheet();
200  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
201  if (sheetSet == null) {
202  sheetSet = Sheet.createPropertiesSet();
203  sheet.put(sheetSet);
204  }
205 
206  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.name"),
207  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.displayName"),
208  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.desc"),
209  NAME));
210  return sheet;
211  }
212 
213  @Override
214  public String getItemType() {
215  return getClass().getName();
216  }
217  }
218 
224  private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> {
225 
226  private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>();
227  // maps the artifact type to its child node
228  private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>();
229 
230  @SuppressWarnings("deprecation")
231  TypeFactory() {
232  super();
233 
234  // these are shown in other parts of the UI
235  doNotShow.add(new BlackboardArtifact.Type(TSK_GEN_INFO));
236  doNotShow.add(new BlackboardArtifact.Type(TSK_EMAIL_MSG));
237  doNotShow.add(new BlackboardArtifact.Type(TSK_HASHSET_HIT));
238  doNotShow.add(new BlackboardArtifact.Type(TSK_KEYWORD_HIT));
239  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_FILE_HIT));
240  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
241  doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
242  doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE));
243  doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE));
244  doNotShow.add(new BlackboardArtifact.Type(TSK_TL_EVENT));
245 
246  //This is not meant to be shown in the UI at all. It is more of a meta artifact.
247  doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT));
248  }
249 
250  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
251  String eventType = evt.getPropertyName();
252  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
258  try {
265  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
266  if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
267  refresh(true);
268  }
269  } catch (NoCurrentCaseException notUsed) {
273  }
274  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
275  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
281  try {
283  refresh(true);
284  } catch (NoCurrentCaseException notUsed) {
288  }
289  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
290  // case was closed. Remove listeners so that we don't get called with a stale case handle
291  if (evt.getNewValue() == null) {
292  removeNotify();
293  skCase = null;
294  }
295  }
296  };
297 
298  @Override
299  protected void addNotify() {
303  }
304 
305  @Override
306  protected void removeNotify() {
310  typeNodeList.clear();
311  }
312 
313  @Override
314  protected boolean createKeys(List<BlackboardArtifact.Type> list) {
315  if (skCase != null) {
316  try {
317  List<BlackboardArtifact.Type> types = (filteringDSObjId > 0)
318  ? blackboard.getArtifactTypesInUse(filteringDSObjId)
319  : skCase.getArtifactTypesInUse();
320 
321  types.removeAll(doNotShow);
322  Collections.sort(types,
323  new Comparator<BlackboardArtifact.Type>() {
324  @Override
325  public int compare(BlackboardArtifact.Type a, BlackboardArtifact.Type b) {
326  return a.getDisplayName().compareTo(b.getDisplayName());
327  }
328  });
329  list.addAll(types);
330 
331  // the create node method will get called only for new types
332  // refresh the counts if we already created them from a previous update
333  for (BlackboardArtifact.Type art : types) {
334  TypeNode node = typeNodeList.get(art);
335  if (node != null) {
336  node.updateDisplayName();
337  }
338  }
339  } catch (TskCoreException ex) {
340  Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
341  }
342  }
343  return true;
344  }
345 
346  @Override
347  protected Node createNodeForKey(BlackboardArtifact.Type key) {
348  TypeNode node = new TypeNode(key);
349  typeNodeList.put(key, node);
350  return node;
351  }
352  }
353 
360  public class TypeNode extends DisplayableItemNode {
361 
362  private final BlackboardArtifact.Type type;
363  private long childCount = 0;
364 
365  TypeNode(BlackboardArtifact.Type type) {
366  super(Children.create(new ArtifactFactory(type), true), Lookups.singleton(type.getDisplayName()));
367  super.setName(type.getTypeName());
368  this.type = type;
369  this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(type.getTypeID())); //NON-NLS
370  updateDisplayName();
371  }
372 
373  final void updateDisplayName() {
374  if (skCase == null) {
375  return;
376  }
377 
378  // NOTE: This completely destroys our lazy-loading ideal
379  // a performance increase might be had by adding a
380  // "getBlackboardArtifactCount()" method to skCase
381  try {
382  this.childCount = (filteringDSObjId > 0)
383  ? blackboard.getArtifactsCount(type.getTypeID(), filteringDSObjId)
384  : skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
385  } catch (TskCoreException ex) {
386  Logger.getLogger(TypeNode.class.getName())
387  .log(Level.WARNING, "Error getting child count", ex); //NON-NLS
388  }
389  super.setDisplayName(type.getDisplayName() + " \u200E(\u200E" + childCount + ")\u200E");
390  }
391 
392  @Override
393  protected Sheet createSheet() {
394  Sheet sheet = super.createSheet();
395  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
396  if (sheetSet == null) {
397  sheetSet = Sheet.createPropertiesSet();
398  sheet.put(sheetSet);
399  }
400 
401  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.name"),
402  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.displayName"),
403  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.desc"),
404  type.getDisplayName()));
405 
406  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"),
407  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"),
408  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"),
409  childCount));
410 
411  return sheet;
412  }
413 
414  @Override
415  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
416  return visitor.visit(this);
417  }
418 
419  @Override
420  public boolean isLeafTypeNode() {
421  return true;
422  }
423 
424  @Override
425  public String getItemType() {
426  return getClass().getName() + type.getDisplayName();
427  }
428  }
429 
433  private class ArtifactFactory extends BaseChildFactory<BlackboardArtifact> {
434 
435  private BlackboardArtifact.Type type;
436 
437  ArtifactFactory(BlackboardArtifact.Type type) {
438  super(type.getTypeName());
439  this.type = type;
440  }
441 
442  private final PropertyChangeListener pcl = new PropertyChangeListener() {
443  @Override
444  public void propertyChange(PropertyChangeEvent evt) {
445  String eventType = evt.getPropertyName();
446  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
453  try {
461  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
462  if (null != event && event.getBlackboardArtifactType().equals(type)) {
463  refresh(true);
464  }
465  } catch (NoCurrentCaseException notUsed) {
469  }
470  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
471  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
478  try {
480  refresh(true);
481  } catch (NoCurrentCaseException notUsed) {
485  }
486  }
487  }
488  };
489 
490  @Override
491  protected void onAdd() {
494  }
495 
496  @Override
497  protected void onRemove() {
500  }
501 
502  @Override
503  protected Node createNodeForKey(BlackboardArtifact key) {
504  return new BlackboardArtifactNode(key);
505  }
506 
507  @Override
508  protected List<BlackboardArtifact> makeKeys() {
509  if (skCase != null) {
510  try {
511  return (filteringDSObjId > 0)
512  ? blackboard.getArtifacts(type.getTypeID(), filteringDSObjId)
513  : skCase.getBlackboardArtifacts(type.getTypeID());
514  } catch (TskCoreException ex) {
515  Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS
516  }
517  }
518  return Collections.emptyList();
519  }
520  }
521 }
boolean createKeys(List< BlackboardArtifact.Type > list)
void removeIngestModuleEventListener(final PropertyChangeListener listener)
static synchronized IngestManager getInstance()
final ArrayList< BlackboardArtifact.Type > doNotShow
void removeIngestJobEventListener(final PropertyChangeListener listener)
static final Set< IngestManager.IngestModuleEvent > INGEST_MODULE_EVENTS_OF_INTEREST
void addIngestJobEventListener(final PropertyChangeListener listener)
ExtractedContent(SleuthkitCase skCase, long objId)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:486
final HashMap< BlackboardArtifact.Type, TypeNode > typeNodeList
static final Set< IngestManager.IngestJobEvent > INGEST_JOB_EVENTS_OF_INTEREST
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:531

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.