Autopsy  4.7.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-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.logging.Level;
30 import org.openide.nodes.ChildFactory;
31 import org.openide.nodes.Children;
32 import org.openide.nodes.Node;
33 import org.openide.nodes.Sheet;
34 import org.openide.util.NbBundle;
35 import org.openide.util.lookup.Lookups;
41 import org.sleuthkit.datamodel.BlackboardArtifact;
42 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT;
43 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG;
44 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO;
45 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT;
46 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT;
47 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT;
48 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT;
49 import org.sleuthkit.datamodel.SleuthkitCase;
50 import org.sleuthkit.datamodel.TskCoreException;
51 import org.sleuthkit.datamodel.TskException;
52 
57 public class ExtractedContent implements AutopsyVisitableItem {
58 
59  private SleuthkitCase skCase; // set to null after case has been closed
60  public static final String NAME = NbBundle.getMessage(RootNode.class, "ExtractedContentNode.name.text");
61 
62  public ExtractedContent(SleuthkitCase skCase) {
63  this.skCase = skCase;
64  }
65 
66  @Override
67  public <T> T accept(AutopsyItemVisitor<T> visitor) {
68  return visitor.visit(this);
69  }
70 
71  public SleuthkitCase getSleuthkitCase() {
72  return skCase;
73  }
74 
75  static String getIconFilePath(int typeID) {
76  String filePath = "org/sleuthkit/autopsy/images/"; //NON-NLS
77  if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
78  return filePath + "bookmarks.png"; //NON-NLS
79  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
80  return filePath + "cookies.png"; //NON-NLS
81  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
82  return filePath + "history.png"; //NON-NLS
83  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
84  return filePath + "downloads.png"; //NON-NLS
85  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
86  return filePath + "recent_docs.png"; //NON-NLS
87  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()) {
88  return filePath + "gps_trackpoint.png"; //NON-NLS
89  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
90  return filePath + "programs.png"; //NON-NLS
91  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
92  return filePath + "usb_devices.png"; //NON-NLS
93  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
94  return filePath + "mail-icon-16.png"; //NON-NLS
95  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXTRACTED_TEXT.getTypeID()) {
96  return filePath + "text-file.png"; //NON-NLS
97  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
98  return filePath + "searchquery.png"; //NON-NLS
99  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()) {
100  return filePath + "camera-icon-16.png"; //NON-NLS
101  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_OS_INFO.getTypeID()) {
102  return filePath + "computer.png"; //NON-NLS
103  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SERVICE_ACCOUNT.getTypeID()) {
104  return filePath + "account-icon-16.png"; //NON-NLS
105  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID()) {
106  return filePath + "contact.png"; //NON-NLS
107  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) {
108  return filePath + "message.png"; //NON-NLS
109  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID()) {
110  return filePath + "calllog.png"; //NON-NLS
111  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALENDAR_ENTRY.getTypeID()) {
112  return filePath + "calendar.png"; //NON-NLS
113  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_SPEED_DIAL_ENTRY.getTypeID()) {
114  return filePath + "speeddialentry.png"; //NON-NLS
115  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_BLUETOOTH_PAIRING.getTypeID()) {
116  return filePath + "bluetooth.png"; //NON-NLS
117  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK.getTypeID()) {
118  return filePath + "gpsfav.png"; //NON-NLS
119  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_LAST_KNOWN_LOCATION.getTypeID()) {
120  return filePath + "gps-lastlocation.png"; //NON-NLS
121  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_SEARCH.getTypeID()) {
122  return filePath + "gps-search.png"; //NON-NLS
123  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID()) {
124  return filePath + "installed.png"; //NON-NLS
125  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() ||
126  typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID()) {
127  return filePath + "encrypted-file.png"; //NON-NLS
128  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) {
129  return filePath + "mismatch-16.png"; //NON-NLS
130  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) {
131  return filePath + "gps_trackpoint.png"; //NON-NLS
132  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID()) {
133  return filePath + "drive_network.png"; //NON-NLS
134  } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED.getTypeID()) {
135  return filePath + "face.png"; //NON-NLS
136  }
137  return filePath + "artifact-icon.png"; //NON-NLS
138  }
139 
140  public class RootNode extends DisplayableItemNode {
141 
142  public RootNode(SleuthkitCase skCase) {
143  super(Children.create(new TypeFactory(), true), Lookups.singleton(NAME));
144  super.setName(NAME);
145  super.setDisplayName(NAME);
146  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/extracted_content.png"); //NON-NLS
147  }
148 
149  @Override
150  public boolean isLeafTypeNode() {
151  return false;
152  }
153 
154  @Override
155  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
156  return visitor.visit(this);
157  }
158 
159  @Override
160  protected Sheet createSheet() {
161  Sheet sheet = super.createSheet();
162  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
163  if (sheetSet == null) {
164  sheetSet = Sheet.createPropertiesSet();
165  sheet.put(sheetSet);
166  }
167 
168  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.name"),
169  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.displayName"),
170  NbBundle.getMessage(this.getClass(), "ExtractedContentNode.createSheet.name.desc"),
171  NAME));
172  return sheet;
173  }
174 
175  @Override
176  public String getItemType() {
177  return getClass().getName();
178  }
179  }
180 
186  private class TypeFactory extends ChildFactory.Detachable<BlackboardArtifact.Type> {
187 
188  private final ArrayList<BlackboardArtifact.Type> doNotShow = new ArrayList<>();
189  // maps the artifact type to its child node
190  private final HashMap<BlackboardArtifact.Type, TypeNode> typeNodeList = new HashMap<>();
191 
192  public TypeFactory() {
193  super();
194 
195  // these are shown in other parts of the UI tree
196  doNotShow.add(new BlackboardArtifact.Type(TSK_GEN_INFO));
197  doNotShow.add(new BlackboardArtifact.Type(TSK_EMAIL_MSG));
198  doNotShow.add(new BlackboardArtifact.Type(TSK_HASHSET_HIT));
199  doNotShow.add(new BlackboardArtifact.Type(TSK_KEYWORD_HIT));
200  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_FILE_HIT));
201  doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
202  doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
203  }
204 
205  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
206  String eventType = evt.getPropertyName();
207  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
213  try {
220  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
221  if (null != event && !(this.doNotShow.contains(event.getBlackboardArtifactType()))) {
222  refresh(true);
223  }
224  } catch (NoCurrentCaseException notUsed) {
228  }
229  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
230  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
236  try {
238  refresh(true);
239  } catch (NoCurrentCaseException notUsed) {
243  }
244  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
245  // case was closed. Remove listeners so that we don't get called with a stale case handle
246  if (evt.getNewValue() == null) {
247  removeNotify();
248  skCase = null;
249  }
250  }
251  };
252 
253  @Override
254  protected void addNotify() {
258  }
259 
260  @Override
261  protected void removeNotify() {
265  typeNodeList.clear();
266  }
267 
268  @Override
269  protected boolean createKeys(List<BlackboardArtifact.Type> list) {
270  //TEST COMMENT
271  if (skCase != null) {
272  try {
273  List<BlackboardArtifact.Type> types = skCase.getArtifactTypesInUse();
274  types.removeAll(doNotShow);
275  Collections.sort(types,
276  new Comparator<BlackboardArtifact.Type>() {
277  @Override
278  public int compare(BlackboardArtifact.Type a, BlackboardArtifact.Type b) {
279  return a.getDisplayName().compareTo(b.getDisplayName());
280  }
281  });
282  list.addAll(types);
283 
284  // the create node method will get called only for new types
285  // refresh the counts if we already created them from a previous update
286  for (BlackboardArtifact.Type art : types) {
287  TypeNode node = typeNodeList.get(art);
288  if (node != null) {
289  node.updateDisplayName();
290  }
291  }
292  } catch (TskCoreException ex) {
293  Logger.getLogger(TypeFactory.class.getName()).log(Level.SEVERE, "Error getting list of artifacts in use: " + ex.getLocalizedMessage()); //NON-NLS
294  }
295  }
296  return true;
297  }
298 
299  @Override
300  protected Node createNodeForKey(BlackboardArtifact.Type key) {
301  TypeNode node = new TypeNode(key);
302  typeNodeList.put(key, node);
303  return node;
304  }
305  }
306 
313  public class TypeNode extends DisplayableItemNode {
314 
315  private final BlackboardArtifact.Type type;
316  private long childCount = 0;
317 
318  TypeNode(BlackboardArtifact.Type type) {
319  super(Children.create(new ArtifactFactory(type), true), Lookups.singleton(type.getDisplayName()));
320  super.setName(type.getTypeName());
321  this.type = type;
322  this.setIconBaseWithExtension(ExtractedContent.getIconFilePath(type.getTypeID())); //NON-NLS
323  updateDisplayName();
324  }
325 
326  final void updateDisplayName() {
327  if (skCase == null) {
328  return;
329  }
330 
331  // NOTE: This completely destroys our lazy-loading ideal
332  // a performance increase might be had by adding a
333  // "getBlackboardArtifactCount()" method to skCase
334  try {
335  this.childCount = skCase.getBlackboardArtifactsTypeCount(type.getTypeID());
336  } catch (TskException ex) {
337  Logger.getLogger(TypeNode.class.getName())
338  .log(Level.WARNING, "Error getting child count", ex); //NON-NLS
339  }
340  super.setDisplayName(type.getDisplayName() + " \u200E(\u200E" + childCount + ")\u200E");
341  }
342 
343  @Override
344  protected Sheet createSheet() {
345  Sheet sheet = super.createSheet();
346  Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
347  if (sheetSet == null) {
348  sheetSet = Sheet.createPropertiesSet();
349  sheet.put(sheetSet);
350  }
351 
352  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.name"),
353  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.displayName"),
354  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.artType.desc"),
355  type.getDisplayName()));
356 
357  sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.name"),
358  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.displayName"),
359  NbBundle.getMessage(this.getClass(), "ArtifactTypeNode.createSheet.childCnt.desc"),
360  childCount));
361 
362  return sheet;
363  }
364 
365  @Override
366  public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
367  return visitor.visit(this);
368  }
369 
370  @Override
371  public boolean isLeafTypeNode() {
372  return true;
373  }
374 
375  @Override
376  public String getItemType() {
377  return getClass().getName() + type.getDisplayName();
378  }
379  }
380 
384  private class ArtifactFactory extends ChildFactory.Detachable<BlackboardArtifact> {
385 
386  private BlackboardArtifact.Type type;
387 
388  public ArtifactFactory(BlackboardArtifact.Type type) {
389  super();
390  this.type = type;
391  }
392 
393  private final PropertyChangeListener pcl = new PropertyChangeListener() {
394  @Override
395  public void propertyChange(PropertyChangeEvent evt) {
396  String eventType = evt.getPropertyName();
397  if (eventType.equals(IngestManager.IngestModuleEvent.DATA_ADDED.toString())) {
404  try {
412  final ModuleDataEvent event = (ModuleDataEvent) evt.getOldValue();
413  if (null != event && event.getBlackboardArtifactType().equals(type)) {
414  refresh(true);
415  }
416  } catch (NoCurrentCaseException notUsed) {
420  }
421  } else if (eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString())
422  || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString())) {
429  try {
431  refresh(true);
432  } catch (NoCurrentCaseException notUsed) {
436  }
437  }
438  }
439  };
440 
441  @Override
442  protected void addNotify() {
445  }
446 
447  @Override
448  protected void removeNotify() {
451  }
452 
453  @Override
454  protected boolean createKeys(List<BlackboardArtifact> list) {
455  if (skCase != null) {
456  try {
457  List<BlackboardArtifact> arts = skCase.getBlackboardArtifacts(type.getTypeID());
458  list.addAll(arts);
459  } catch (TskException ex) {
460  Logger.getLogger(ArtifactFactory.class.getName()).log(Level.SEVERE, "Couldn't get blackboard artifacts from database", ex); //NON-NLS
461  }
462  }
463  return true;
464  }
465 
466  @Override
467  protected Node createNodeForKey(BlackboardArtifact key) {
468  return new BlackboardArtifactNode(key);
469  }
470  }
471 }
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)
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:420
final HashMap< BlackboardArtifact.Type, TypeNode > typeNodeList
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Definition: Case.java:465

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