Autopsy  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;
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)
138  || file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
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  case FILES_AND_DIRECTORIES:
542  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
543  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
544  case ALL:
545  return true; //Effectively ignores the metatype condition when All is selected.
546  default:
547  return true;
548  }
549  }
550 
556  Type getMetaType() {
557  return this.type;
558  }
559  }
560 
564  static interface TextCondition extends FileAttributeCondition {
565 
571  String getTextToMatch();
572 
580  boolean isRegex();
581 
589  boolean textMatches(String textToMatch);
590 
591  }
592 
597  private static abstract class AbstractTextCondition implements TextCondition {
598 
599  private final TextMatcher textMatcher;
600 
606  AbstractTextCondition(String text, Boolean partialMatch) {
607  if (partialMatch) {
608  this.textMatcher = new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
609  } else {
610  this.textMatcher = new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
611  }
612  }
613 
619  AbstractTextCondition(Pattern regex) {
620  this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
621  }
622 
628  @Override
629  public String getTextToMatch() {
630  return this.textMatcher.getTextToMatch();
631  }
632 
640  @Override
641  public boolean isRegex() {
642  return this.textMatcher.isRegex();
643  }
644 
652  @Override
653  public boolean textMatches(String textToMatch) {
654  return this.textMatcher.textMatches(textToMatch);
655  }
656 
657  @Override
658  public abstract boolean passes(AbstractFile file);
659 
660  }
661 
667  static final class ParentPathCondition extends AbstractTextCondition {
668 
669  private static final long serialVersionUID = 1L;
670 
676  ParentPathCondition(String path) {
677  super(path, true);
678  }
679 
685  ParentPathCondition(Pattern path) {
686  super(path);
687  }
688 
689  @Override
690  public boolean passes(AbstractFile file) {
691  return this.textMatches(file.getParentPath() + "/");
692  }
693 
694  }
695 
701  static interface FileNameCondition extends TextCondition {
702  }
703 
709  static final class FullNameCondition extends AbstractTextCondition implements FileNameCondition {
710 
711  private static final long serialVersionUID = 1L;
712 
718  FullNameCondition(String name) {
719  super(name, false);
720  }
721 
727  FullNameCondition(Pattern name) {
728  super(name);
729  }
730 
731  @Override
732  public boolean passes(AbstractFile file) {
733  return this.textMatches(file.getName());
734  }
735 
736  }
737 
743  static final class ExtensionCondition extends AbstractTextCondition implements FileNameCondition {
744 
745  private static final long serialVersionUID = 1L;
746 
752  ExtensionCondition(String extension) {
753  // If there is a leading ".", strip it since
754  // AbstractFile.getFileNameExtension() returns just the
755  // extension chars and not the dot.
756  super(extension.startsWith(".") ? extension.substring(1) : extension, false);
757  }
758 
765  ExtensionCondition(Pattern extension) {
766  super(extension);
767  }
768 
769  @Override
770  public boolean passes(AbstractFile file) {
771  return this.textMatches(file.getNameExtension());
772  }
773 
774  }
775 
780  private static interface TextMatcher extends Serializable {
781 
787  String getTextToMatch();
788 
796  boolean isRegex();
797 
805  boolean textMatches(String subject);
806 
807  }
808 
812  private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
813 
814  private static final long serialVersionUID = 1L;
815  private final String textToMatch;
816 
823  CaseInsensitiveStringComparisionMatcher(String textToMatch) {
824  this.textToMatch = textToMatch;
825  }
826 
827  @Override
828  public String getTextToMatch() {
829  return this.textToMatch;
830  }
831 
832  @Override
833  public boolean isRegex() {
834  return false;
835  }
836 
837  @Override
838  public boolean textMatches(String subject) {
839  return subject.equalsIgnoreCase(textToMatch);
840  }
841 
842  }
843 
848 
849  private static final long serialVersionUID = 1L;
850  private final String textToMatch;
851  private final Pattern pattern;
852 
860  this.textToMatch = textToMatch;
861  this.pattern = Pattern.compile(Pattern.quote(textToMatch), Pattern.CASE_INSENSITIVE);
862  }
863 
864  @Override
865  public String getTextToMatch() {
866  return this.textToMatch;
867  }
868 
869  @Override
870  public boolean isRegex() {
871  return false;
872  }
873 
874  @Override
875  public boolean textMatches(String subject) {
876  return pattern.matcher(subject).find();
877  }
878  }
879 
883  private static class RegexMatcher implements TextMatcher {
884 
885  private static final long serialVersionUID = 1L;
886  private final Pattern regex;
887 
894  RegexMatcher(Pattern regex) {
895  this.regex = regex;
896  }
897 
898  @Override
899  public String getTextToMatch() {
900  return this.regex.pattern();
901  }
902 
903  @Override
904  public boolean isRegex() {
905  return true;
906  }
907 
908  @Override
909  public boolean textMatches(String subject) {
910  // A single match is sufficient.
911  return this.regex.matcher(subject).find();
912  }
913 
914  }
915 
916  }
917 
918 }
TskData.TSK_DB_FILES_TYPE_ENUM getType()
FilesSet(String name, String description, boolean ignoreKnownFiles, boolean ignoreUnallocatedSpace, Map< String, Rule > rules)
Definition: FilesSet.java:60

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