Autopsy  3.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 2014 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.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.UUID;
26 import java.util.regex.Pattern;
29 
38 final class FilesSet {
39 
40  private final String name;
41  private final String description;
42  private final boolean ignoreKnownFiles;
43  private final Map<String, Rule> rules = new HashMap<>();
44 
55  FilesSet(String name, String description, boolean ignoreKnownFiles, Map<String, Rule> rules) {
56  if ((name == null) || (name.isEmpty())) {
57  throw new IllegalArgumentException("Interesting files set name cannot be null or empty");
58  }
59  this.name = name;
60  this.description = (description != null ? description : "");
61  this.ignoreKnownFiles = ignoreKnownFiles;
62  if (rules != null) {
63  this.rules.putAll(rules);
64  }
65  }
66 
72  String getName() {
73  return this.name;
74  }
75 
81  String getDescription() {
82  return this.description;
83  }
84 
94  boolean ignoresKnownFiles() {
95  return this.ignoreKnownFiles;
96  }
97 
103  Map<String, Rule> getRules() {
104  return new HashMap<>(this.rules);
105  }
106 
114  String fileIsMemberOf(AbstractFile file) {
115  if ((this.ignoreKnownFiles) && (file.getKnown() == TskData.FileKnown.KNOWN)) {
116  return null;
117  }
118  for (Rule rule : rules.values()) {
119  if (rule.isSatisfied(file)) {
120  return rule.getName();
121  }
122  }
123  return null;
124  }
125 
126  @Override
127  public String toString() {
128  // This override is designed to provide a display name for use with
129  // javax.swing.DefaultListModel<E>.
130  return this.name;
131  }
132 
137  static class Rule {
138 
139  private final String uuid;
140  private final String ruleName;
141  private final FileNameFilter fileNameFilter;
142  private final MetaTypeFilter metaTypeFilter;
143  private final ParentPathFilter pathFilter;
144  private final List<FileAttributeFilter> filters = new ArrayList<>();
145 
154  Rule(String ruleName, FileNameFilter fileNameFilter, MetaTypeFilter metaTypeFilter, ParentPathFilter pathFilter) {
155  // since ruleName is optional, ruleUUID can be used to uniquely identify a rule.
156  this.uuid = UUID.randomUUID().toString();
157 
158  if (ruleName == null) {
159  throw new IllegalArgumentException("Interesting files set rule name cannot be null");
160  }
161  if (fileNameFilter == null) {
162  throw new IllegalArgumentException("Interesting files set rule file name filter cannot be null");
163  }
164  if (metaTypeFilter == null) {
165  throw new IllegalArgumentException("Interesting files set rule meta-type filter cannot be null");
166  }
167  this.ruleName = ruleName;
168 
169  /* The rules are evaluated in the order added. MetaType check is fastest, so do it first */
170  this.metaTypeFilter = metaTypeFilter;
171  this.filters.add(this.metaTypeFilter);
172 
173  this.fileNameFilter = fileNameFilter;
174  this.filters.add(fileNameFilter);
175 
176  this.pathFilter = pathFilter;
177  if (this.pathFilter != null) {
178  this.filters.add(this.pathFilter);
179  }
180  }
181 
187  String getName() {
188  return ruleName;
189  }
190 
196  FileNameFilter getFileNameFilter() {
197  return this.fileNameFilter;
198  }
199 
205  MetaTypeFilter getMetaTypeFilter() {
206  return this.metaTypeFilter;
207  }
208 
214  ParentPathFilter getPathFilter() {
215  return this.pathFilter;
216  }
217 
224  boolean isSatisfied(AbstractFile file) {
225  for (FileAttributeFilter filter : filters) {
226  if (!filter.passes(file)) {
227  return false;
228  }
229  }
230  return true;
231  }
232 
236  @Override
237  public String toString() {
238  // This override is designed to provide a display name for use with
239  // javax.swing.DefaultListModel<E>.
240  return this.ruleName + " (" + fileNameFilter.getTextToMatch() + ")";
241  }
242 
246  public String getUuid() {
247  return this.uuid;
248  }
249 
254  static interface FileAttributeFilter {
255 
262  boolean passes(AbstractFile file);
263  }
264 
270  static final class MetaTypeFilter implements FileAttributeFilter {
271 
272  enum Type {
273 
274  FILES,
275  DIRECTORIES,
276  FILES_AND_DIRECTORIES
277  }
278 
279  private final Type type;
280 
286  MetaTypeFilter(Type type) {
287  this.type = type;
288  }
289 
293  @Override
294  public boolean passes(AbstractFile file) {
295  switch (this.type) {
296  case FILES:
297  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG;
298  case DIRECTORIES:
299  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
300  default:
301  return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG
302  || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR;
303  }
304  }
305 
311  Type getMetaType() {
312  return this.type;
313  }
314  }
315 
319  static interface TextFilter extends FileAttributeFilter {
320 
326  String getTextToMatch();
327 
335  boolean isRegex();
336 
343  boolean textMatches(String textToMatch);
344 
345  }
346 
351  private static abstract class AbstractTextFilter implements TextFilter {
352 
353  private final TextMatcher textMatcher;
354 
360  AbstractTextFilter(String text, Boolean partialMatch) {
361  if(partialMatch)
362  this.textMatcher = new FilesSet.Rule.CaseInsensitivePartialStringComparisionMatcher(text);
363  else
364  this.textMatcher = new FilesSet.Rule.CaseInsensitiveStringComparisionMatcher(text);
365  }
366 
372  AbstractTextFilter(Pattern regex) {
373  this.textMatcher = new FilesSet.Rule.RegexMatcher(regex);
374  }
375 
381  @Override
382  public String getTextToMatch() {
383  return this.textMatcher.getTextToMatch();
384  }
385 
393  @Override
394  public boolean isRegex() {
395  return this.textMatcher.isRegex();
396  }
397 
404  @Override
405  public boolean textMatches(String textToMatch) {
406  return this.textMatcher.textMatches(textToMatch);
407  }
408 
412  @Override
413  public abstract boolean passes(AbstractFile file);
414 
415  }
416 
422  static final class ParentPathFilter extends AbstractTextFilter {
423 
429  ParentPathFilter(String path) {
430  super(path, true);
431  }
432 
438  ParentPathFilter(Pattern path) {
439  super(path);
440  }
441 
445  @Override
446  public boolean passes(AbstractFile file) {
447  return this.textMatches(file.getParentPath() + "/");
448  }
449 
450  }
451 
456  static interface FileNameFilter extends TextFilter {
457  }
458 
464  static final class FullNameFilter extends AbstractTextFilter implements FileNameFilter {
465 
471  FullNameFilter(String name) {
472  super(name, false);
473  }
474 
480  FullNameFilter(Pattern name) {
481  super(name);
482  }
483 
487  @Override
488  public boolean passes(AbstractFile file) {
489  return this.textMatches(file.getName());
490  }
491 
492  }
493 
499  static final class ExtensionFilter extends AbstractTextFilter implements FileNameFilter {
500 
506  ExtensionFilter(String extension) {
507  // If there is a leading ".", strip it since
508  // AbstractFile.getFileNameExtension() returns just the
509  // extension chars and not the dot.
510  super(extension.startsWith(".") ? extension.substring(1) : extension, false);
511  }
512 
519  ExtensionFilter(Pattern extension) {
520  super(extension.pattern(), false);
521  }
522 
526  @Override
527  public boolean passes(AbstractFile file) {
528  return this.textMatches(file.getNameExtension());
529  }
530 
531  }
532 
537  private static interface TextMatcher {
538 
544  String getTextToMatch();
545 
553  boolean isRegex();
554 
561  boolean textMatches(String subject);
562 
563  }
564 
568  private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
569 
570  private final String textToMatch;
571 
578  CaseInsensitiveStringComparisionMatcher(String textToMatch) {
579  this.textToMatch = textToMatch;
580  }
581 
585  @Override
586  public String getTextToMatch() {
587  return this.textToMatch;
588  }
589 
593  @Override
594  public boolean isRegex() {
595  return false;
596  }
597 
601  @Override
602  public boolean textMatches(String subject) {
603  return subject.equalsIgnoreCase(textToMatch);
604  }
605 
606  }
607 
612 
613  private final String textToMatch;
614  private final Pattern pattern;
615 
623  this.textToMatch = textToMatch;
624  this.pattern = Pattern.compile(Pattern.quote(textToMatch), Pattern.CASE_INSENSITIVE);
625  }
626 
630  @Override
631  public String getTextToMatch() {
632  return this.textToMatch;
633  }
634 
638  @Override
639  public boolean isRegex() {
640  return false;
641  }
642 
646  @Override
647  public boolean textMatches(String subject) {
648  return pattern.matcher(subject).find();
649  }
650  }
651 
655  private static class RegexMatcher implements TextMatcher {
656 
657  private final Pattern regex;
658 
665  RegexMatcher(Pattern regex) {
666  this.regex = regex;
667  }
668 
672  @Override
673  public String getTextToMatch() {
674  return this.regex.pattern();
675  }
676 
680  @Override
681  public boolean isRegex() {
682  return true;
683  }
684 
688  @Override
689  public boolean textMatches(String subject) {
690  // A single match is sufficient.
691  return this.regex.matcher(subject).find();
692  }
693 
694  }
695 
696  }
697 
698 }

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