Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FileTypesByExtension.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011 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.Arrays;
24 import java.util.List;
25 import java.util.Observable;
26 import java.util.Observer;
27 import java.util.logging.Level;
28 import org.openide.nodes.AbstractNode;
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.AbstractFile;
40 import org.sleuthkit.datamodel.Content;
41 import org.sleuthkit.datamodel.ContentVisitor;
42 import org.sleuthkit.datamodel.DerivedFile;
43 import org.sleuthkit.datamodel.Directory;
44 import org.sleuthkit.datamodel.File;
45 import org.sleuthkit.datamodel.LayoutFile;
46 import org.sleuthkit.datamodel.LocalFile;
47 import org.sleuthkit.datamodel.SleuthkitCase;
48 import org.sleuthkit.datamodel.TskCoreException;
49 import org.sleuthkit.datamodel.TskData;
50 
54  public final class FileTypesByExtension implements AutopsyVisitableItem {
55 
56  private final SleuthkitCase skCase;
57 
58  public FileTypesByExtension(SleuthkitCase skCase) {
59  this.skCase = skCase;
60  }
61 
62  public SleuthkitCase getSleuthkitCase() {
63  return this.skCase;
64  }
65 
66  @Override
67  public <T> T accept(AutopsyItemVisitor<T> v) {
68  return v.visit(this);
69  }
70 
75  private static class FileTypesByExtObservable extends Observable {
76 
78  super();
82  }
83 
84  private void removeListeners() {
85  deleteObservers();
89  }
90 
91  private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
92  String eventType = evt.getPropertyName();
93  if (eventType.equals(IngestManager.IngestModuleEvent.CONTENT_CHANGED.toString()) || eventType.equals(IngestManager.IngestJobEvent.COMPLETED.toString()) || eventType.equals(IngestManager.IngestJobEvent.CANCELLED.toString()) || eventType.equals(Case.Events.DATA_SOURCE_ADDED.toString())) {
100  try {
102  update();
103  } catch (IllegalStateException notUsed) {
107  }
108  } else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
109  // case was closed. Remove listeners so that we don't get called with a stale case handle
110  if (evt.getNewValue() == null) {
111  removeListeners();
112  }
113  }
114  };
115 
116  private void update() {
117  setChanged();
118  notifyObservers();
119  }
120  }
121 
125  static class FileTypesByExtNode extends DisplayableItemNode {
126 
127  private static final String FNAME = NbBundle.getMessage(FileTypesByExtNode.class, "FileTypesByExtNode.fname.text");
128  private final FileTypesByExtension.RootFilter filter;
129 
136  FileTypesByExtNode(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter) {
137  super(Children.create(new FileTypesByExtNodeChildren(skCase, filter, null), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
138  this.filter = filter;
139  init();
140  }
141 
149  private FileTypesByExtNode(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, Observable o) {
150  super(Children.create(new FileTypesByExtNodeChildren(skCase, filter, o), true), Lookups.singleton(filter == null ? FNAME : filter.getName()));
151  this.filter = filter;
152  init();
153  }
154 
155  private void init() {
156  // root node of tree
157  if (filter == null) {
158  super.setName(FNAME);
159  super.setDisplayName(FNAME);
160  } // sub-node in file tree (i.e. documents, exec, etc.)
161  else {
162  super.setName(filter.getName());
163  super.setDisplayName(filter.getDisplayName());
164  }
165  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file_types.png"); //NON-NLS
166  }
167 
168  @Override
169  public boolean isLeafTypeNode() {
170  return false;
171  }
172 
173  @Override
174  public <T> T accept(DisplayableItemNodeVisitor<T> v) {
175  return v.visit(this);
176  }
177 
178  @Override
179  protected Sheet createSheet() {
180  Sheet s = super.createSheet();
181  Sheet.Set ss = s.get(Sheet.PROPERTIES);
182  if (ss == null) {
183  ss = Sheet.createPropertiesSet();
184  s.put(ss);
185  }
186  ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.name.name"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.name.displayName"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.name.desc"), getName()));
187  return s;
188  }
189 
190  @Override
191  public String getItemType() {
196  if (filter == null) {
197  return getClass().getName();
198  }
199  if (filter.equals(FileTypesByExtension.RootFilter.TSK_DOCUMENT_FILTER) || filter.equals(FileTypesByExtension.RootFilter.TSK_EXECUTABLE_FILTER)) {
200  return getClass().getName() + filter.getName();
201  }
202  return getClass().getName();
203  }
204 
205  private static class FileTypesByExtNodeChildren extends ChildFactory<FileTypesByExtension.SearchFilterInterface> {
206 
207  private final SleuthkitCase skCase;
209  private final Observable notifier;
210 
218  private FileTypesByExtNodeChildren(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, Observable o) {
219  super();
220  this.skCase = skCase;
221  this.filter = filter;
222  if (o == null) {
223  this.notifier = new FileTypesByExtObservable();
224  } else {
225  this.notifier = o;
226  }
227  }
228 
229  @Override
230  protected boolean createKeys(List<FileTypesByExtension.SearchFilterInterface> list) {
231  // root node
232  if (filter == null) {
233  list.addAll(Arrays.asList(FileTypesByExtension.RootFilter.values()));
234  } // document and executable has another level of nodes
236  list.addAll(Arrays.asList(FileTypesByExtension.DocumentFilter.values()));
238  list.addAll(Arrays.asList(FileTypesByExtension.ExecutableFilter.values()));
239  }
240  return true;
241  }
242 
243  @Override
245  // make new nodes for the sub-nodes
246  if (key.getName().equals(FileTypesByExtension.RootFilter.TSK_DOCUMENT_FILTER.getName())) {
247  return new FileTypesByExtNode(skCase, FileTypesByExtension.RootFilter.TSK_DOCUMENT_FILTER, notifier);
248  } else if (key.getName().equals(FileTypesByExtension.RootFilter.TSK_EXECUTABLE_FILTER.getName())) {
249  return new FileTypesByExtNode(skCase, FileTypesByExtension.RootFilter.TSK_EXECUTABLE_FILTER, notifier);
250  } else {
251  return new FileExtensionNode(key, skCase, notifier);
252  }
253  }
254  }
255 
256  }
257 
262  static class FileExtensionNode extends DisplayableItemNode {
263 
265  SleuthkitCase skCase;
266 
274  FileExtensionNode(FileTypesByExtension.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
275  super(Children.create(new FileExtensionNodeChildren(filter, skCase, o), true), Lookups.singleton(filter.getDisplayName()));
276  this.filter = filter;
277  this.skCase = skCase;
278  init();
279  o.addObserver(new ByExtNodeObserver());
280  }
281 
282  private void init() {
283  super.setName(filter.getName());
284  updateDisplayName();
285  this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/file-filter-icon.png"); //NON-NLS
286  }
287 
288  // update the display name when new events are fired
289  private class ByExtNodeObserver implements Observer {
290 
291  @Override
292  public void update(Observable o, Object arg) {
293  updateDisplayName();
294  }
295  }
296 
297  private void updateDisplayName() {
298  final long count = FileExtensionNodeChildren.calculateItems(skCase, filter);
299  super.setDisplayName(filter.getDisplayName() + " (" + count + ")");
300  }
301 
302  @Override
303  public <T> T accept(DisplayableItemNodeVisitor<T> v) {
304  return v.visit(this);
305  }
306 
307  @Override
308  protected Sheet createSheet() {
309  Sheet s = super.createSheet();
310  Sheet.Set ss = s.get(Sheet.PROPERTIES);
311  if (ss == null) {
312  ss = Sheet.createPropertiesSet();
313  s.put(ss);
314  }
315  ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.name"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.displayName"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.filterType.desc"), filter.getDisplayName()));
316  String extensions = "";
317  for (String ext : filter.getFilter()) {
318  extensions += "'" + ext + "', ";
319  }
320  extensions = extensions.substring(0, extensions.lastIndexOf(','));
321  ss.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.name"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.displayName"), NbBundle.getMessage(this.getClass(), "FileTypesByExtNode.createSheet.fileExt.desc"), extensions));
322  return s;
323  }
324 
325  @Override
326  public boolean isLeafTypeNode() {
327  return true;
328  }
329 
335  @Override
336  public String getItemType() {
337  return DisplayableItemNode.FILE_PARENT_NODE_KEY;
338  }
339 
344  private static class FileExtensionNodeChildren extends ChildFactory.Detachable<Content> {
345 
346  private final SleuthkitCase skCase;
348  private static final Logger LOGGER = Logger.getLogger(FileExtensionNodeChildren.class.getName());
349  private final Observable notifier;
350 
358  private FileExtensionNodeChildren(FileTypesByExtension.SearchFilterInterface filter, SleuthkitCase skCase, Observable o) {
359  super();
360  this.filter = filter;
361  this.skCase = skCase;
362  notifier = o;
363  }
364 
365  @Override
366  protected void addNotify() {
367  if (notifier != null) {
368  notifier.addObserver(observer);
369  }
370  }
371 
372  @Override
373  protected void removeNotify() {
374  if (notifier != null) {
375  notifier.deleteObserver(observer);
376  }
377  }
378  private final Observer observer = new FileTypeChildFactoryObserver();
379 
380  // Cause refresh of children if there are changes
381  private class FileTypeChildFactoryObserver implements Observer {
382 
383  @Override
384  public void update(Observable o, Object arg) {
385  refresh(true);
386  }
387  }
388 
394  private static long calculateItems(SleuthkitCase sleuthkitCase, FileTypesByExtension.SearchFilterInterface filter) {
395  try {
396  return sleuthkitCase.countFilesWhere(createQuery(filter));
397  } catch (TskCoreException ex) {
398  LOGGER.log(Level.SEVERE, "Error getting file search view count", ex); //NON-NLS
399  return 0;
400  }
401  }
402 
403  @Override
404  protected boolean createKeys(List<Content> list) {
405  try {
406  List<AbstractFile> files = skCase.findAllFilesWhere(createQuery(filter));
407  list.addAll(files);
408  } catch (TskCoreException ex) {
409  LOGGER.log(Level.SEVERE, "Couldn't get search results", ex); //NON-NLS
410  }
411  return true;
412  }
413 
415  StringBuilder query = new StringBuilder();
416  query.append("(dir_type = ").append(TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue()).append(")"); //NON-NLS
418  query.append(" AND (known IS NULL OR known != ").append(TskData.FileKnown.KNOWN.getFileKnownValue()).append(")"); //NON-NLS
419  }
420  query.append(" AND (NULL"); //NON-NLS
421  for (String s : filter.getFilter()) {
422  query.append(" OR LOWER(name) LIKE LOWER('%").append(s).append("')"); //NON-NLS
423  }
424  query.append(')');
425  return query.toString();
426  }
427 
428  @Override
429  protected Node createNodeForKey(Content key) {
430  return key.accept(new ContentVisitor.Default<AbstractNode>() {
431  @Override
432  public FileNode visit(File f) {
433  return new FileNode(f, false);
434  }
435 
436  @Override
437  public DirectoryNode visit(Directory d) {
438  return new DirectoryNode(d);
439  }
440 
441  @Override
442  public LayoutFileNode visit(LayoutFile lf) {
443  return new LayoutFileNode(lf);
444  }
445 
446  @Override
447  public LocalFileNode visit(DerivedFile df) {
448  return new LocalFileNode(df);
449  }
450 
451  @Override
452  public LocalFileNode visit(LocalFile lf) {
453  return new LocalFileNode(lf);
454  }
455 
456  @Override
457  protected AbstractNode defaultVisit(Content di) {
458  throw new UnsupportedOperationException(NbBundle.getMessage(this.getClass(), "FileTypeChildren.exception.notSupported.msg", di.toString()));
459  }
460  });
461  }
462  }
463  }
464 
465  // root node filters
466  public static enum RootFilter implements AutopsyVisitableItem, SearchFilterInterface {
467 
468  TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", //NON-NLS
469  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskImgFilter.text"),
471  TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", //NON-NLS
472  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskVideoFilter.text"),
474  TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", //NON-NLS
475  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskAudioFilter.text"),
477  TSK_ARCHIVE_FILTER(3, "TSK_ARCHIVE_FILTER", //NON-NLS
478  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskArchiveFilter.text"),
480  TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", //NON-NLS
481  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskDocumentFilter.text"),
482  Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt")), //NON-NLS
483  TSK_EXECUTABLE_FILTER(3, "TSK_EXECUTABLE_FILTER", //NON-NLS
484  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.tskExecFilter.text"),
485  Arrays.asList(".exe", ".dll", ".bat", ".cmd", ".com")); //NON-NLS
486 
487  private final int id;
488  private final String name;
489  private final String displayName;
490  private final List<String> filter;
491 
492  private RootFilter(int id, String name, String displayName, List<String> filter) {
493  this.id = id;
494  this.name = name;
495  this.displayName = displayName;
496  this.filter = filter;
497  }
498 
499  @Override
500  public <T> T accept(AutopsyItemVisitor<T> v) {
501  return v.visit(this);
502  }
503 
504  @Override
505  public String getName() {
506  return this.name;
507  }
508 
509  @Override
510  public int getId() {
511  return this.id;
512  }
513 
514  @Override
515  public String getDisplayName() {
516  return this.displayName;
517  }
518 
519  @Override
520  public List<String> getFilter() {
521  return this.filter;
522  }
523  }
524 
525  // document sub-node filters
526  public static enum DocumentFilter implements AutopsyVisitableItem, SearchFilterInterface {
527 
528  AUT_DOC_HTML(0, "AUT_DOC_HTML", //NON-NLS
529  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocHtmlFilter.text"),
530  Arrays.asList(".htm", ".html")), //NON-NLS
531  AUT_DOC_OFFICE(1, "AUT_DOC_OFFICE", //NON-NLS
532  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocOfficeFilter.text"),
533  Arrays.asList(".doc", ".docx", ".odt", ".xls", ".xlsx", ".ppt", ".pptx")), //NON-NLS
534  AUT_DOC_PDF(2, "AUT_DOC_PDF", //NON-NLS
535  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autoDocPdfFilter.text"),
536  Arrays.asList(".pdf")), //NON-NLS
537  AUT_DOC_TXT(3, "AUT_DOC_TXT", //NON-NLS
538  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocTxtFilter.text"),
539  Arrays.asList(".txt")), //NON-NLS
540  AUT_DOC_RTF(4, "AUT_DOC_RTF", //NON-NLS
541  NbBundle.getMessage(FileTypesByExtension.class, "FileTypeExtensionFilters.autDocRtfFilter.text"),
542  Arrays.asList(".rtf")); //NON-NLS
543 
544  private final int id;
545  private final String name;
546  private final String displayName;
547  private final List<String> filter;
548 
549  private DocumentFilter(int id, String name, String displayName, List<String> filter) {
550  this.id = id;
551  this.name = name;
552  this.displayName = displayName;
553  this.filter = filter;
554  }
555 
556  @Override
557  public <T> T accept(AutopsyItemVisitor<T> v) {
558  return v.visit(this);
559  }
560 
561  @Override
562  public String getName() {
563  return this.name;
564  }
565 
566  @Override
567  public int getId() {
568  return this.id;
569  }
570 
571  @Override
572  public String getDisplayName() {
573  return this.displayName;
574  }
575 
576  @Override
577  public List<String> getFilter() {
578  return this.filter;
579  }
580  }
581 
582  // executable sub-node filters
583  public static enum ExecutableFilter implements AutopsyVisitableItem, SearchFilterInterface {
584 
585  ExecutableFilter_EXE(0, "ExecutableFilter_EXE", ".exe", Arrays.asList(".exe")), //NON-NLS
586  ExecutableFilter_DLL(1, "ExecutableFilter_DLL", ".dll", Arrays.asList(".dll")), //NON-NLS
587  ExecutableFilter_BAT(2, "ExecutableFilter_BAT", ".bat", Arrays.asList(".bat")), //NON-NLS
588  ExecutableFilter_CMD(3, "ExecutableFilter_CMD", ".cmd", Arrays.asList(".cmd")), //NON-NLS
589  ExecutableFilter_COM(4, "ExecutableFilter_COM", ".com", Arrays.asList(".com")); //NON-NLS
590 
591  private final int id;
592  private final String name;
593  private final String displayName;
594  private final List<String> filter;
595 
596  private ExecutableFilter(int id, String name, String displayName, List<String> filter) {
597  this.id = id;
598  this.name = name;
599  this.displayName = displayName;
600  this.filter = filter;
601  }
602 
603  @Override
604  public <T> T accept(AutopsyItemVisitor<T> v) {
605  return v.visit(this);
606  }
607 
608  @Override
609  public String getName() {
610  return this.name;
611  }
612 
613  @Override
614  public int getId() {
615  return this.id;
616  }
617 
618  @Override
619  public String getDisplayName() {
620  return this.displayName;
621  }
622 
623  @Override
624  public List<String> getFilter() {
625  return this.filter;
626  }
627  }
628 
629  interface SearchFilterInterface {
630 
631  public String getName();
632 
633  public int getId();
634 
635  public String getDisplayName();
636 
637  public List<String> getFilter();
638  }
639 }
void removeIngestModuleEventListener(final PropertyChangeListener listener)
FileExtensionNodeChildren(FileTypesByExtension.SearchFilterInterface filter, SleuthkitCase skCase, Observable o)
static synchronized IngestManager getInstance()
static void removePropertyChangeListener(PropertyChangeListener listener)
Definition: Case.java:318
static long calculateItems(SleuthkitCase sleuthkitCase, FileTypesByExtension.SearchFilterInterface filter)
FileTypesByExtNodeChildren(SleuthkitCase skCase, FileTypesByExtension.RootFilter filter, Observable o)
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
static void addPropertyChangeListener(PropertyChangeListener listener)
Definition: Case.java:306
RootFilter(int id, String name, String displayName, List< String > filter)
DocumentFilter(int id, String name, String displayName, List< String > filter)
void addIngestModuleEventListener(final PropertyChangeListener listener)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
ExecutableFilter(int id, String name, String displayName, List< String > filter)

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