mirror of
https://github.com/elisspace/autopsy.git
synced 2026-10-05 08:46:20 +00:00
Finished condition adding.
This commit is contained in:
@@ -257,7 +257,23 @@ final class FilesSet implements Serializable {
|
||||
public String toString() {
|
||||
// This override is designed to provide a display name for use with
|
||||
// javax.swing.DefaultListModel<E>.
|
||||
return this.ruleName + " (" + fileNameCondition.getTextToMatch() + ")";
|
||||
if(fileNameCondition != null) {
|
||||
return this.ruleName + " (" + fileNameCondition.getTextToMatch() + ")";
|
||||
}
|
||||
else if (this.pathCondition != null) {
|
||||
return this.ruleName + " (" + pathCondition.getTextToMatch() + ")";
|
||||
}
|
||||
else if (this.mimeTypeCondition != null) {
|
||||
return this.ruleName + " (" + mimeTypeCondition.getMimeType() + ")";
|
||||
}
|
||||
else if (this.fileSizeCondition != null) {
|
||||
return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue()
|
||||
+ " " + fileSizeCondition.getUnit().getName() + ")";
|
||||
}
|
||||
else {
|
||||
return this.ruleName + " ()";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,6 +290,13 @@ final class FilesSet implements Serializable {
|
||||
return mimeTypeCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fileSizeCondition
|
||||
*/
|
||||
public FileSizeCondition getFileSizeCondition() {
|
||||
return fileSizeCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for the file attribute conditions of which interesting
|
||||
* files set membership rules are composed.
|
||||
@@ -331,13 +354,40 @@ final class FilesSet implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @return the comparator
|
||||
*/
|
||||
public COMPARATOR getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unit
|
||||
*/
|
||||
public SIZE_UNIT getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sizeValue
|
||||
*/
|
||||
public int getSizeValue() {
|
||||
return sizeValue;
|
||||
}
|
||||
|
||||
static enum COMPARATOR {
|
||||
|
||||
LESS_THAN,
|
||||
LESS_THAN_EQUAL,
|
||||
EQUAL,
|
||||
GREATER_THAN,
|
||||
GREATER_THAN_EQUAL;
|
||||
LESS_THAN("<"),
|
||||
LESS_THAN_EQUAL("≤"),
|
||||
EQUAL("="),
|
||||
GREATER_THAN(">"),
|
||||
GREATER_THAN_EQUAL("≥");
|
||||
|
||||
private String symbol;
|
||||
|
||||
COMPARATOR(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public static COMPARATOR fromSymbol(String symbol) {
|
||||
if (symbol.equals("<=") || symbol.equals("≤")) {
|
||||
@@ -354,18 +404,27 @@ final class FilesSet implements Serializable {
|
||||
throw new IllegalArgumentException("Invalid symbol");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the symbol
|
||||
*/
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
|
||||
static enum SIZE_UNIT {
|
||||
|
||||
BYTE(1),
|
||||
KILOBYTE(1024),
|
||||
MEGABYTE(1024 * 1024),
|
||||
GIGABYTE(1024 * 1024 * 1024);
|
||||
BYTE(1, "Bytes"),
|
||||
KILOBYTE(1024, "Kilobytes"),
|
||||
MEGABYTE(1024 * 1024, "Megabytes"),
|
||||
GIGABYTE(1024 * 1024 * 1024, "Gigabytes");
|
||||
private long size;
|
||||
private String name;
|
||||
|
||||
private SIZE_UNIT(long size) {
|
||||
private SIZE_UNIT(long size, String name) {
|
||||
this.size = size;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
@@ -373,24 +432,26 @@ final class FilesSet implements Serializable {
|
||||
}
|
||||
|
||||
public static SIZE_UNIT fromName(String name) {
|
||||
if (name.equals("Bytes")) {
|
||||
return BYTE;
|
||||
} else if (name.equals("Kilobytes")) {
|
||||
return KILOBYTE;
|
||||
} else if (name.equals("Megabytes")) {
|
||||
return MEGABYTE;
|
||||
} else if (name.equals("Gigabytes")) {
|
||||
return GIGABYTE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid symbol");
|
||||
for (SIZE_UNIT unit : SIZE_UNIT.values()) {
|
||||
if (unit.getName().equals(name)) {
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid name for size unit.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
private COMPARATOR comparator;
|
||||
private SIZE_UNIT unit;
|
||||
private int sizeValue;
|
||||
|
||||
FileSizeCondition(COMPARATOR comparator, SIZE_UNIT uint, int sizeValue) {
|
||||
FileSizeCondition(COMPARATOR comparator, SIZE_UNIT unit, int sizeValue) {
|
||||
this.comparator = comparator;
|
||||
this.unit = unit;
|
||||
this.sizeValue = sizeValue;
|
||||
@@ -399,8 +460,8 @@ final class FilesSet implements Serializable {
|
||||
@Override
|
||||
public boolean passes(AbstractFile file) {
|
||||
long fileSize = file.getSize();
|
||||
long conditionSize = this.unit.getSize() * this.sizeValue;
|
||||
switch (this.comparator) {
|
||||
long conditionSize = this.getUnit().getSize() * this.getSizeValue();
|
||||
switch (this.getComparator()) {
|
||||
case GREATER_THAN:
|
||||
return fileSize > conditionSize;
|
||||
case GREATER_THAN_EQUAL:
|
||||
@@ -508,7 +569,6 @@ final class FilesSet implements Serializable {
|
||||
*/
|
||||
private static abstract class AbstractTextCondition implements TextCondition {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final TextMatcher textMatcher;
|
||||
|
||||
/**
|
||||
@@ -702,7 +762,7 @@ final class FilesSet implements Serializable {
|
||||
* An interface for objects that do textual matches, used to compose a
|
||||
* text condition.
|
||||
*/
|
||||
private static interface TextMatcher {
|
||||
private static interface TextMatcher extends Serializable {
|
||||
|
||||
/**
|
||||
* Get the text the matcher examines.
|
||||
@@ -736,6 +796,7 @@ final class FilesSet implements Serializable {
|
||||
*/
|
||||
private static class CaseInsensitiveStringComparisionMatcher implements TextMatcher {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String textToMatch;
|
||||
|
||||
/**
|
||||
@@ -779,6 +840,7 @@ final class FilesSet implements Serializable {
|
||||
*/
|
||||
private static class CaseInsensitivePartialStringComparisionMatcher implements TextMatcher {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String textToMatch;
|
||||
private final Pattern pattern;
|
||||
|
||||
@@ -823,6 +885,7 @@ final class FilesSet implements Serializable {
|
||||
*/
|
||||
private static class RegexMatcher implements TextMatcher {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern regex;
|
||||
|
||||
/**
|
||||
|
||||
@@ -351,6 +351,9 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.filesRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="filesRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="dirsRadio">
|
||||
<Properties>
|
||||
@@ -361,6 +364,9 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.dirsRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="dirsRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="filesAndDirsRadio">
|
||||
<Properties>
|
||||
@@ -371,6 +377,9 @@
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties" key="FilesSetRulePanel.filesAndDirsRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="filesAndDirsRadioActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
@@ -50,7 +50,12 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
"FilesSetRulePanel.bytes=Bytes",
|
||||
"FilesSetRulePanel.kiloBytes=Kilobytes",
|
||||
"FilesSetRulePanel.megaBytes=Megabytes",
|
||||
"FilesSetRulePanel.gigaBytes=Gigabytes"
|
||||
"FilesSetRulePanel.gigaBytes=Gigabytes",
|
||||
"FilesSetRulePanel.NoConditionError=Must have at least one condition to make a rule.",
|
||||
"FilesSetRulePanel.NoMimeTypeError=Please select a valid MIME type.",
|
||||
"FilesSetRulePanel.NoNameError=Name cannot be empty",
|
||||
"FilesSetRulePanel.NoPathError=Path cannot be empty",
|
||||
"FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0."
|
||||
})
|
||||
|
||||
private static final SortedSet<MediaType> mediaTypes = MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry().getTypes();
|
||||
@@ -139,8 +144,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
if (!(this.fileSizeCheck.isSelected() || this.mimeCheck.isSelected()
|
||||
|| this.nameCheck.isSelected() || this.pathCheck.isSelected())) {
|
||||
this.okButton.setEnabled(false);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.okButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
@@ -242,40 +246,55 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
*/
|
||||
boolean isValidRuleDefinition() {
|
||||
|
||||
// The rule must have name condition text.
|
||||
if (this.nameTextField.getText().isEmpty()) {
|
||||
if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected())) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.emptyNameCondition"),
|
||||
Bundle.FilesSetRulePanel_NoConditionError(),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The name condition must either be a regular expression that compiles or
|
||||
// a string without illegal file name chars.
|
||||
if (this.nameRegexCheckbox.isSelected()) {
|
||||
try {
|
||||
Pattern.compile(this.nameTextField.getText());
|
||||
} catch (PatternSyntaxException ex) {
|
||||
if (this.nameCheck.isSelected()) {
|
||||
// The name condition must either be a regular expression that compiles or
|
||||
// a string without illegal file name chars.
|
||||
if (this.nameTextField.getText().isEmpty()) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidNameRegex", ex.getLocalizedMessage()),
|
||||
Bundle.FilesSetRulePanel_NoNameError(),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInName"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
if (this.nameRegexCheckbox.isSelected()) {
|
||||
try {
|
||||
Pattern.compile(this.nameTextField.getText());
|
||||
} catch (PatternSyntaxException ex) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidNameRegex", ex.getLocalizedMessage()),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (this.nameTextField.getText().isEmpty() || !FilesSetRulePanel.containsOnlyLegalChars(this.nameTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_NAME_CHARS)) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInName"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The path condition, if specified, must either be a regular expression
|
||||
// that compiles or a string without illegal file path chars.
|
||||
if (!this.pathTextField.getText().isEmpty()) {
|
||||
// that compiles or a string without illegal file path chars.
|
||||
if (this.pathCheck.isSelected()) {
|
||||
if (this.pathTextField.getText().isEmpty()) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
Bundle.FilesSetRulePanel_NoPathError(),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
if (this.pathRegexCheckBox.isSelected()) {
|
||||
try {
|
||||
Pattern.compile(this.pathTextField.getText());
|
||||
@@ -287,7 +306,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!FilesSetRulePanel.containsOnlyLegalChars(this.pathTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_PATH_CHARS)) {
|
||||
if (this.pathTextField.getText().isEmpty() || !FilesSetRulePanel.containsOnlyLegalChars(this.pathTextField.getText(), FilesSetRulePanel.ILLEGAL_FILE_PATH_CHARS)) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
NbBundle.getMessage(FilesSetPanel.class, "FilesSetRulePanel.messages.invalidCharInPath"),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
@@ -296,6 +315,24 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.mimeCheck.isSelected()) {
|
||||
if (this.mimeTypeComboBox.getSelectedIndex() == 0) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
Bundle.FilesSetRulePanel_NoMimeTypeError(),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.fileSizeCheck.isSelected()) {
|
||||
if ((Integer) this.fileSizeSpinner.getValue() == 0) {
|
||||
NotifyDescriptor notifyDesc = new NotifyDescriptor.Message(
|
||||
Bundle.FilesSetRulePanel_ZeroFileSizeError(),
|
||||
NotifyDescriptor.WARNING_MESSAGE);
|
||||
DialogDisplayer.getDefault().notify(notifyDesc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -461,7 +498,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
* state of the UI components in the type button group.
|
||||
*/
|
||||
private void setComponentsForSearchType() {
|
||||
if (this.dirsRadio.isSelected()) {
|
||||
if (!this.filesRadio.isSelected()) {
|
||||
this.fullNameRadioButton.setSelected(true);
|
||||
this.extensionRadioButton.setEnabled(false);
|
||||
this.mimeTypeComboBox.setEnabled(false);
|
||||
@@ -601,12 +638,27 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
|
||||
typeButtonGroup.add(filesRadio);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(filesRadio, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.filesRadio.text")); // NOI18N
|
||||
filesRadio.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
filesRadioActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
typeButtonGroup.add(dirsRadio);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(dirsRadio, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dirsRadio.text")); // NOI18N
|
||||
dirsRadio.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
dirsRadioActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
typeButtonGroup.add(filesAndDirsRadio);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(filesAndDirsRadio, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.filesAndDirsRadio.text")); // NOI18N
|
||||
filesAndDirsRadio.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
filesAndDirsRadioActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
@@ -780,6 +832,19 @@ final class FilesSetRulePanel extends javax.swing.JPanel {
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_mimeTypeComboBoxActionPerformed
|
||||
|
||||
private void filesRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioActionPerformed
|
||||
|
||||
this.setComponentsForSearchType();
|
||||
}//GEN-LAST:event_filesRadioActionPerformed
|
||||
|
||||
private void dirsRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioActionPerformed
|
||||
this.setComponentsForSearchType();
|
||||
}//GEN-LAST:event_dirsRadioActionPerformed
|
||||
|
||||
private void filesAndDirsRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesAndDirsRadioActionPerformed
|
||||
this.setComponentsForSearchType();
|
||||
}//GEN-LAST:event_filesAndDirsRadioActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JRadioButton dirsRadio;
|
||||
private javax.swing.JComboBox equalitySymbolComboBox;
|
||||
|
||||
+65
-113
@@ -19,6 +19,9 @@
|
||||
package org.sleuthkit.autopsy.modules.interestingitems;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -29,9 +32,13 @@ import java.util.Observable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.openide.util.Exceptions;
|
||||
import org.openide.util.io.NbObjectInputStream;
|
||||
import org.openide.util.io.NbObjectOutputStream;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.XMLUtil;
|
||||
@@ -50,6 +57,8 @@ final class InterestingItemDefsManager extends Observable {
|
||||
private static final List<String> ILLEGAL_FILE_NAME_CHARS = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("\\", "/", ":", "*", "?", "\"", "<", ">")));
|
||||
private static final List<String> ILLEGAL_FILE_PATH_CHARS = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("\\", ":", "*", "?", "\"", "<", ">")));
|
||||
private static final String INTERESTING_FILES_SET_DEFS_FILE_NAME = "InterestingFilesSetDefs.xml"; //NON-NLS
|
||||
private static final String INTERESING_FILES_SET_DEFS_SERIALIZATION_NAME = "interestingFileSets.settings";
|
||||
private static final String INTERESING_FILES_SET_DEFS_SERIALIZATION_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + INTERESING_FILES_SET_DEFS_SERIALIZATION_NAME;
|
||||
private static final String DEFAULT_FILE_SET_DEFS_PATH = PlatformUtil.getUserConfigDirectory() + File.separator + INTERESTING_FILES_SET_DEFS_FILE_NAME;
|
||||
private static InterestingItemDefsManager instance;
|
||||
|
||||
@@ -86,7 +95,7 @@ final class InterestingItemDefsManager extends Observable {
|
||||
* Gets a copy of the current interesting files set definitions.
|
||||
*
|
||||
* @return A map of interesting files set names to interesting file sets,
|
||||
* possibly empty.
|
||||
* possibly empty.
|
||||
*/
|
||||
synchronized Map<String, FilesSet> getInterestingFilesSets() {
|
||||
return FilesSetXML.readDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH);
|
||||
@@ -97,10 +106,10 @@ final class InterestingItemDefsManager extends Observable {
|
||||
* previous definitions.
|
||||
*
|
||||
* @param filesSets A mapping of interesting files set names to files sets,
|
||||
* used to enforce unique files set names.
|
||||
* used to enforce unique files set names.
|
||||
*/
|
||||
synchronized void setInterestingFilesSets(Map<String, FilesSet> filesSets) {
|
||||
FilesSetXML.writeDefinitionsFile(DEFAULT_FILE_SET_DEFS_PATH, filesSets);
|
||||
FilesSetXML.writeDefinitionsFile(INTERESING_FILES_SET_DEFS_SERIALIZATION_PATH, filesSets);
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
}
|
||||
@@ -167,7 +176,7 @@ final class InterestingItemDefsManager extends Observable {
|
||||
// Check if the file exists.
|
||||
File defsFile = new File(filePath);
|
||||
if (!defsFile.exists()) {
|
||||
return filesSets;
|
||||
return readSerializedDefinitions();
|
||||
}
|
||||
|
||||
// Check if the file can be read.
|
||||
@@ -195,16 +204,25 @@ final class InterestingItemDefsManager extends Observable {
|
||||
for (int i = 0; i < setElems.getLength(); ++i) {
|
||||
readFilesSet((Element) setElems.item(i), filesSets, filePath);
|
||||
}
|
||||
|
||||
return filesSets;
|
||||
}
|
||||
|
||||
private static Map<String, FilesSet> readSerializedDefinitions() {
|
||||
String filePath = INTERESING_FILES_SET_DEFS_SERIALIZATION_PATH;
|
||||
try (NbObjectInputStream in = new NbObjectInputStream(new FileInputStream(filePath.toString()))) {
|
||||
Map<String, FilesSet> filesSetMap = (Map<String, FilesSet>) in.readObject();
|
||||
return filesSetMap;
|
||||
} catch (IOException | ClassNotFoundException ex) {
|
||||
throw new PersistenceException(String.format("Failed to read settings from %s", filePath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in an interesting files set.
|
||||
*
|
||||
* @param setElem An interesting files set XML element
|
||||
* @param setElem An interesting files set XML element
|
||||
* @param filesSets A collection to which the set is to be added.
|
||||
* @param filePath The source file, used for error reporting.
|
||||
* @param filePath The source file, used for error reporting.
|
||||
*/
|
||||
private static void readFilesSet(Element setElem, Map<String, FilesSet> filesSets, String filePath) {
|
||||
// The file set must have a unique name.
|
||||
@@ -279,11 +297,11 @@ final class InterestingItemDefsManager extends Observable {
|
||||
* XML element.
|
||||
*
|
||||
* @param filePath The path of the definitions file.
|
||||
* @param setName The name of the files set.
|
||||
* @param elem The file name rule XML element.
|
||||
* @param setName The name of the files set.
|
||||
* @param elem The file name rule XML element.
|
||||
*
|
||||
* @return A file name rule, or null if there is an error (the error is
|
||||
* logged).
|
||||
* logged).
|
||||
*/
|
||||
private static FilesSet.Rule readFileNameRule(Element elem) {
|
||||
String ruleName = FilesSetXML.readRuleName(elem);
|
||||
@@ -292,12 +310,12 @@ final class InterestingItemDefsManager extends Observable {
|
||||
// regex, or it may be from a TSK Framework rule definition with a
|
||||
// "*" globbing char, or it may be simple text.
|
||||
String content = elem.getTextContent();
|
||||
FilesSet.Rule.FullNameCondition namecondition;
|
||||
FilesSet.Rule.FullNameCondition nameCondition;
|
||||
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
|
||||
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON-NLS
|
||||
Pattern pattern = compileRegex(content);
|
||||
if (pattern != null) {
|
||||
namecondition = new FilesSet.Rule.FullNameCondition(pattern);
|
||||
nameCondition = new FilesSet.Rule.FullNameCondition(pattern);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.NAME_RULE_TAG + " regex, ignoring malformed '{0}' rule definition", ruleName); // NON-NLS
|
||||
return null;
|
||||
@@ -309,29 +327,29 @@ final class InterestingItemDefsManager extends Observable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
namecondition = new FilesSet.Rule.FullNameCondition(content);
|
||||
nameCondition = new FilesSet.Rule.FullNameCondition(content);
|
||||
}
|
||||
|
||||
// Read in the type condition.
|
||||
FilesSet.Rule.MetaTypeCondition metaTypecondition = FilesSetXML.readMetaTypecondition(elem);
|
||||
if (metaTypecondition == null) {
|
||||
FilesSet.Rule.MetaTypeCondition metaTypeCondition = FilesSetXML.readMetaTypeCondition(elem);
|
||||
if (metaTypeCondition == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read in the optional path condition. Null is o.k., but if the attribute
|
||||
// is there, be sure it is not malformed.
|
||||
FilesSet.Rule.ParentPathCondition pathcondition = null;
|
||||
FilesSet.Rule.ParentPathCondition pathCondition = null;
|
||||
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|
||||
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
|
||||
pathcondition = FilesSetXML.readPathcondition(elem);
|
||||
if (pathcondition == null) {
|
||||
pathCondition = FilesSetXML.readPathCondition(elem);
|
||||
if (pathCondition == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new FilesSet.Rule(ruleName, namecondition, metaTypecondition, pathcondition, null, null);
|
||||
return new FilesSet.Rule(ruleName, nameCondition, metaTypeCondition, pathCondition, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,7 +359,7 @@ final class InterestingItemDefsManager extends Observable {
|
||||
* @param elem The file name extension rule XML element.
|
||||
*
|
||||
* @return A file name extension rule, or null if there is an error (the
|
||||
* error is logged).
|
||||
* error is logged).
|
||||
*/
|
||||
private static FilesSet.Rule readFileExtensionRule(Element elem) {
|
||||
String ruleName = FilesSetXML.readRuleName(elem);
|
||||
@@ -350,12 +368,12 @@ final class InterestingItemDefsManager extends Observable {
|
||||
// be a regex, or it may be from a TSK Framework rule definition
|
||||
// with a "*" globbing char.
|
||||
String content = elem.getTextContent();
|
||||
FilesSet.Rule.ExtensionCondition extcondition;
|
||||
FilesSet.Rule.ExtensionCondition extCondition;
|
||||
String regex = elem.getAttribute(FilesSetXML.REGEX_ATTR);
|
||||
if ((!regex.isEmpty() && regex.equalsIgnoreCase("true")) || content.contains("*")) { // NON-NLS
|
||||
Pattern pattern = compileRegex(content);
|
||||
if (pattern != null) {
|
||||
extcondition = new FilesSet.Rule.ExtensionCondition(pattern);
|
||||
extCondition = new FilesSet.Rule.ExtensionCondition(pattern);
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Error compiling " + FilesSetXML.EXTENSION_RULE_TAG + " regex, ignoring malformed {0} rule definition", ruleName); // NON-NLS
|
||||
return null;
|
||||
@@ -367,35 +385,35 @@ final class InterestingItemDefsManager extends Observable {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extcondition = new FilesSet.Rule.ExtensionCondition(content);
|
||||
extCondition = new FilesSet.Rule.ExtensionCondition(content);
|
||||
}
|
||||
|
||||
// The rule must have a meta-type condition, unless a TSK Framework
|
||||
// definitions file is being read.
|
||||
FilesSet.Rule.MetaTypeCondition metaTypecondition = null;
|
||||
FilesSet.Rule.MetaTypeCondition metaTypeCondition = null;
|
||||
if (!elem.getAttribute(FilesSetXML.TYPE_FILTER_ATTR).isEmpty()) {
|
||||
metaTypecondition = FilesSetXML.readMetaTypecondition(elem);
|
||||
if (metaTypecondition == null) {
|
||||
metaTypeCondition = FilesSetXML.readMetaTypeCondition(elem);
|
||||
if (metaTypeCondition == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
metaTypecondition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
|
||||
metaTypeCondition = new FilesSet.Rule.MetaTypeCondition(FilesSet.Rule.MetaTypeCondition.Type.FILES);
|
||||
}
|
||||
|
||||
// The rule may have a path condition. Null is o.k., but if the attribute
|
||||
// is there, it must not be malformed.
|
||||
FilesSet.Rule.ParentPathCondition pathcondition = null;
|
||||
FilesSet.Rule.ParentPathCondition pathCondition = null;
|
||||
if (!elem.getAttribute(FilesSetXML.PATH_FILTER_ATTR).isEmpty()
|
||||
|| !elem.getAttribute(FilesSetXML.PATH_REGEX_ATTR).isEmpty()) {
|
||||
pathcondition = FilesSetXML.readPathcondition(elem);
|
||||
if (pathcondition == null) {
|
||||
pathCondition = FilesSetXML.readPathCondition(elem);
|
||||
if (pathCondition == null) {
|
||||
// Malformed attribute.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new FilesSet.Rule(ruleName, extcondition, metaTypecondition, pathcondition, null, null);
|
||||
return new FilesSet.Rule(ruleName, extCondition, metaTypeCondition, pathCondition, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,14 +446,15 @@ final class InterestingItemDefsManager extends Observable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a meta-type condition for an interesting files set membership
|
||||
* rule from data in an XML element.
|
||||
* Construct a meta-type condition for an interesting files set
|
||||
* membership rule from data in an XML element.
|
||||
*
|
||||
* @param ruleElement The XML element.
|
||||
*
|
||||
* @return The meta-type condition, or null if there is an error (logged).
|
||||
* @return The meta-type condition, or null if there is an error
|
||||
* (logged).
|
||||
*/
|
||||
private static FilesSet.Rule.MetaTypeCondition readMetaTypecondition(Element ruleElement) {
|
||||
private static FilesSet.Rule.MetaTypeCondition readMetaTypeCondition(Element ruleElement) {
|
||||
FilesSet.Rule.MetaTypeCondition condition = null;
|
||||
String conditionAttribute = ruleElement.getAttribute(FilesSetXML.TYPE_FILTER_ATTR);
|
||||
if (!conditionAttribute.isEmpty()) {
|
||||
@@ -462,14 +481,14 @@ final class InterestingItemDefsManager extends Observable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a path condition for an interesting files set membership rule
|
||||
* from data in an XML element.
|
||||
* Construct a path condition for an interesting files set membership
|
||||
* rule from data in an XML element.
|
||||
*
|
||||
* @param ruleElement The XML element.
|
||||
*
|
||||
* @return The path condition, or null if there is an error (logged).
|
||||
*/
|
||||
private static FilesSet.Rule.ParentPathCondition readPathcondition(Element ruleElement) {
|
||||
private static FilesSet.Rule.ParentPathCondition readPathCondition(Element ruleElement) {
|
||||
FilesSet.Rule.ParentPathCondition condition = null;
|
||||
String path = ruleElement.getAttribute(FilesSetXML.PATH_FILTER_ATTR);
|
||||
String pathRegex = ruleElement.getAttribute(FilesSetXML.PATH_REGEX_ATTR);
|
||||
@@ -499,84 +518,17 @@ final class InterestingItemDefsManager extends Observable {
|
||||
// multiple intersting files set definition files, e.g., one for
|
||||
// definitions that ship with Autopsy and one for user definitions.
|
||||
static boolean writeDefinitionsFile(String filePath, Map<String, FilesSet> interestingFilesSets) {
|
||||
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
// Create the new XML document.
|
||||
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement(FilesSetXML.FILE_SETS_ROOT_TAG);
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
// Add the interesting files sets to the document.
|
||||
for (FilesSet set : interestingFilesSets.values()) {
|
||||
// Add the files set element and its attributes.
|
||||
Element setElement = doc.createElement(FilesSetXML.FILE_SET_TAG);
|
||||
setElement.setAttribute(FilesSetXML.NAME_ATTR, set.getName());
|
||||
setElement.setAttribute(FilesSetXML.DESC_ATTR, set.getDescription());
|
||||
setElement.setAttribute(FilesSetXML.IGNORE_KNOWN_FILES_ATTR, Boolean.toString(set.ignoresKnownFiles()));
|
||||
|
||||
// Add the child elements for the set membership rules.
|
||||
for (FilesSet.Rule rule : set.getRules().values()) {
|
||||
// Add a rule element with the appropriate name condition
|
||||
// type tag.
|
||||
FilesSet.Rule.FileNameCondition namecondition = rule.getFileNameCondition();
|
||||
Element ruleElement;
|
||||
if (namecondition instanceof FilesSet.Rule.FullNameCondition) {
|
||||
ruleElement = doc.createElement(FilesSetXML.NAME_RULE_TAG);
|
||||
} else {
|
||||
ruleElement = doc.createElement(FilesSetXML.EXTENSION_RULE_TAG);
|
||||
}
|
||||
|
||||
// Add the rule name attribute.
|
||||
ruleElement.setAttribute(FilesSetXML.NAME_ATTR, rule.getName());
|
||||
|
||||
// Add the name condition regex attribute
|
||||
ruleElement.setAttribute(FilesSetXML.REGEX_ATTR, Boolean.toString(namecondition.isRegex()));
|
||||
|
||||
// Add the type condition attribute.
|
||||
FilesSet.Rule.MetaTypeCondition typecondition = rule.getMetaTypeCondition();
|
||||
switch (typecondition.getMetaType()) {
|
||||
case FILES:
|
||||
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_FILES);
|
||||
break;
|
||||
case DIRECTORIES:
|
||||
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_DIRS);
|
||||
break;
|
||||
default:
|
||||
ruleElement.setAttribute(FilesSetXML.TYPE_FILTER_ATTR, FilesSetXML.TYPE_FILTER_VALUE_FILES_AND_DIRS);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add the optional path condition.
|
||||
FilesSet.Rule.ParentPathCondition pathcondition = rule.getPathCondition();
|
||||
if (pathcondition != null) {
|
||||
if (pathcondition.isRegex()) {
|
||||
ruleElement.setAttribute(FilesSetXML.PATH_REGEX_ATTR, pathcondition.getTextToMatch());
|
||||
} else {
|
||||
ruleElement.setAttribute(FilesSetXML.PATH_FILTER_ATTR, pathcondition.getTextToMatch());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the name condition text as the rule element content.
|
||||
ruleElement.setTextContent(namecondition.getTextToMatch());
|
||||
|
||||
setElement.appendChild(ruleElement);
|
||||
}
|
||||
|
||||
rootElement.appendChild(setElement);
|
||||
try (NbObjectOutputStream out = new NbObjectOutputStream(new FileOutputStream(filePath))) {
|
||||
out.writeObject(interestingFilesSets);
|
||||
File xmlFile = new File(DEFAULT_FILE_SET_DEFS_PATH);
|
||||
if(xmlFile.exists()) {
|
||||
xmlFile.delete();
|
||||
}
|
||||
|
||||
// Overwrite the previous definitions file. Note that the utility
|
||||
// method logs an error on failure.
|
||||
return XMLUtil.saveDoc(FilesSetXML.class, filePath, XML_ENCODING, doc);
|
||||
|
||||
} catch (ParserConfigurationException ex) {
|
||||
logger.log(Level.SEVERE, "Error writing interesting files definition file to " + filePath, ex); // NON-NLS
|
||||
return false;
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
throw new PersistenceException(String.format("Failed to write settings to %s", filePath), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+27
-5
@@ -250,13 +250,22 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
|
||||
FilesSet.Rule.MetaTypeCondition typeCondition = rule.getMetaTypeCondition();
|
||||
FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition();
|
||||
FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition();
|
||||
FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition();
|
||||
|
||||
// Populate the components that display the properties of the
|
||||
// selected rule.
|
||||
InterestingItemDefsPanel.this.fileNameTextField.setText(nameCondition.getTextToMatch());
|
||||
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.FullNameCondition);
|
||||
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.ExtensionCondition);
|
||||
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(nameCondition.isRegex());
|
||||
if (nameCondition != null) {
|
||||
InterestingItemDefsPanel.this.fileNameTextField.setText(nameCondition.getTextToMatch());
|
||||
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.FullNameCondition);
|
||||
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(nameCondition instanceof FilesSet.Rule.ExtensionCondition);
|
||||
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(nameCondition.isRegex());
|
||||
}
|
||||
else {
|
||||
InterestingItemDefsPanel.this.fileNameTextField.setText("");
|
||||
InterestingItemDefsPanel.this.fileNameRadioButton.setSelected(true);
|
||||
InterestingItemDefsPanel.this.fileNameExtensionRadioButton.setSelected(false);
|
||||
InterestingItemDefsPanel.this.fileNameRegexCheckbox.setSelected(false);
|
||||
}
|
||||
switch (typeCondition.getMetaType()) {
|
||||
case FILES:
|
||||
InterestingItemDefsPanel.this.filesRadioButton.setSelected(true);
|
||||
@@ -275,7 +284,20 @@ final class InterestingItemDefsPanel extends IngestModuleGlobalSettingsPanel imp
|
||||
InterestingItemDefsPanel.this.rulePathConditionTextField.setText("");
|
||||
InterestingItemDefsPanel.this.rulePathConditionRegexCheckBox.setSelected(false);
|
||||
}
|
||||
InterestingItemDefsPanel.this.mimeTypeComboBox.setSelectedItem(mimeTypeCondition.getMimeType());
|
||||
if (mimeTypeCondition != null) {
|
||||
InterestingItemDefsPanel.this.mimeTypeComboBox.setSelectedItem(mimeTypeCondition.getMimeType());
|
||||
} else {
|
||||
InterestingItemDefsPanel.this.mimeTypeComboBox.setSelectedIndex(0);
|
||||
}
|
||||
if (fileSizeCondition != null) {
|
||||
InterestingItemDefsPanel.this.fileSizeUnitComboBox.setSelectedItem(fileSizeCondition.getUnit().getName());
|
||||
InterestingItemDefsPanel.this.equalitySignComboBox.setSelectedItem(fileSizeCondition.getComparator().getSymbol());
|
||||
InterestingItemDefsPanel.this.jSpinner1.setValue(fileSizeCondition.getSizeValue());
|
||||
} else {
|
||||
InterestingItemDefsPanel.this.fileSizeUnitComboBox.setSelectedIndex(1);
|
||||
InterestingItemDefsPanel.this.equalitySignComboBox.setSelectedIndex(2);
|
||||
InterestingItemDefsPanel.this.jSpinner1.setValue(0);
|
||||
}
|
||||
|
||||
// Enable the new, edit and delete rule buttons.
|
||||
InterestingItemDefsPanel.this.newRuleButton.setEnabled(true);
|
||||
|
||||
Reference in New Issue
Block a user