Autopsy  4.9.1
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-2018 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.Objects;
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;
44 import org.sleuthkit.datamodel.Blackboard;
45 import org.sleuthkit.datamodel.BlackboardArtifact;
46 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
47 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
48 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO;
49 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT;
50 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
51 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
52 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
53 import org.sleuthkit.datamodel.SleuthkitCase;
54 import org.sleuthkit.datamodel.TskCoreException;
55 import org.sleuthkit.datamodel.TskException;
56 
61 public class ExtractedContent implements AutopsyVisitableItem {
62 
63  private SleuthkitCase skCase; // set to null after case has been closed
64  private Blackboard blackboard;
65  public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
66  private final long datasourceObjId;
67 
73  public ExtractedContent(SleuthkitCase skCase) {
74  this(skCase, 0);
75  }
76 
83  public ExtractedContent(SleuthkitCase skCase, long objId) {
84  this.skCase = skCase;
85  this.datasourceObjId = objId;
86  this.blackboard = skCase.getBlackboard();
87  }
88 
89  @Override
90  public <T> T accept(AutopsyItemVisitor<T> visitor) {
91  return visitor.visit(this);
92  }
93 
94  public SleuthkitCase getSleuthkitCase() {
95  return skCase;
96  }
97 
98  static String getIconFilePath(int typeID) {
99  String filePath = "org/sleuthkit/autopsy/images/"; //NON-NLS
100  if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
101  return filePath + "bookmarks.png"; //NON-NLS
102  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
103  return filePath + "cookies.png"; //NON-NLS
104  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
105  return filePath + "history.png"; //NON-NLS
106  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
107  return filePath + "downloads.png"; //NON-NLS
108  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
109  return filePath + "recent_docs.png"; //NON-NLS
110  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()) {
111  return filePath + "gps_trackpoint.png"; //NON-NLS
112  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
113  return filePath + "programs.png"; //NON-NLS
114  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
115  return filePath + "usb_devices.png"; //NON-NLS
116  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
117  return filePath + "mail-icon-16.png"; //NON-NLS
118  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXTRACTED_TEXT.getTypeID()) {
119  return filePath + "text-file.png"; //NON-NLS
120  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
121  return filePath + "searchquery.png"; //NON-NLS
122  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()) {
123  return filePath + "camera-icon-16.png"; //NON-NLS
124  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID()) {
125  return filePath + "computer.png"; //NON-NLS
126  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()) {
127  return filePath + "account-icon-16.png"; //NON-NLS
128  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
129  return filePath + "contact.png"; //NON-NLS
130  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
131  return filePath + "message.png"; //NON-NLS
132  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) {
133  return filePath + "calllog.png"; //NON-NLS
134  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID()) {
135  return filePath + "calendar.png"; //NON-NLS
136  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID()) {
137  return filePath + "speeddialentry.png"; //NON-NLS
138  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()) {
139  return filePath + "bluetooth.png"; //NON-NLS
140  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()) {
141  return filePath + "gpsfav.png"; //NON-NLS
142  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()) {
143  return filePath + "gps-lastlocation.png"; //NON-NLS
144  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID()) {
145  return filePath + "gps-search.png"; //NON-NLS
146  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID()) {
147  return filePath + "installed.png"; //NON-NLS
148  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() ||
149  typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID()) {
150  return filePath + "encrypted-file.png"; //NON-NLS
151  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) {
152  return filePath + "mismatch-16.png"; //NON-NLS
153  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) {
154  return filePath + "gps_trackpoint.png"; //NON-NLS
155  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID()) {
156  return filePath + "drive_network.png"; //NON-NLS
157  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED.getTypeID()) {
158  return filePath + "face.png"; //NON-NLS
159  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK.getTypeID()) {
160  return filePath + "network-wifi.png"; //NON-NLS
161  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WIFI_NETWORK_ADAPTER.getTypeID()) {
162  return filePath + "network-wifi.png"; //NON-NLS
163  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SIM_ATTACHED.getTypeID()) {
164  return filePath + "sim_card.png"; //NON-NLS
165  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_ADAPTER.getTypeID()) {
166  return filePath + "Bluetooth.png"; //NON-NLS
167  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_INFO.getTypeID()) {
168  return filePath + "devices.png"; //NON-NLS
169  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_VERIFICATION_FAILED.getTypeID()) {
170  return filePath + "validationFailed.png"; //NON-NLS
171  }
172  return filePath + "artifact-icon.png"; //NON-NLS
173  }
174 
175  public class RootNode extends DisplayableItemNode {
176 
177  public RootNode(SleuthkitCase skCase) {
178  super(Children.create(new TypeFactory(), true), Lookups.singleton(NAME));
179  super.setName(NAME);
180  super.setDisplayName(NAME);
181  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/extracted_content.png"); //NON-NLS
182  }
183 
184  @Override
185  public boolean isLeafTypeNode() {
186  return false;
187  }
188 
189  @Override
190  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
191  return visitor.visit(this);
192  }
193 
194  @Override
195  protected Sheet createSheet() {
196  Sheet sheet = super.createSheet();
197  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
198  if (sheetSet == null) {
199  sheetSet = Sheet.createPropertiesSet();
200  sheet.put(sheetSet);
201  }
202 
203  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.name"),
204  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.displayName"),
205  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.desc"),
206  NAME));
207  return sheet;
208  }
209 
210  @Override
211  public String getItemType() {
212  return getClass().getName();
213  }
214  }
215 
221  private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> {
222 
223  private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>();
224  // maps the artifact type to its child node
225  private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>();
226 
227  public TypeFactory() {
228  super();
229 
230  // these are shown in other parts of the UI tree
231  doNotShow.add(new BlackboardArtifact.Type(TSK_GEN_INFO));
232  doNotShow.add(new BlackboardArtifact.Type(TSK_EMAIL_MSG));
233  doNotShow.add(new BlackboardArtifact.Type(TSK_HASHSET_HIT));
234  doNotShow.add(new BlackboardArtifact.Type(TSK_KEYWORD_HIT));
235  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_FILE_HIT));
236  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
237  doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
238  }
239 
240  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
241  String eventType = evt.getPropertyName();
242  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
248  try {
255  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
256  if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
257  refresh(true);
258  }
259  } catch (NoCurrentCaseException notUsed) {
263  }
264  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
265  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
271  try {
273  refresh(true);
274  } catch (NoCurrentCaseException notUsed) {
278  }
279  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
280  // case was closed. Remove listeners so that we don't get called with a stale case handle
281  if (evt.getNewValue() == null) {
282  removeNotify();
283  skCase = null;
284  }
285  }
286  };
287 
288  @Override
289  protected void addNotify() {
293  }
294 
295  @Override
296  protected void removeNotify() {
300  typeNodeList.clear();
301  }
302 
303  @Override
304  protected boolean createKeys(List<BlackboardArtifact.Type> list) {
305  if (skCase != null) {
306  try {
307  List<BlackboardArtifact.Type> types = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
308  blackboard.getArtifactTypesInUse(datasourceObjId) :
309  skCase.getArtifactTypesInUse() ;
310 
311  types.removeAll(doNotShow);
312  Collections.sort(types,
313  new Comparator<BlackboardArtifact.Type>() {
314  @Override
315  public int compare(BlackboardArtifact.Type a, BlackboardArtifact.Type b) {
316  return a.getDisplayName().compareTo(b.getDisplayName());
317  }
318  });
319  list.addAll(types);
320 
321  // the create node method will get called only for new types
322  // refresh the counts if we already created them from a previous update
323  for (BlackboardArtifact.Type art : types) {
324  TypeNode node = typeNodeList.get(art);
325  if (node != null) {
326  node.updateDisplayName();
327  }
328  }
329  } catch (TskCoreException ex) {
330  Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
331  }
332  }
333  return true;
334  }
335 
336  @Override
337  protected Node createNodeForKey(BlackboardArtifact.Type key) {
338  TypeNode node = new TypeNode(key);
339  typeNodeList.put(key, node);
340  return node;
341  }
342  }
343 
350  public class TypeNode extends DisplayableItemNode {
351 
352  private final BlackboardArtifact.Type type;
353  private long childCount = 0;
354 
355  TypeNode(BlackboardArtifact.Type type) {
356  super(Children.create(new ArtifactFactory(type), true), Lookups.singleton(type.getDisplayName()));
357  super.setName(type.getTypeName());
358  this.type = type;
359  this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(type.getTypeID())); //NON-NLS
360  updateDisplayName();
361  }
362 
363  final void updateDisplayName() {
364  if (skCase == null) {
365  return;
366  }
367 
368  // NOTE: This completely destroys our lazy-loading ideal
369  // a performance increase might be had by adding a
370  // "getBlackboardArtifactCount()" method to skCase
371  try {
372  this.childCount = Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
373  blackboard.getArtifactsCount(type.getTypeID(), datasourceObjId) :
374  skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
375  } catch (TskException ex) {
376  Logger.getLogger(TypeNode.class.getName())
377  .log(Level.WARNING, "Error getting child count", ex); //NON-NLS
378  }
379  super.setDisplayName(type.getDisplayName() + " \u200E(\u200E" + childCount + ")\u200E");
380  }
381 
382  @Override
383  protected Sheet createSheet() {
384  Sheet sheet = super.createSheet();
385  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
386  if (sheetSet == null) {
387  sheetSet = Sheet.createPropertiesSet();
388  sheet.put(sheetSet);
389  }
390 
391  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.name"),
392  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.displayName"),
393  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.desc"),
394  type.getDisplayName()));
395 
396  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"),
397  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"),
398  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"),
399  childCount));
400 
401  return sheet;
402  }
403 
404  @Override
405  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
406  return visitor.visit(this);
407  }
408 
409  @Override
410  public boolean isLeafTypeNode() {
411  return true;
412  }
413 
414  @Override
415  public String getItemType() {
416  return getClass().getName() + type.getDisplayName();
417  }
418  }
419 
423  private class ArtifactFactory extends ChildFactory.Detachable<BlackboardArtifact> {
424 
425  private BlackboardArtifact.Type type;
426 
427  public ArtifactFactory(BlackboardArtifact.Type type) {
428  super();
429  this.type = type;
430  }
431 
432  private final PropertyChangeListener pcl = new PropertyChangeListener() {
433  @Override
434  public void propertyChange(PropertyChangeEvent evt) {
435  String eventType = evt.getPropertyName();
436  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
443  try {
451  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
452  if (null != event && event.getBlackboardArtifactType().equals(type)) {
453  refresh(true);
454  }
455  } catch (NoCurrentCaseException notUsed) {
459  }
460  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
461  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
468  try {
470  refresh(true);
471  } catch (NoCurrentCaseException notUsed) {
475  }
476  }
477  }
478  };
479 
480  @Override
481  protected void addNotify() {
484  }
485 
486  @Override
487  protected void removeNotify() {
490  }
491 
492  @Override
493  protected boolean createKeys(List<BlackboardArtifact> list) {
494  if (skCase != null) {
495  try {
496  List<BlackboardArtifact> arts =
497  Objects.equals(CasePreferences.getGroupItemsInTreeByDataSource(), true) ?
498  blackboard.getArtifacts(type.getTypeID(), datasourceObjId) :
499  skCase.getBlackboardArtifacts(type.getTypeID());
500  list.addAll(arts);
501  } catch (TskException ex) {
502  Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS
503  }
504  }
505  return true;
506  }
507 
508  @Override
509  protected Node createNodeForKey(BlackboardArtifact key) {
510  return new BlackboardArtifactNode(key);
511  }
512  }
513 }
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)
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:429
final HashMap< BlackboardArtifact.Type, TypeNode > typeNodeList
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:474

Copyright © 2012-2018 Basis Technology. Generated on: Tue Dec 18 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.