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

Copyright © 2012-2015 Basis Technology. Generated on: Wed Apr 6 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.