Autopsy  4.8.0
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-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.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.openide.util.NbBundle;
29 import org.sleuthkit.datamodel.AbstractFile;
30 import org.sleuthkit.datamodel.TskData;
31 
40 public final class FilesSet implements Serializable {
41 
42  private static final long serialVersionUID = 1L;
43  private final String name;
44  private final String description;
45  private final boolean ignoreKnownFiles;
46  private final boolean ignoreUnallocatedSpace;
47  private final Map<String, Rule> rules = new HashMap<>();
48 
61  public FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map<String, Rule> rules) {
62  if ((name == null) || (name.isEmpty())) {
63  throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
64  }
65  this.name = name;
66  this.description = (description != null ? description : "");
67  this.ignoreKnownFiles = ignoreKnownFiles;
68  this.ignoreUnallocatedSpace = ignoreUnallocatedSpace;
69  if (rules != null) {
70  this.rules.putAll(rules);
71  }
72  }
73 
79  public String getName() {
80  return this.name;
81  }
82 
88  public String getDescription() {
89  return this.description;
90  }
91 
101  public boolean ignoresKnownFiles() {
102  return this.ignoreKnownFiles;
103  }
104 
111  public boolean ingoresUnallocatedSpace() {
112  return this.ignoreUnallocatedSpace;
113  }
114 
120  public Map<String, Rule> getRules() {
121  return new HashMap<>(this.rules);
122  }
123 
132  public String fileIsMemberOf(AbstractFile file) {
133  if ((this.ignoreKnownFiles) && (file.getKnown() == TskData.FileKnown.KNOWN)) {
134  return null;
135  }
136 
137  if ((this.ignoreUnallocatedSpace)
138  && (file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
139  || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
140  || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS))) {
141  return null;
142  }
143 
144  for (Rule rule : rules.values()) {
145  if (rule.isSatisfied(file)) {
146  return rule.getName();
147  }
148  }
149  return null;
150  }
151 
152  @Override
153  public String toString() {
154  // This override is designed to provide a display name for use with
155  // javax.swing.DefaultListModel<E>.
156  return this.name;
157  }
158 
163  public final static class Rule implements Serializable {
164 
165  private static final long serialVersionUID = 1L;
166  private final String uuid;
167  private final String ruleName;
168  private final FileNameCondition fileNameCondition;
174  private final List<FileAttributeCondition> conditions = new ArrayList<>();
175 
188  public Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition, DateCondition dateCondition) {
189  // since ruleName is optional, ruleUUID can be used to uniquely identify a rule.
190  this.uuid = UUID.randomUUID().toString();
191  if (metaTypeCondition == null) {
192  throw new IllegalArgumentException("Interesting files set rule meta-type condition cannot be null");
193  }
194 
195  this.ruleName = ruleName;
196 
197  /*
198  * The rules are evaluated in the order added. MetaType check is
199  * fastest, so do it first
200  */
201  this.metaTypeCondition = metaTypeCondition;
202  this.conditions.add(this.metaTypeCondition);
203 
204  this.fileSizeCondition = fileSizeCondition;
205  if (this.fileSizeCondition != null) {
206  this.conditions.add(this.fileSizeCondition);
207  }
208 
209  this.fileNameCondition = fileNameCondition;
210  if (this.fileNameCondition != null) {
211  this.conditions.add(fileNameCondition);
212  }
213 
214  this.mimeTypeCondition = mimeTypeCondition;
215  if (this.mimeTypeCondition != null) {
216  this.conditions.add(mimeTypeCondition);
217  }
218 
219  this.pathCondition = pathCondition;
220  if (this.pathCondition != null) {
221  this.conditions.add(this.pathCondition);
222  }
223  this.dateCondition = dateCondition;
224  if (this.dateCondition != null) {
225  this.conditions.add(this.dateCondition);
226  }
227  }
228 
234  public String getName() {
235  return ruleName;
236  }
237 
243  public FileNameCondition getFileNameCondition() {
244  return this.fileNameCondition;
245  }
246 
253  return this.metaTypeCondition;
254  }
255 
262  return this.pathCondition;
263  }
264 
266  return this.dateCondition;
267  }
268 
276  public boolean isSatisfied(AbstractFile file) {
277  for (FileAttributeCondition condition : conditions) {
278  if (!condition.passes(file)) {
279  return false;
280  }
281  }
282  return true;
283  }
284 
285  @NbBundle.Messages({
286  "# {0} - daysIncluded",
287  "FilesSet.rule.dateRule.toString=(modified within {0} day(s))"
288  })
289  @Override
290  public String toString() {
291  // This override is designed to provide a display name for use with
292  // javax.swing.DefaultListModel<E>.
293  if (fileNameCondition != null) {
294  return this.ruleName + " (" + fileNameCondition.getTextToMatch() + ")";
295  } else if (this.pathCondition != null) {
296  return this.ruleName + " (" + pathCondition.getTextToMatch() + ")";
297  } else if (this.mimeTypeCondition != null) {
298  return this.ruleName + " (" + mimeTypeCondition.getMimeType() + ")";
299  } else if (this.fileSizeCondition != null) {
300  return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue()
301  + " " + fileSizeCondition.getUnit().getName() + ")";
302  } else if (this.dateCondition != null) {
303  return this.ruleName + Bundle.FilesSet_rule_dateRule_toString(dateCondition.getDaysIncluded());
304  } else {
305  return this.ruleName + " ()";
306  }
307 
308  }
309 
313  public String getUuid() {
314  return this.uuid;
315  }
316 
321  return mimeTypeCondition;
322  }
323 
328  return fileSizeCondition;
329  }
330 
335  static interface FileAttributeCondition extends Serializable {
336 
344  boolean passes(AbstractFile file);
345  }
346 
350  public static final class MimeTypeCondition implements FileAttributeCondition {
351 
352  private static final long serialVersionUID = 1L;
353  private final String mimeType;
354 
360  public MimeTypeCondition(String mimeType) {
361  this.mimeType = mimeType;
362  }
363 
364  @Override
365  public boolean passes(AbstractFile file) {
366  return this.mimeType.equals(file.getMIMEType());
367  }
368 
374  public String getMimeType() {
375  return this.mimeType;
376  }
377 
378  }
379 
384  public static final class FileSizeCondition implements FileAttributeCondition {
385 
386  private static final long serialVersionUID = 1L;
387 
391  public static enum COMPARATOR {
392 
393  LESS_THAN("<"),
395  EQUAL("="),
398 
399  private String symbol;
400 
401  private COMPARATOR(String symbol) {
402  this.symbol = symbol;
403  }
404 
405  public static COMPARATOR fromSymbol(String symbol) {
406  switch (symbol) {
407  case "<=":
408  case "≤":
409  return LESS_THAN_EQUAL;
410  case "<":
411  return LESS_THAN;
412  case "==":
413  case "=":
414  return EQUAL;
415  case ">":
416  return GREATER_THAN;
417  case ">=":
418  case "≥":
419  return GREATER_THAN_EQUAL;
420  default:
421  throw new IllegalArgumentException("Invalid symbol");
422  }
423  }
424 
428  public String getSymbol() {
429  return symbol;
430  }
431  }
432 
436  public static enum SIZE_UNIT {
437 
438  BYTE(1, "Bytes"),
439  KILOBYTE(1024, "Kilobytes"),
440  MEGABYTE(1024 * 1024, "Megabytes"),
441  GIGABYTE(1024 * 1024 * 1024, "Gigabytes");
442  private long size;
443  private String name;
444 
445  private SIZE_UNIT(long size, String name) {
446  this.size = size;
447  this.name = name;
448  }
449 
450  public long getSize() {
451  return this.size;
452  }
453 
454  public static SIZE_UNIT fromName(String name) {
455  for (SIZE_UNIT unit : SIZE_UNIT.values()) {
456  if (unit.getName().equals(name)) {
457  return unit;
458  }
459  }
460  throw new IllegalArgumentException("Invalid name for size unit.");
461  }
462 
466  public String getName() {
467  return name;
468  }
469  }
470  private final COMPARATOR comparator;
471  private final SIZE_UNIT unit;
472  private final int sizeValue;
473 
474  public FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, int sizeValue) {
475  this.comparator = comparator;
476  this.unit = unit;
477  this.sizeValue = sizeValue;
478  }
479 
486  return comparator;
487  }
488 
494  public SIZE_UNIT getUnit() {
495  return unit;
496  }
497 
503  public int getSizeValue() {
504  return sizeValue;
505  }
506 
507  @Override
508  public boolean passes(AbstractFile file) {
509  long fileSize = file.getSize();
510  long conditionSize = this.getUnit().getSize() * this.getSizeValue();
511  switch (this.getComparator()) {
512  case GREATER_THAN:
513  return fileSize > conditionSize;
514  case GREATER_THAN_EQUAL:
515  return fileSize >= conditionSize;
516  case LESS_THAN_EQUAL:
517  return fileSize <= conditionSize;
518  case LESS_THAN:
519  return fileSize < conditionSize;
520  default:
521  return fileSize == conditionSize;
522 
523  }
524  }
525 
526  }
527 
533  public static final class MetaTypeCondition implements FileAttributeCondition {
534 
535  private static final long serialVersionUID = 1L;
536 
537  public enum Type {
538 
542  ALL
543  }
544 
545  private final Type type;
546 
552  public MetaTypeCondition(Type type) {
553  this.type = type;
554  }
555 
556  @Override
557  public boolean passes(AbstractFile file) {
558  switch (this.type) {
559  case FILES:
560  return file.isFile();
561  case DIRECTORIES:
562  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR
563  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR;
564  case FILES_AND_DIRECTORIES:
565  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
566  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR
567  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR;
568  case ALL:
569  return true; //Effectively ignores the metatype condition when All is selected.
570  default:
571  return true;
572  }
573  }
574 
580  public Type getMetaType() {
581  return this.type;
582  }
583  }
584 
588  static interface TextCondition extends FileAttributeCondition {
589 
595  String getTextToMatch();
596 
604  boolean isRegex();
605 
613  boolean textMatches(String textToMatch);
614 
615  }
616 
621  private static abstract class AbstractTextCondition implements TextCondition {
622 
623  /*
624  * To ensure compatibility with existing serialized configuration
625  * settings, this class cannot have a 'serialVersionUID'.
626  */
627 
628  private final TextMatcher textMatcher;
629 
635  AbstractTextCondition(String text, Boolean partialMatch) {
636  if (partialMatch) {
637  this.textMatcher = new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
638  } else {
639  this.textMatcher = new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
640  }
641  }
642 
648  AbstractTextCondition(Pattern regex) {
649  this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
650  }
651 
657  @Override
658  public String getTextToMatch() {
659  return this.textMatcher.getTextToMatch();
660  }
661 
669  @Override
670  public boolean isRegex() {
671  return this.textMatcher.isRegex();
672  }
673 
681  @Override
682  public boolean textMatches(String textToMatch) {
683  return this.textMatcher.textMatches(textToMatch);
684  }
685 
686  @Override
687  public abstract boolean passes(AbstractFile file);
688 
689  }
690 
696  public static final class ParentPathCondition extends AbstractTextCondition {
697 
698  private static final long serialVersionUID = 1L;
699 
705  public ParentPathCondition(String path) {
706  super(path, true);
707  }
708 
714  public ParentPathCondition(Pattern path) {
715  super(path);
716  }
717 
718  @Override
719  public boolean passes(AbstractFile file) {
720  return this.textMatches(file.getParentPath() + "/");
721  }
722 
723  }
724 
730  static interface FileNameCondition extends TextCondition {
731  }
732 
738  public static final class FullNameCondition extends AbstractTextCondition implements FileNameCondition {
739 
740  private static final long serialVersionUID = 1L;
741 
747  public FullNameCondition(String name) {
748  super(name, false);
749  }
750 
756  public FullNameCondition(Pattern name) {
757  super(name);
758  }
759 
760  @Override
761  public boolean passes(AbstractFile file) {
762  return this.textMatches(file.getName());
763  }
764 
765  }
766 
771  public static final class DateCondition implements FileAttributeCondition {
772 
773  /*
774  * To ensure compatibility with existing serialized configuration
775  * settings, this class cannot have a 'serialVersionUID'.
776  */
777 
778  private final static long SECS_PER_DAY = 60 * 60 * 24;
779 
780  private int daysIncluded;
781 
788  public DateCondition(int days) {
789  daysIncluded = days;
790  }
791 
797  public int getDaysIncluded() {
798  return daysIncluded;
799  }
800 
801  @Override
802  public boolean passes(AbstractFile file) {
803  long dateThreshold = System.currentTimeMillis() / 1000 - daysIncluded * SECS_PER_DAY;
804  return file.getCrtime() > dateThreshold || file.getMtime() > dateThreshold;
805  }
806 
807  }
808 
814  public static final class ExtensionCondition extends AbstractTextCondition implements FileNameCondition {
815 
816  private static final long serialVersionUID = 1L;
817 
823  public ExtensionCondition(String extension) {
824  // If there is a leading ".", strip it since
825  // AbstractFile.getFileNameExtension() returns just the
826  // extension chars and not the dot.
827  super(extension.startsWith(".") ? extension.substring(1) : extension, false);
828  }
829 
836  public ExtensionCondition(Pattern extension) {
837  super(extension);
838  }
839 
840  @Override
841  public boolean passes(AbstractFile file) {
842  return this.textMatches(file.getNameExtension());
843  }
844 
845  }
846 
851  private static interface TextMatcher extends Serializable {
852 
858  String getTextToMatch();
859 
867  boolean isRegex();
868 
876  boolean textMatches(String subject);
877 
878  }
879 
883  private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
884 
885  private static final long serialVersionUID = 1L;
886  private final String textToMatch;
887 
894  CaseInsensitiveStringComparisionMatcher(String textToMatch) {
895  this.textToMatch = textToMatch;
896  }
897 
898  @Override
899  public String getTextToMatch() {
900  return this.textToMatch;
901  }
902 
903  @Override
904  public boolean isRegex() {
905  return false;
906  }
907 
908  @Override
909  public boolean textMatches(String subject) {
910  return subject.equalsIgnoreCase(textToMatch);
911  }
912 
913  }
914 
919 
920  private static final long serialVersionUID = 1L;
921  private final String textToMatch;
922  private final Pattern pattern;
923 
931  this.textToMatch = textToMatch;
932  this.pattern = Pattern.compile(Pattern.quote(textToMatch), Pattern.CASE_INSENSITIVE);
933  }
934 
935  @Override
936  public String getTextToMatch() {
937  return this.textToMatch;
938  }
939 
940  @Override
941  public boolean isRegex() {
942  return false;
943  }
944 
945  @Override
946  public boolean textMatches(String subject) {
947  return pattern.matcher(subject).find();
948  }
949  }
950 
954  private static class RegexMatcher implements TextMatcher {
955 
956  private static final long serialVersionUID = 1L;
957  private final Pattern regex;
958 
965  RegexMatcher(Pattern regex) {
966  this.regex = regex;
967  }
968 
969  @Override
970  public String getTextToMatch() {
971  return this.regex.pattern();
972  }
973 
974  @Override
975  public boolean isRegex() {
976  return true;
977  }
978 
979  @Override
980  public boolean textMatches(String subject) {
981  // A single match is sufficient.
982  return this.regex.matcher(subject).find();
983  }
984 
985  }
986 
987  }
988 
989 }
FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, int sizeValue)
Definition: FilesSet.java:474
FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map< String, Rule > rules)
Definition: FilesSet.java:61
Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition, DateCondition dateCondition)
Definition: FilesSet.java:188
final List< FileAttributeCondition > conditions
Definition: FilesSet.java:174

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