Autopsy  4.4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FilesSet.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2017 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.modules.interestingitems;
20 
21 import java.io.Serializable;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.UUID;
27 import java.util.regex.Pattern;
28 import org.sleuthkit.datamodel.AbstractFile;
29 import org.sleuthkit.datamodel.TskData;
30 
39 public final class FilesSet implements Serializable {
40 
41  private static final long serialVersionUID = 1L;
42  private final String name;
43  private final String description;
44  private final boolean ignoreKnownFiles;
45  private final boolean ignoreUnallocatedSpace;
46  private final Map<String, Rule> rules = new HashMap<>();
47 
60  public FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map<String, Rule> rules) {
61  if ((name == null) || (name.isEmpty())) {
62  throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
63  }
64  this.name = name;
65  this.description = (description != null ? description : "");
66  this.ignoreKnownFiles = ignoreKnownFiles;
67  this.ignoreUnallocatedSpace = ignoreUnallocatedSpace;
68  if (rules != null) {
69  this.rules.putAll(rules);
70  }
71  }
72 
78  public String getName() {
79  return this.name;
80  }
81 
87  public String getDescription() {
88  return this.description;
89  }
90 
100  boolean ignoresKnownFiles() {
101  return this.ignoreKnownFiles;
102  }
103 
110  public boolean ingoresUnallocatedSpace() {
111  return this.ignoreUnallocatedSpace;
112  }
113 
119  Map<String, Rule> getRules() {
120  return new HashMap<>(this.rules);
121  }
122 
131  public String fileIsMemberOf(AbstractFile file) {
132  if ((this.ignoreKnownFiles) && (file.getKnown() == TskData.FileKnown.KNOWN)) {
133  return null;
134  }
135 
136  if ((this.ignoreUnallocatedSpace)
137  && (file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
138  || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
139  || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))) {
140  return null;
141  }
142 
143  for (Rule rule : rules.values()) {
144  if (rule.isSatisfied(file)) {
145  return rule.getName();
146  }
147  }
148  return null;
149  }
150 
151  @Override
152  public String toString() {
153  // This override is designed to provide a display name for use with
154  // javax.swing.DefaultListModel<E>.
155  return this.name;
156  }
157 
162  static class Rule implements Serializable {
163 
164  private static final long serialVersionUID = 1L;
165  private final String uuid;
166  private final String ruleName;
167  private final FileNameCondition fileNameCondition;
168  private final MetaTypeCondition metaTypeCondition;
169  private final ParentPathCondition pathCondition;
170  private final MimeTypeCondition mimeTypeCondition;
171  private final FileSizeCondition fileSizeCondition;
172  private final List<FileAttributeCondition> conditions = new ArrayList<>();
173 
184  Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition) {
185  // since ruleName is optional, ruleUUID can be used to uniquely identify a rule.
186  this.uuid = UUID.randomUUID().toString();
187  if (metaTypeCondition == null) {
188  throw new IllegalArgumentException("Interesting files set rule meta-type condition cannot be null");
189  }
190 
191  this.ruleName = ruleName;
192 
193  /*
194  * The rules are evaluated in the order added. MetaType check is
195  * fastest, so do it first
196  */
197  this.metaTypeCondition = metaTypeCondition;
198  this.conditions.add(this.metaTypeCondition);
199 
200  this.fileSizeCondition = fileSizeCondition;
201  if (this.fileSizeCondition != null) {
202  this.conditions.add(this.fileSizeCondition);
203  }
204 
205  this.fileNameCondition = fileNameCondition;
206  if (this.fileNameCondition != null) {
207  this.conditions.add(fileNameCondition);
208  }
209 
210  this.mimeTypeCondition = mimeTypeCondition;
211  if (this.mimeTypeCondition != null) {
212  this.conditions.add(mimeTypeCondition);
213  }
214 
215  this.pathCondition = pathCondition;
216  if (this.pathCondition != null) {
217  this.conditions.add(this.pathCondition);
218  }
219  }
220 
226  String getName() {
227  return ruleName;
228  }
229 
235  FileNameCondition getFileNameCondition() {
236  return this.fileNameCondition;
237  }
238 
244  MetaTypeCondition getMetaTypeCondition() {
245  return this.metaTypeCondition;
246  }
247 
253  ParentPathCondition getPathCondition() {
254  return this.pathCondition;
255  }
256 
264  boolean isSatisfied(AbstractFile file) {
265  for (FileAttributeCondition condition : conditions) {
266  if (!condition.passes(file)) {
267  return false;
268  }
269  }
270  return true;
271  }
272 
273  @Override
274  public String toString() {
275  // This override is designed to provide a display name for use with
276  // javax.swing.DefaultListModel<E>.
277  if (fileNameCondition != null) {
278  return this.ruleName + " (" + fileNameCondition.getTextToMatch() + ")";
279  } else if (this.pathCondition != null) {
280  return this.ruleName + " (" + pathCondition.getTextToMatch() + ")";
281  } else if (this.mimeTypeCondition != null) {
282  return this.ruleName + " (" + mimeTypeCondition.getMimeType() + ")";
283  } else if (this.fileSizeCondition != null) {
284  return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue()
285  + " " + fileSizeCondition.getUnit().getName() + ")";
286  } else {
287  return this.ruleName + " ()";
288  }
289 
290  }
291 
295  public String getUuid() {
296  return this.uuid;
297  }
298 
302  MimeTypeCondition getMimeTypeCondition() {
303  return mimeTypeCondition;
304  }
305 
309  FileSizeCondition getFileSizeCondition() {
310  return fileSizeCondition;
311  }
312 
317  static interface FileAttributeCondition extends Serializable {
318 
326  boolean passes(AbstractFile file);
327  }
328 
332  static final class MimeTypeCondition implements FileAttributeCondition {
333 
334  private static final long serialVersionUID = 1L;
335  private final String mimeType;
336 
342  MimeTypeCondition(String mimeType) {
343  this.mimeType = mimeType;
344  }
345 
346  @Override
347  public boolean passes(AbstractFile file) {
348  return this.mimeType.equals(file.getMIMEType());
349  }
350 
356  String getMimeType() {
357  return this.mimeType;
358  }
359 
360  }
361 
366  static final class FileSizeCondition implements FileAttributeCondition {
367 
368  private static final long serialVersionUID = 1L;
369 
373  static enum COMPARATOR {
374 
375  LESS_THAN("<"),
376  LESS_THAN_EQUAL("≤"),
377  EQUAL("="),
378  GREATER_THAN(">"),
379  GREATER_THAN_EQUAL("≥");
380 
381  private String symbol;
382 
383  COMPARATOR(String symbol) {
384  this.symbol = symbol;
385  }
386 
387  public static COMPARATOR fromSymbol(String symbol) {
388  if (symbol.equals("<=") || symbol.equals("≤")) {
389  return LESS_THAN_EQUAL;
390  } else if (symbol.equals("<")) {
391  return LESS_THAN;
392  } else if (symbol.equals("==") || symbol.equals("=")) {
393  return EQUAL;
394  } else if (symbol.equals(">")) {
395  return GREATER_THAN;
396  } else if (symbol.equals(">=") || symbol.equals("≥")) {
397  return GREATER_THAN_EQUAL;
398  } else {
399  throw new IllegalArgumentException("Invalid symbol");
400  }
401  }
402 
406  public String getSymbol() {
407  return symbol;
408  }
409  }
410 
414  static enum SIZE_UNIT {
415 
416  BYTE(1, "Bytes"),
417  KILOBYTE(1024, "Kilobytes"),
418  MEGABYTE(1024 * 1024, "Megabytes"),
419  GIGABYTE(1024 * 1024 * 1024, "Gigabytes");
420  private long size;
421  private String name;
422 
423  private SIZE_UNIT(long size, String name) {
424  this.size = size;
425  this.name = name;
426  }
427 
428  public long getSize() {
429  return this.size;
430  }
431 
432  public static SIZE_UNIT fromName(String name) {
433  for (SIZE_UNIT unit : SIZE_UNIT.values()) {
434  if (unit.getName().equals(name)) {
435  return unit;
436  }
437  }
438  throw new IllegalArgumentException("Invalid name for size unit.");
439  }
440 
444  public String getName() {
445  return name;
446  }
447  }
448  private final COMPARATOR comparator;
449  private final SIZE_UNIT unit;
450  private final int sizeValue;
451 
452  FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, int sizeValue) {
453  this.comparator = comparator;
454  this.unit = unit;
455  this.sizeValue = sizeValue;
456  }
457 
463  COMPARATOR getComparator() {
464  return comparator;
465  }
466 
472  SIZE_UNIT getUnit() {
473  return unit;
474  }
475 
481  int getSizeValue() {
482  return sizeValue;
483  }
484 
485  @Override
486  public boolean passes(AbstractFile file) {
487  long fileSize = file.getSize();
488  long conditionSize = this.getUnit().getSize() * this.getSizeValue();
489  switch (this.getComparator()) {
490  case GREATER_THAN:
491  return fileSize > conditionSize;
492  case GREATER_THAN_EQUAL:
493  return fileSize >= conditionSize;
494  case LESS_THAN_EQUAL:
495  return fileSize <= conditionSize;
496  case LESS_THAN:
497  return fileSize < conditionSize;
498  default:
499  return fileSize == conditionSize;
500 
501  }
502  }
503 
504  }
505 
511  static final class MetaTypeCondition implements FileAttributeCondition {
512 
513  private static final long serialVersionUID = 1L;
514 
515  enum Type {
516 
517  FILES,
518  DIRECTORIES,
519  FILES_AND_DIRECTORIES,
520  ALL
521  }
522 
523  private final Type type;
524 
530  MetaTypeCondition(Type type) {
531  this.type = type;
532  }
533 
534  @Override
535  public boolean passes(AbstractFile file) {
536  switch (this.type) {
537  case FILES:
538  return file.isFile();
539  case DIRECTORIES:
540  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR
541  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR;
542  case FILES_AND_DIRECTORIES:
543  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
544  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR
545  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR;
546  case ALL:
547  return true; //Effectively ignores the metatype condition when All is selected.
548  default:
549  return true;
550  }
551  }
552 
558  Type getMetaType() {
559  return this.type;
560  }
561  }
562 
566  static interface TextCondition extends FileAttributeCondition {
567 
573  String getTextToMatch();
574 
582  boolean isRegex();
583 
591  boolean textMatches(String textToMatch);
592 
593  }
594 
599  private static abstract class AbstractTextCondition implements TextCondition {
600 
601  private final TextMatcher textMatcher;
602 
608  AbstractTextCondition(String text, Boolean partialMatch) {
609  if (partialMatch) {
610  this.textMatcher = new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
611  } else {
612  this.textMatcher = new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
613  }
614  }
615 
621  AbstractTextCondition(Pattern regex) {
622  this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
623  }
624 
630  @Override
631  public String getTextToMatch() {
632  return this.textMatcher.getTextToMatch();
633  }
634 
642  @Override
643  public boolean isRegex() {
644  return this.textMatcher.isRegex();
645  }
646 
654  @Override
655  public boolean textMatches(String textToMatch) {
656  return this.textMatcher.textMatches(textToMatch);
657  }
658 
659  @Override
660  public abstract boolean passes(AbstractFile file);
661 
662  }
663 
669  static final class ParentPathCondition extends AbstractTextCondition {
670 
671  private static final long serialVersionUID = 1L;
672 
678  ParentPathCondition(String path) {
679  super(path, true);
680  }
681 
687  ParentPathCondition(Pattern path) {
688  super(path);
689  }
690 
691  @Override
692  public boolean passes(AbstractFile file) {
693  return this.textMatches(file.getParentPath() + "/");
694  }
695 
696  }
697 
703  static interface FileNameCondition extends TextCondition {
704  }
705 
711  static final class FullNameCondition extends AbstractTextCondition implements FileNameCondition {
712 
713  private static final long serialVersionUID = 1L;
714 
720  FullNameCondition(String name) {
721  super(name, false);
722  }
723 
729  FullNameCondition(Pattern name) {
730  super(name);
731  }
732 
733  @Override
734  public boolean passes(AbstractFile file) {
735  return this.textMatches(file.getName());
736  }
737 
738  }
739 
745  static final class ExtensionCondition extends AbstractTextCondition implements FileNameCondition {
746 
747  private static final long serialVersionUID = 1L;
748 
754  ExtensionCondition(String extension) {
755  // If there is a leading ".", strip it since
756  // AbstractFile.getFileNameExtension() returns just the
757  // extension chars and not the dot.
758  super(extension.startsWith(".") ? extension.substring(1) : extension, false);
759  }
760 
767  ExtensionCondition(Pattern extension) {
768  super(extension);
769  }
770 
771  @Override
772  public boolean passes(AbstractFile file) {
773  return this.textMatches(file.getNameExtension());
774  }
775 
776  }
777 
782  private static interface TextMatcher extends Serializable {
783 
789  String getTextToMatch();
790 
798  boolean isRegex();
799 
807  boolean textMatches(String subject);
808 
809  }
810 
814  private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
815 
816  private static final long serialVersionUID = 1L;
817  private final String textToMatch;
818 
825  CaseInsensitiveStringComparisionMatcher(String textToMatch) {
826  this.textToMatch = textToMatch;
827  }
828 
829  @Override
830  public String getTextToMatch() {
831  return this.textToMatch;
832  }
833 
834  @Override
835  public boolean isRegex() {
836  return false;
837  }
838 
839  @Override
840  public boolean textMatches(String subject) {
841  return subject.equalsIgnoreCase(textToMatch);
842  }
843 
844  }
845 
850 
851  private static final long serialVersionUID = 1L;
852  private final String textToMatch;
853  private final Pattern pattern;
854 
862  this.textToMatch = textToMatch;
863  this.pattern = Pattern.compile(Pattern.quote(textToMatch), Pattern.CASE_INSENSITIVE);
864  }
865 
866  @Override
867  public String getTextToMatch() {
868  return this.textToMatch;
869  }
870 
871  @Override
872  public boolean isRegex() {
873  return false;
874  }
875 
876  @Override
877  public boolean textMatches(String subject) {
878  return pattern.matcher(subject).find();
879  }
880  }
881 
885  private static class RegexMatcher implements TextMatcher {
886 
887  private static final long serialVersionUID = 1L;
888  private final Pattern regex;
889 
896  RegexMatcher(Pattern regex) {
897  this.regex = regex;
898  }
899 
900  @Override
901  public String getTextToMatch() {
902  return this.regex.pattern();
903  }
904 
905  @Override
906  public boolean isRegex() {
907  return true;
908  }
909 
910  @Override
911  public boolean textMatches(String subject) {
912  // A single match is sufficient.
913  return this.regex.matcher(subject).find();
914  }
915 
916  }
917 
918  }
919 
920 }
FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map< String, Rule > rules)
Definition: FilesSet.java:60

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