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

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