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)