19 package org.sleuthkit.autopsy.modules.interestingitems;
 
   21 import java.io.Serializable;
 
   22 import java.util.ArrayList;
 
   23 import java.util.HashMap;
 
   24 import java.util.List;
 
   26 import java.util.UUID;
 
   27 import java.util.regex.Pattern;
 
   39 final class FilesSet 
implements Serializable {
 
   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 Map<String, Rule> rules = 
new HashMap<>();
 
   57     FilesSet(String name, String description, 
boolean ignoreKnownFiles, Map<String, Rule> rules) {
 
   58         if ((name == null) || (name.isEmpty())) {
 
   59             throw new IllegalArgumentException(
"Interesting files set name cannot be null or empty");
 
   62         this.description = (description != null ? description : 
"");
 
   63         this.ignoreKnownFiles = ignoreKnownFiles;
 
   65             this.rules.putAll(rules);
 
   83     String getDescription() {
 
   84         return this.description;
 
   96     boolean ignoresKnownFiles() {
 
   97         return this.ignoreKnownFiles;
 
  105     Map<String, Rule> getRules() {
 
  106         return new HashMap<>(this.rules);
 
  117     String fileIsMemberOf(AbstractFile file) {
 
  118         if ((this.ignoreKnownFiles) && (file.getKnown() == TskData.FileKnown.KNOWN)) {
 
  121         for (Rule rule : rules.values()) {
 
  122             if (rule.isSatisfied(file)) {
 
  123                 return rule.getName();
 
  130     public String toString() {
 
  140     static class Rule 
implements Serializable {
 
  142         private static final long serialVersionUID = 1L;
 
  143         private final String uuid;
 
  144         private final String ruleName;
 
  145         private final FileNameCondition fileNameCondition;
 
  146         private final MetaTypeCondition metaTypeCondition;
 
  147         private final ParentPathCondition pathCondition;
 
  148         private final MimeTypeCondition mimeTypeCondition;
 
  149         private final FileSizeCondition fileSizeCondition;
 
  150         private final List<FileAttributeCondition> conditions = 
new ArrayList<>();
 
  162         Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition) {
 
  164             this.uuid = UUID.randomUUID().toString();
 
  165             if (metaTypeCondition == null) {
 
  166                 throw new IllegalArgumentException(
"Interesting files set rule meta-type condition cannot be null");
 
  168             if (pathCondition == null && fileNameCondition == null && mimeTypeCondition == null && fileSizeCondition == null) {
 
  169                 throw new IllegalArgumentException(
"Must have at least one condition on rule.");
 
  172             this.ruleName = ruleName;
 
  178             this.metaTypeCondition = metaTypeCondition;
 
  179             this.conditions.add(this.metaTypeCondition);
 
  181             this.fileSizeCondition = fileSizeCondition;
 
  182             if (this.fileSizeCondition != null) {
 
  183                 this.conditions.add(this.fileSizeCondition);
 
  186             this.fileNameCondition = fileNameCondition;
 
  187             if (this.fileNameCondition != null) {
 
  188                 this.conditions.add(fileNameCondition);
 
  191             this.mimeTypeCondition = mimeTypeCondition;
 
  192             if (this.mimeTypeCondition != null) {
 
  193                 this.conditions.add(mimeTypeCondition);
 
  196             this.pathCondition = pathCondition;
 
  197             if (this.pathCondition != null) {
 
  198                 this.conditions.add(this.pathCondition);
 
  216         FileNameCondition getFileNameCondition() {
 
  217             return this.fileNameCondition;
 
  225         MetaTypeCondition getMetaTypeCondition() {
 
  226             return this.metaTypeCondition;
 
  234         ParentPathCondition getPathCondition() {
 
  235             return this.pathCondition;
 
  245         boolean isSatisfied(AbstractFile file) {
 
  246             for (FileAttributeCondition condition : conditions) {
 
  247                 if (!condition.passes(file)) {
 
  255         public String toString() {
 
  258             if (fileNameCondition != null) {
 
  259                 return this.ruleName + 
" (" + fileNameCondition.getTextToMatch() + 
")";
 
  260             } 
else if (this.pathCondition != null) {
 
  261                 return this.ruleName + 
" (" + pathCondition.getTextToMatch() + 
")";
 
  262             } 
else if (this.mimeTypeCondition != null) {
 
  263                 return this.ruleName + 
" (" + mimeTypeCondition.getMimeType() + 
")";
 
  264             } 
else if (this.fileSizeCondition != null) {
 
  265                 return this.ruleName + 
" (" + fileSizeCondition.getComparator().getSymbol() + 
" " + fileSizeCondition.getSizeValue()
 
  266                         + 
" " + fileSizeCondition.getUnit().getName() + 
")";
 
  268                 return this.ruleName + 
" ()";
 
  276         public String getUuid() {
 
  283         MimeTypeCondition getMimeTypeCondition() {
 
  284             return mimeTypeCondition;
 
  290         FileSizeCondition getFileSizeCondition() {
 
  291             return fileSizeCondition;
 
  298         static interface FileAttributeCondition 
extends Serializable {
 
  307             boolean passes(AbstractFile file);
 
  313         static final class MimeTypeCondition 
implements FileAttributeCondition {
 
  315             private static final long serialVersionUID = 1L;
 
  316             private final String mimeType;
 
  323             MimeTypeCondition(String mimeType) {
 
  324                 this.mimeType = mimeType;
 
  328             public boolean passes(AbstractFile file) {
 
  329                 return this.mimeType.equals(file.getMIMEType());
 
  337             String getMimeType() {
 
  338                 return this.mimeType;
 
  347         static final class FileSizeCondition 
implements FileAttributeCondition {
 
  349             private static final long serialVersionUID = 1L;
 
  354             static enum COMPARATOR {
 
  357                 LESS_THAN_EQUAL(
"≤"),
 
  360                 GREATER_THAN_EQUAL(
"≥");
 
  362                 private String symbol;
 
  364                 COMPARATOR(String symbol) {
 
  365                     this.symbol = symbol;
 
  368                 public static COMPARATOR fromSymbol(String symbol) {
 
  369                     if (symbol.equals(
"<=") || symbol.equals(
"≤")) {
 
  370                         return LESS_THAN_EQUAL;
 
  371                     } 
else if (symbol.equals(
"<")) {
 
  373                     } 
else if (symbol.equals(
"==") || symbol.equals(
"=")) {
 
  375                     } 
else if (symbol.equals(
">")) {
 
  377                     } 
else if (symbol.equals(
">=") || symbol.equals(
"≥")) {
 
  378                         return GREATER_THAN_EQUAL;
 
  380                         throw new IllegalArgumentException(
"Invalid symbol");
 
  387                 public String getSymbol() {
 
  395             static enum SIZE_UNIT {
 
  398                 KILOBYTE(1024, 
"Kilobytes"),
 
  399                 MEGABYTE(1024 * 1024, 
"Megabytes"),
 
  400                 GIGABYTE(1024 * 1024 * 1024, 
"Gigabytes");
 
  404                 private SIZE_UNIT(
long size, String name) {
 
  409                 public long getSize() {
 
  413                 public static SIZE_UNIT fromName(String name) {
 
  414                     for (SIZE_UNIT unit : SIZE_UNIT.values()) {
 
  415                         if (unit.getName().equals(name)) {
 
  419                     throw new IllegalArgumentException(
"Invalid name for size unit.");
 
  425                 public String getName() {
 
  429             private final COMPARATOR comparator;
 
  430             private final SIZE_UNIT unit;
 
  431             private final int sizeValue;
 
  433             FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, 
int sizeValue) {
 
  434                 this.comparator = comparator;
 
  436                 this.sizeValue = sizeValue;
 
  444             COMPARATOR getComparator() {
 
  453             SIZE_UNIT getUnit() {
 
  467             public boolean passes(AbstractFile file) {
 
  468                 long fileSize = file.getSize();
 
  469                 long conditionSize = this.getUnit().getSize() * this.getSizeValue();
 
  470                 switch (this.getComparator()) {
 
  472                         return fileSize > conditionSize;
 
  473                     case GREATER_THAN_EQUAL:
 
  474                         return fileSize >= conditionSize;
 
  475                     case LESS_THAN_EQUAL:
 
  476                         return fileSize <= conditionSize;
 
  478                         return fileSize < conditionSize;
 
  480                         return fileSize == conditionSize;
 
  492         static final class MetaTypeCondition 
implements FileAttributeCondition {
 
  494             private static final long serialVersionUID = 1L;
 
  500                 FILES_AND_DIRECTORIES
 
  503             private final Type type;
 
  510             MetaTypeCondition(Type type) {
 
  515             public boolean passes(AbstractFile file) {
 
  518                         return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG;
 
  520                         return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
 
  522                         return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
 
  523                                 || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
 
  540         static interface TextCondition 
extends FileAttributeCondition {
 
  547             String getTextToMatch();
 
  565             boolean textMatches(String textToMatch);
 
  584                     this.textMatcher = 
new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
 
  586                     this.textMatcher = 
new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
 
  596                 this.textMatcher = 
new FilesSet.Rule.RegexMatcher(regex);
 
  618                 return this.textMatcher.
isRegex();
 
  634             public abstract boolean passes(AbstractFile file);
 
  643         static final class ParentPathCondition 
extends AbstractTextCondition {
 
  645             private static final long serialVersionUID = 1L;
 
  652             ParentPathCondition(String path) {
 
  661             ParentPathCondition(Pattern path) {
 
  666             public boolean passes(AbstractFile file) {
 
  667                 return this.textMatches(file.getParentPath() + 
"/");
 
  677         static interface FileNameCondition 
extends TextCondition {
 
  685         static final class FullNameCondition 
extends AbstractTextCondition implements FileNameCondition {
 
  687             private static final long serialVersionUID = 1L;
 
  694             FullNameCondition(String name) {
 
  703             FullNameCondition(Pattern name) {
 
  708             public boolean passes(AbstractFile file) {
 
  719         static final class ExtensionCondition 
extends AbstractTextCondition implements FileNameCondition {
 
  721             private static final long serialVersionUID = 1L;
 
  728             ExtensionCondition(String extension) {
 
  732                 super(extension.startsWith(
".") ? extension.substring(1) : extension, 
false);
 
  741             ExtensionCondition(Pattern extension) {
 
  742                 super(extension.pattern(), 
false);
 
  746             public boolean passes(AbstractFile file) {
 
  790             private static final long serialVersionUID = 1L;
 
  815                 return subject.equalsIgnoreCase(textToMatch);
 
  825             private static final long serialVersionUID = 1L;
 
  837                 this.pattern = Pattern.compile(Pattern.quote(textToMatch), Pattern.CASE_INSENSITIVE);
 
  852                 return pattern.matcher(subject).find();
 
  861             private static final long serialVersionUID = 1L;
 
  876                 return this.regex.pattern();
 
  887                 return this.regex.matcher(subject).find();
 
boolean textMatches(String textToMatch)
abstract boolean passes(AbstractFile file)
boolean textMatches(String subject)
boolean textMatches(String subject)
final TextMatcher textMatcher
boolean textMatches(String subject)
boolean textMatches(String subject)